kernel - Wakeup threads blocked in the VM page allocator more quickly
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 27 Jun 2013 06:40:29 +0000 (23:40 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 27 Jun 2013 06:56:51 +0000 (23:56 -0700)
commit77d1fb91cace7f1779195614024e920f1b70b275
tree50bc8885060344763e254d35f98fb30695e31d6e
parent43f7c5533b94bf18b84d4924b43e9288b4dcdedb
kernel - Wakeup threads blocked in the VM page allocator more quickly

Additional tuning to changes in the way the pageout daemon and VM system
wakes up threads blocked allocating normal VM pages.  Previously the VM
system would wait for the vm_paging_target() to be reached before waking
up all waiters, and had code to try to wakeup individual threads past
the minimum.

This just didn't work very well on machines with lots of memory because
it could take quite a long time for the pageout daemon to actually reach
the vm_paging_target() (and VM load could prevent it from being reached at
all!).  Many threads could wind up being blocked indefinitely waiting for
cache and/or free page counts to reach reasonable levels.

The solution is to give the kernel time to build up a smaller number
of free+cache pages beyond the minimum, enough to give all waiting threads
a fair shot at allocating at least one page, and then simply wakeup all
the waiters.  This hysteresis is set smallish on purpose, defaulting to
a value of 16 in order to avoid holding threads blocked for excessive
periods of time.

Under heavy VM loads this creates an overlap between memory consumers and
the pageout daemon, allowing the pageout daemon to run continuously in
these situations.

* Add the vm.page_free_hysteresis sysctl, initialized to 16.  This field
  specifies a small number of pages past the minimum required for normal
  system operation before the VM system will wakeup threads blocked in the
  VM page allocator.

* Adjust tmpfs to force-free pages through the hysteresis value to reduce
  degenerate block/wakeup situations under heavy VM loads.
sys/vfs/tmpfs/tmpfs_vnops.c
sys/vm/vm_page.c
sys/vm/vm_page2.h
sys/vm/vm_pageout.c
sys/vm/vm_pageout.h