Fix buffer cache deadlocks by splitting dirty buffers into two categories:
authorMatthew Dillon <dillon@dragonflybsd.org>
Thu, 10 Jan 2008 07:34:04 +0000 (07:34 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Thu, 10 Jan 2008 07:34:04 +0000 (07:34 +0000)
commit4b958e7b1d7cced2b6068daed31a38464e05e2f0
tree913e373d215fbf3200bd6b73346695b30d75bc30
parent6ea85f939708bab9adf487743019ce17933b5d31
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