And I love you for it.
If you like playing with big giant buffer caches, please try this diff
and let me know if you have any issues with it.
This diff fixes an issue where we weren't handling the inactive pages
case correctly in the page daemon. In a nutshell, inactive pages is a
count maintained by the page daemon to know how many memory pages it
can recover cheaply. they are pages that have been marked as
reclaimable by the clock hand algorithm in the pager. We weren't dealing
with this correctly wrt backing off the buffer cache, and accounting
for pages we could reclaim cheaply, which now includes the buffer cache,
the result being that we could sit there and swap with the buffer cache
holding on to memory it should release.
This could use some relatively large exposure on all arches, and on large
and small memory machines. Please let me know if you encounter any issues
with it.
Thanks
-Bob
Index: sys/mount.h
===================================================================
RCS file: /cvs/src/sys/sys/mount.h,v
retrieving revision 1.98
diff -u sys/mount.h
--- sys/mount.h 9 Aug 2009 14:37:46 -0000 1.98
+++ sys/mount.h 29 Sep 2009 02:02:22 -0000
@@ -509,6 +509,8 @@
extern long buflowpages, bufhighpages, bufbackpages;
#define BUFPAGES_DEFICIT (((buflowpages - bcstats.numbufpages) < 0) ? 0 \
: buflowpages - bcstats.numbufpages)
+#define BUFPAGES_INACT (((bcstats.numcleanpages - buflowpages) < 0) ? 0 \
+ : bcstats.numcleanpages - buflowpages)
extern int bufcachepercent;
extern void bufadjust(int);
extern int bufbackoff(void);
Index: uvm/uvm_page.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_page.c,v
retrieving revision 1.96
diff -u uvm/uvm_page.c
--- uvm/uvm_page.c 13 Aug 2009 15:29:59 -0000 1.96
+++ uvm/uvm_page.c 29 Sep 2009 02:02:23 -0000
@@ -794,7 +794,7 @@
*/
if ((uvmexp.free - BUFPAGES_DEFICIT) < uvmexp.freemin ||
((uvmexp.free - BUFPAGES_DEFICIT) < uvmexp.freetarg &&
- uvmexp.inactive < uvmexp.inactarg))
+ (uvmexp.inactive + BUFPAGES_INACT) < uvmexp.inactarg))
wakeup(&uvm.pagedaemon);
/*
Index: uvm/uvm_pdaemon.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_pdaemon.c,v
retrieving revision 1.54
diff -u uvm/uvm_pdaemon.c
--- uvm/uvm_pdaemon.c 8 Aug 2009 13:43:59 -0000 1.54
+++ uvm/uvm_pdaemon.c 29 Sep 2009 02:02:23 -0000
@@ -212,7 +212,6 @@
*/
for (;;) {
- int scanned = 0;
uvm_lock_fpageq();
UVMHIST_LOG(pdhist," <<SLEEPING>>",0,0,0,0);
msleep(&uvm.pagedaemon, &uvm.fpageqlock, PVM | PNORELOCK,
@@ -242,17 +241,11 @@
/*
* get pages from the buffer cache, or scan if needed
*/
- if ((uvmexp.free - BUFPAGES_DEFICIT) < uvmexp.freetarg) {
- if (bufbackoff() == -1) {
+ if (((uvmexp.free - BUFPAGES_DEFICIT) < uvmexp.freetarg) ||
+ ((uvmexp.inactive + BUFPAGES_INACT) < uvmexp.inactarg)) {
+ if (bufbackoff() == -1)
uvmpd_scan();
- scanned = 1;
- } else
- scanned = 0;
}
-
- if (!scanned && (uvmexp.inactive < uvmexp.inactarg))
- uvmpd_scan();
-
/*
* if there's any free memory to be had,