Fix buffer cache deadlocks by splitting dirty buffers into two categories:
commit5cae058489dd626a4d9988da27ff5ff2e6094086
authorMatthew Dillon <dillon@dragonflybsd.org>
Thu, 10 Jan 2008 07:34:04 +0000 (10 07:34 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Thu, 10 Jan 2008 07:34:04 +0000 (10 07:34 +0000)
tree931b6ec800ece5a4d2d8803b724b370f2bf3bdf5
parent254ee8c8d9a98d15bcd089704820c3321aff5bde
Fix buffer cache deadlocks by splitting dirty buffers into two categories:
Light weight dirty buffers and heavy weight dirty buffers.  Add a second
buffer cache flushing daemon to deal with the heavy weight dirty buffers.

Currently only HAMMER uses the new feature, but it can also easily be used
by UFS in the future.

Buffer cache deadlocks can occur in low memory situations where the buffer
cache tries to flush out dirty buffers and deadlocks when the act of
flushing a dirty buffer requires additional buffers to be acquired.  Because
there was only one buffer flushing daemon, a deadlock on a heavy weight buffer
prevented any further buffer flushes, whether light or heavy weight, and
wound up deadlocking the entire system.

Giving the heavy weight buffers their own daemon solves the problem by
allowing light weight buffers to continue to be flushed even if a stall
occurs on a heavy weight buffer.  The numbers of dirty heavy weight buffers
is limited to ensure that enough light weight buffers are available.

This is primarily implemented by changing getblk()'s mostly unused slpflag
parameter to a new blkflags parameter and adding a new buffer cache queue
called BQUEUE_DIRTY_HW.
sys/kern/vfs_bio.c
sys/sys/buf.h
sys/vfs/nfs/nfs_bio.c