kernel - Remove bottlenecks related to mass pipe closures
authorMatthew Dillon <dillon@apollo.backplane.com>
Mon, 14 Aug 2017 02:48:28 +0000 (19:48 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Mon, 14 Aug 2017 03:03:14 +0000 (20:03 -0700)
commit5eab490ea55e4eabb73d3ecb5cd179f745d78196
tree78ccbdf512f352cb79945b27788d033079d49acd
parentaf1cde6419d10c94b94431b3ac9de3ee41509601
kernel - Remove bottlenecks related to mass pipe closures

* These changes fix teardown latencies involved with destroying a large
  number of pipe()s at the same time, for example when a large number
  of processes are killed simultaneously.  Testing with 900,000 processes
  chaining 900,000 pipe()s, the system could become unusable for upwards
  of an hour when the test is killed with ^C prior to these changes.

  After these changes the system balks for less than 30 seconds in the
  900,000 process case.

* Wrap pipe teardowns in a pcpu mutex.  Such teardowns only occur when the
  normal pcpu pipe cache / hysteresis gets blown out due to a large number
  of closures occurring simultaneously and are not typically in the
  critical path.

  The pcpu mutex allows good concurrency while also limiting the number of
  processes which can be tearing down pipe KVM at the same time.  If
  we have say 900,000 processes all exiting, this mechanism limits the
  teardown to (ncpus) concurrent processes.

  The mutex uses a queued lock (whereas the lockmgr spams wakeup()s),
  so we use a mutex to avoid a degenerate O(N^2) wakeup situation.
  This removes an enormous amount of overhead during the teardown.

* When removing areas from the kernel_map, issue a pmap_remove() call
  on the kernel_pmap before cleaning up the underlying VM object just as
  we do for other types of maps.  This was originally not done because the
  kernel_pmap can be extremely sparse and iteration could be inefficient.

  However, the current pmap implementation handles sparse pmaps just
  fine.  Removing the pages in bulk reduces the number of global IPIs
  that wind up being issued during the removal, greatly improving
  performance when a large volume of kernel resource is being destroyed
  all at once.

* Increase the zalloc burst from 4 pages to 32 pages.  When adding pages,
  use more relaxed vm_page_alloc() flags after the 4th page to try to
  avoid blowing up the emergency free page cache.
sys/kern/sys_pipe.c
sys/vm/vm_map.c
sys/vm/vm_zone.c
sys/vm/vm_zone.h