summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_pageout.c
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>1999-07-04 00:25:38 +0000
committermckusick <mckusick@FreeBSD.org>1999-07-04 00:25:38 +0000
commit9d4f0d78faaae0a9bd808ea72476ec00a6109c13 (patch)
tree1c352c42843e000e32439c87998b06c43fb0463d /sys/vm/vm_pageout.c
parent5360158df22b13c88c6aab8bdf7bceeb0a55c9a8 (diff)
downloadFreeBSD-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.c20
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.
OpenPOWER on IntegriCloud