kernel - Implement RLIMIT_RSS, Increase maximum supported swap
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 28 Dec 2016 02:34:26 +0000 (18:34 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 28 Dec 2016 06:57:34 +0000 (22:57 -0800)
commit534ee349e6008aebda57a822826743cf9ba54abe
tree16a2498505326cbb2ccca7d207dc18fd1bd885fb
parentb3fef7a1c7af0e46de2e155f1c8e644545bfa7cf
kernel - Implement RLIMIT_RSS, Increase maximum supported swap

* Implement RLIMIT_RSS by forcing pages out to swap if a process's RSS
  exceeds the rlimit.  Currently the algorith used to choose the pages
  is fairly unsophisticated (we don't have the luxury of a per-process
  vm_page_queues[] array).

* Implement the swap_user_async sysctl, default off.  This sysctl can be
  set to 1 to enable asynchronous paging in the RSS code.  This is mostly
  for testing and is not recommended since it allows the process to eat
  memory more quickly than it can be paged out.

* Reimplement vm.swap_burst_read so the sysctl now specifies the number
  of pages that are allowed to be burst.  Still disabled by default (will
  be enabled in a followup commit).

* Fix an overflow in the nswap_lowat and nswap_hiwat calculations.

* Refactor some of the pageout code to support synchronous direct
  paging, which the RSS code uses.  Thew new code also implements a
  feature that will move clean pages to PQ_CACHE, making them immediately
  reallocatable.

* Refactor the vm_pageout_deficit variable, using atomic ops.

* Fix an issue in vm_pageout_clean() (originally part of the inactive scan)
  which prevented clustering from operating properly on write.

* Refactor kern/subr_blist.c and all associated code that uses to increase
  swblk_t from int32_t to int64_t, and to increase the radix supported from
  31 bits to 63 bits.

  This increases the maximum supported swap from 2TB to some ungodly large
  value.  Remember that, by default, space for up to 4 swap devices
  is preallocated so if you are allocating insane amounts of swap it is
  best to do it with four equal-sized partitions instead of one so kernel
  memory is efficiently allocated.

* There are two kernel data structures associated with swap.  The blmeta
  structure which has approximately a 1:8192 ratio (ram:swap) and is
  pre-allocated up-front, and the swmeta structure whos KVA is reserved
  but not allocated.

  The swmeta structure has a 1:341 ratio.  It tracks swap assignments for
  pages in vm_object's.  The kernel limits the number of structures to
  approximately half of physical memory, meaning that if you have a machine
  with 16GB of ram the maximum amount of swapped-out data you can support
  with that is 16/2*341 = 2.7TB.  Not that you would actually want to eat
  half your ram to do actually do that.

  A large system with, say, 128GB of ram, would be able to support
  128/2*341 = 21TB of swap.  The ultimate limitation is the 512GB of KVM.
  The swap system can use up to 256GB of this so the maximum swap currently
  supported by DragonFly on a machine with > 512GB of ram is going to be
  256/2*341 = 43TB.  To expand this further would require some adjustments
  to increase the amount of KVM supported by the kernel.

* WARNING! swmeta is allocated via zalloc().  Once allocated, the memory
  can be reused for swmeta but cannot be freed for use by other subsystems.
  You should only configure as much swap as you are willing to reserve ram
  for.
20 files changed:
lib/libkvm/kvm_getswapinfo.c
sys/cpu/x86_64/include/param.h
sys/kern/subr_blist.c
sys/kern/subr_param.c
sys/platform/pc64/include/pmap.h
sys/platform/pc64/x86_64/trap.c
sys/platform/vkernel64/include/pmap.h
sys/sys/blist.h
sys/vm/swap_pager.c
sys/vm/swap_pager.h
sys/vm/vm_fault.c
sys/vm/vm_map.c
sys/vm/vm_map.h
sys/vm/vm_object.c
sys/vm/vm_object.h
sys/vm/vm_page.c
sys/vm/vm_pageout.c
sys/vm/vm_pageout.h
sys/vm/vm_pager.h
sys/vm/vm_swap.c