diff options
author | mckusick <mckusick@FreeBSD.org> | 1999-07-04 00:25:38 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 1999-07-04 00:25:38 +0000 |
commit | 9d4f0d78faaae0a9bd808ea72476ec00a6109c13 (patch) | |
tree | 1c352c42843e000e32439c87998b06c43fb0463d /sys/vm/vm_pageout.c | |
parent | 5360158df22b13c88c6aab8bdf7bceeb0a55c9a8 (diff) | |
download | FreeBSD-src-9d4f0d78faaae0a9bd808ea72476ec00a6109c13.zip FreeBSD-src-9d4f0d78faaae0a9bd808ea72476ec00a6109c13.tar.gz |
The buffer queue mechanism has been reformulated. Instead of having
QUEUE_AGE, QUEUE_LRU, and QUEUE_EMPTY we instead have QUEUE_CLEAN,
QUEUE_DIRTY, QUEUE_EMPTY, and QUEUE_EMPTYKVA. With this patch clean
and dirty buffers have been separated. Empty buffers with KVM
assignments have been separated from truely empty buffers. getnewbuf()
has been rewritten and now operates in a 100% optimal fashion. That is,
it is able to find precisely the right kind of buffer it needs to
allocate a new buffer, defragment KVM, or to free-up an existing buffer
when the buffer cache is full (which is a steady-state situation for
the buffer cache).
Buffer flushing has been reorganized. Previously buffers were flushed
in the context of whatever process hit the conditions forcing buffer
flushing to occur. This resulted in processes blocking on conditions
unrelated to what they were doing. This also resulted in inappropriate
VFS stacking chains due to multiple processes getting stuck trying to
flush dirty buffers or due to a single process getting into a situation
where it might attempt to flush buffers recursively - a situation that
was only partially fixed in prior commits. We have added a new daemon
called the buf_daemon which is responsible for flushing dirty buffers
when the number of dirty buffers exceeds the vfs.hidirtybuffers limit.
This daemon attempts to dynamically adjust the rate at which dirty buffers
are flushed such that getnewbuf() calls (almost) never block.
The number of nbufs and amount of buffer space is now scaled past the
8MB limit that was previously imposed for systems with over 64MB of
memory, and the vfs.{lo,hi}dirtybuffers limits have been relaxed
somewhat. The number of physical buffers has been increased with the
intention that we will manage physical I/O differently in the future.
reassignbuf previously attempted to keep the dirtyblkhd list sorted which
could result in non-deterministic operation under certain conditions,
such as when a large number of dirty buffers are being managed. This
algorithm has been changed. reassignbuf now keeps buffers locally sorted
if it can do so cheaply, and otherwise gives up and adds buffers to
the head of the dirtyblkhd list. The new algorithm is deterministic but
not perfect. The new algorithm greatly reduces problems that previously
occured when write_behind was turned off in the system.
The P_FLSINPROG proc->p_flag bit has been replaced by the more descriptive
P_BUFEXHAUST bit. This bit allows processes working with filesystem
buffers to use available emergency reserves. Normal processes do not set
this bit and are not allowed to dig into emergency reserves. The purpose
of this bit is to avoid low-memory deadlocks.
A small race condition was fixed in getpbuf() in vm/vm_pager.c.
Submitted by: Matthew Dillon <dillon@apollo.backplane.com>
Reviewed by: Kirk McKusick <mckusick@mckusick.com>
Diffstat (limited to 'sys/vm/vm_pageout.c')
-rw-r--r-- | sys/vm/vm_pageout.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 414c922..90406fa 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -65,7 +65,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_pageout.c,v 1.142 1999/06/26 14:56:58 peter Exp $ + * $Id: vm_pageout.c,v 1.143 1999/07/01 13:21:46 peter Exp $ */ /* @@ -705,11 +705,9 @@ vm_pageout_scan() rescan0: addl_page_shortage = addl_page_shortage_init; maxscan = cnt.v_inactive_count; - for ( - m = TAILQ_FIRST(&vm_page_queue_inactive); - m != NULL && maxscan-- > 0 && page_shortage > 0; - m = next - ) { + for (m = TAILQ_FIRST(&vm_page_queue_inactive); + m != NULL && maxscan-- > 0 && page_shortage > 0; + m = next) { cnt.v_pdpages++; @@ -845,14 +843,13 @@ rescan0: * solution, though. */ - if ( - object->type != OBJT_DEFAULT && + if (object->type != OBJT_DEFAULT && object->type != OBJT_SWAP && - cnt.v_free_count < cnt.v_free_reserved - ) { + cnt.v_free_count < cnt.v_free_reserved) { s = splvm(); TAILQ_REMOVE(&vm_page_queue_inactive, m, pageq); - TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq); + TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, + pageq); splx(s); continue; } @@ -1349,6 +1346,7 @@ vm_pageout() max_page_launder = (cnt.v_page_count > 1800 ? 32 : 16); + curproc->p_flag |= P_BUFEXHAUST; swap_pager_swap_init(); /* * The pageout daemon is never done, so loop forever. |