linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* A few small Memory Management changes
@ 1998-01-20 13:06 Mark Hemment
  0 siblings, 0 replies; only message in thread
From: Mark Hemment @ 1998-01-20 13:06 UTC (permalink / raw)
  To: linux-mm

[-- Attachment #1: Type: TEXT/PLAIN, Size: 5971 bytes --]

Hi,

   The attached patch, against 2.1.78, contains some simple memory
management changes.  They reduce memory usage, and give a slight increase
in the performance of the page-cache (when a required page is not
present).
   I'd appreciate any comments and/or test results.

  Changes;
	o In mm/slab.c, SLAB_BREAK_GFP_ORDER has been dropped from 2
	  to 1.  This reduces the page order (size) of the slabs
	  for some caches, which prevents stressing the page-allocator
	  with only a small hit in performance.  (Stability is more
	  important than performance).

	o The SLAB cache used for "files_struct" (files_cachep), has
	  been split into two slab-caches (files_cachep, and fds_cachep).
	  The fds_cachep is used for the "struct file" pointers.
	  Previously, the size of objects in files_cachep did not pack
	  well into any possible slab-cache size.  So the SLAB used a
	  large slab size to reduce internal fragmentation.  This was the
	  main cause of "fork(): Out of memory" errors on loaded systems.
	  With the default value of NR_OPEN (1024), the fds_cachep has
	  an object size of 4096 (or 8192 on 64-bit) which is a nice
	  size for the SLAB.
	  NOTE: This also required a change to
		arch/i386/kernel/init_task.c, to give the initial
		(idle) task file-descriptors.  (Does it actually need
		any?).

	o The members of vm_area_struct have been re-arranged so that
	  all the members, used during a find_vma() search, fall on
	  the same cache-line for archs which have a small line size
	  (eg. Intel's 486).
	  NOTE: This change also needs a complementary change to
		INIT_MMAP in asm/processor.h

	o Three members of 'struct page' have been unionised;
		inode	- only needed for named pages
		buffers	- only needed for buffer pages
		pg_swap_entry - only needed for anonymous pages
	  Named (inode) pages are marked PageNamed(pg), and
	  buffer pages are marked PageBuffer(pg).  While there
	  is currently no need to mark anonymous-pages, I'll probably
	  mark them in the future (but that hits a lot of code).

	o In 'struct page', the member "struct page *prev" has been
	  changed to "struct page **pprev".  This simplifies the
	  code to add/remove a named page from an inode's page queue.

	o page_unuse(), in filemap.c, has been simplified.  It is
	  only ever called for a named page, and if the page is still
	  shared it returns "0".  A zero tells the address-space
	  scanning function in vmscan.c that no page has been found,
	  _and_ there has been no blocking (ie. the context which
	  is being scanned could not have exited).

	o In mm/page_alloc.c a new allocation function, __get_user_page()
	  has been added.  This function takes _no_ arguments, and
	  allocates a single page at priority GFP_USER (although the
	  priority isn't actually used during page-reaping).  It offers
	  a slight performance improvement over the generic
	  __get_free_pages(), and returns a "struct page *".

	  Returning a pointer is only benefical in a few palaces at
	  the moment.  By changing some of the vm_operations (eg.
	  ->nopage), to return/take a 'struct page*' some code paths/
	  error handling can be improved.  (I haven't changed the
	  vm_ops in this patch, as it hits _alot_ of code).

	  Also in mm/page_alloc.c there is a new releasing function;
	  __free_freed_page().  This is used with the new inline
	  function (in include/linux/mm.h), release_page().  This new
	  inline removes the need to always call __free_page() in
	  mm/filemap.c.  (A page's count is used to 'lock' a page
	  against reaping when a block may occur.  Normally, filemap.c
	  just needs to drop this lock.  However, the inode associated
	  with the named-page may have been truncated/invalidated.  The
	  truncation/invalidation removes the page from the cache, but it
	  is up to the last page-user to return it to the free-page pool).
	  NOTE: relase_page() is also used in mm/memory.c when zapping
		pages from a context.  As some of these pages are named
		pages, the 'freeing' of the page only reduces the
		reference count.  ie. we avoid the overhead of some
		unnecessary function calls.

	o In mm/filemap.c, the need to always re-check the
	  page-cache (find_page()) after a _possible_ blocking allocation
	  has been removed.
	  Before an allocation, a 'cookie' is taken from the page-cache
	  hash line where the page would/will appear.  After the
	  allocation, the cookie is re-check.  If it has changed, the
	  page-cache needs to be search.  Otherwise there is no need
	  to re-check.
	  Rather than add a cookie counter to each page-cache hash line
	  (which would be 'fat'), the cookie is the first page pointer.
	  As all pages are added to the head of a hash line, the pointer
	  is sufficient.  (It can also give a false-positive if the first
	  page is removed, but this is a small price to pay).

	o The swap code has been changed to dynamically allocate the
	  swap_info_struct when a new swap-area is added.
	  Also, rather than use indices to link the swap-areas togther
	  (as was previously done), two sets of pointers are used.
	  By using two sets of pointers (one set for all swap-areas order
	  by priority, one set for all swap-areas with the same prio) and
	  code to find a swap-page of the highest available priority is
	  simplified.
	  An array of swap-area pointers is still needed, but it is
	  better than an array of swap-area structures.

	o rw_swap_page() has been changed to take a "struct page *" of
	  an I/O locked page, and to return a error.
	  Handling a swap-page write error is difficult, and is not
	  currently done correctly.  The problem is that rw_swap_page()
	  may block, so it is not possible to determine if the PTE
	  is still around (context has exited during the block) to
	  be reloaded.  I need to re-check, perhaps rw_swap_page()
	  cannot block _and_ return an error....

	o There are a few other changes, such as using "struct page *"
	  rather than unsigned long.

   Regards,

      markhe

[-- Attachment #2: patch-own-2.1.78-1.gz --]
[-- Type: APPLICATION/octet-stream, Size: 27403 bytes --]

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~1998-01-20 15:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-01-20 13:06 A few small Memory Management changes Mark Hemment

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox