Fix numerous pageout daemon -> buffer cache deadlocks in the main system.
authorMatthew Dillon <dillon@dragonflybsd.org>
Tue, 1 Jul 2008 02:02:56 +0000 (02:02 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Tue, 1 Jul 2008 02:02:56 +0000 (02:02 +0000)
commit4ecf7cc9c0bfba854db12b3d9cc529b0e705b65e
tree153f701385c1d8297c4506384747aa2b71838d58
parent36a563f27bc062ef4a30bc3c944bd91cf83c5133
Fix numerous pageout daemon -> buffer cache deadlocks in the main system.
These issues usually only occur on systems with small amounts of ram
but it is possible to trigger them on any system.

* Get rid of the IO_NOBWILL hack.  Just have the VN device use IO_DIRECT,
  which will clean out the buffer on completion of the write.

* Add a timeout argument to vm_wait().

* Add a thread->td_flags flag called TDF_SYSTHREAD.  kmalloc()'s made
  from designated threads are allowed to dip into the system reserve
  when allocating pages.  Only the pageout daemon and buf_daemon[_hw] use
  the flag.

* Add a new static procedure, recoverbufpages(), which explicitly tries to
  free buffers and their backing pages on the clean queue.

* Add a new static procedure, bio_page_alloc(), to do all the nasty work
  of allocating a page on behalf of a buffer cache buffer.

  This function will call vm_page_alloc() with VM_ALLOC_SYSTEM to allow
  it to dip into the system reserve.  If the allocation fails this
  function will call recoverbufpages() to try to recycle from VM pages
  from clean buffer cache buffers, and will then attempt to reallocate
  using VM_ALLOC_SYSTEM | VM_ALLOC_INTERRUPT to allow it to dip into
  the interrupt reserve as well.

  Warnings will blare on the console.  If the effort still fails we
  sleep for 1/20 of a second and retry.  The idea though is for all
  the effort above to not result in a failure at the end.

Reported-by: Gergo Szakal <bastyaelvtars@gmail.com>
12 files changed:
sys/dev/disk/vn/vn.c
sys/kern/kern_slaballoc.c
sys/kern/uipc_syscalls.c
sys/kern/vfs_bio.c
sys/sys/thread.h
sys/sys/vnode.h
sys/vm/swap_pager.c
sys/vm/vm_fault.c
sys/vm/vm_glue.c
sys/vm/vm_page.c
sys/vm/vm_pageout.c
sys/vm/vm_pageout.h