svn commit: r303207 - user/alc/PQ_LAUNDRY/sys/vm
Mark Johnston
markj at FreeBSD.org
Fri Jul 22 23:13:26 UTC 2016
Author: markj
Date: Fri Jul 22 23:13:25 2016
New Revision: 303207
URL: https://svnweb.freebsd.org/changeset/base/303207
Log:
Simplify the background laundering code and make it less aggressive.
- Remove the free page threshold for background laundering. It doesn't
really add anything: we only start background laundering if the
pagedaemon has been woken up recently, which means that the free page
count dipped below the pagedaemon wakeup threshold.
- Reduce the maximum background laundering rate to 8MB/s. In HEAD, we
will launder at most 32 * 16 pages * 2 pdwakeups/s = 4 MB/s during a
first pass over the inactive queue.
- When laundering, use a target of
0.1 * l(I)/l(L) * (free target - wakeup thresh)
instead of
0.5 * l(I)/l(L) * free target
so that we effectively launder pages at a tenth the rate that they're
reclaimed by the pagedaemon.
Reviewed by: alc
Modified:
user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c
Modified: user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c
==============================================================================
--- user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c Fri Jul 22 23:05:16 2016 (r303206)
+++ user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c Fri Jul 22 23:13:25 2016 (r303207)
@@ -232,21 +232,16 @@ SYSCTL_INT(_vm, OID_AUTO, act_scan_laund
CTLFLAG_RW, &act_scan_laundry_weight, 0,
"weight given to clean vs. dirty pages in active queue scans");
-static u_int bkgrd_launder_ratio = 100;
+static u_int bkgrd_launder_ratio = 50;
SYSCTL_UINT(_vm, OID_AUTO, bkgrd_launder_ratio,
CTLFLAG_RW, &bkgrd_launder_ratio, 0,
- "ratio of inactive to laundry pages to trigger background laundering");
+ "ratio of clean to dirty inactive pages needed to trigger laundering");
-static u_int bkgrd_launder_max = 32768;
+static u_int bkgrd_launder_max = 2048;
SYSCTL_UINT(_vm, OID_AUTO, bkgrd_launder_max,
CTLFLAG_RW, &bkgrd_launder_max, 0,
"maximum background laundering rate, in pages per second");
-static u_int bkgrd_launder_thresh;
-SYSCTL_UINT(_vm, OID_AUTO, bkgrd_launder_thresh,
- CTLFLAG_RW, &bkgrd_launder_thresh, 0,
- "free page threshold below which background laundering may be started");
-
#define VM_PAGEOUT_PAGE_COUNT 16
int vm_pageout_page_count = VM_PAGEOUT_PAGE_COUNT;
@@ -1097,7 +1092,7 @@ vm_pageout_laundry_worker(void *arg)
struct vm_domain *domain;
uint64_t ninact, nlaundry;
u_int wakeups, gen;
- int cycle, tcycle, domidx, launder, laundered;
+ int cycle, tcycle, domidx, launder;
int shortfall, prev_shortfall, target;
domidx = (uintptr_t)arg;
@@ -1110,10 +1105,6 @@ vm_pageout_laundry_worker(void *arg)
shortfall = prev_shortfall = 0;
target = 0;
- if (bkgrd_launder_thresh == 0)
- bkgrd_launder_thresh = max(vm_cnt.v_free_target / 2,
- 3 * vm_pageout_wakeup_thresh / 2);
-
/*
* The pageout laundry worker is never done, so loop forever.
*/
@@ -1160,49 +1151,54 @@ vm_pageout_laundry_worker(void *arg)
* There's no immediate need to launder any pages; see if we
* meet the conditions to perform background laundering:
*
- * 1. we haven't yet reached the target of the current
- * background laundering run, or
- * 2. the ratio of dirty to clean inactive pages exceeds the
- * background laundering threshold and the free page count is
- * low.
- *
- * We don't start a new background laundering run unless the
- * pagedaemon has been woken up at least once since the previous
- * run.
- */
- if (target > 0 && cycle != tcycle) {
- /* Continue an ongoing background run. */
- launder = target / (tcycle - (cycle % tcycle));
- goto dolaundry;
- }
-
+ * 1. The ratio of dirty to clean inactive pages exceeds the
+ * background laundering threshold and the pagedaemon has
+ * recently been woken up, or
+ * 2. we haven't yet reached the target of the current
+ * background laundering run.
+ */
ninact = vm_cnt.v_inactive_count;
nlaundry = vm_cnt.v_laundry_count;
wakeups = VM_METER_PCPU_CNT(v_pdwakeups);
- if (ninact > 0 &&
- wakeups != gen &&
- vm_cnt.v_free_count < bkgrd_launder_thresh &&
+ if (target == 0 && ninact > 0 && wakeups != gen &&
nlaundry * bkgrd_launder_ratio >= ninact) {
+ gen = wakeups;
+ /*
+ * The pagedaemon has woken up at least once since the
+ * last background laundering run and we're above the
+ * dirty page threshold. Launder some pages to balance
+ * the inactive and laundry queues. We attempt to
+ * finish within one second.
+ */
cycle = 0;
tcycle = VM_LAUNDER_INTERVAL;
- gen = wakeups;
- if (nlaundry >= ninact)
- target = vm_cnt.v_free_target;
- else
- target = (nlaundry * vm_cnt.v_free_target << 16) /
- ninact >> 16;
- target /= 2;
- if (target > bkgrd_launder_max)
- tcycle = target * VM_LAUNDER_INTERVAL /
- bkgrd_launder_max;
- launder = target / (tcycle - (cycle % tcycle));
+
+ /*
+ * Set our target to that of the pagedaemon, scaled by
+ * the relative lengths of the inactive and laundry
+ * queues. Divide by a fudge factor as well: we don't
+ * want to reclaim dirty pages at the same rate as clean
+ * pages.
+ */
+ target = vm_cnt.v_free_target -
+ vm_pageout_wakeup_thresh;
+ target = nlaundry * (u_int)target / ninact / 10;
+ if (target == 0)
+ target = 1;
+
+ /*
+ * Make sure we don't exceed the background laundering
+ * threshold.
+ */
+ target = min(target, bkgrd_launder_max);
}
+ if (target > 0 && cycle != tcycle)
+ launder = target / (tcycle - cycle);
dolaundry:
- if (launder > 0) {
- laundered = vm_pageout_launder(domain, launder);
- target -= min(laundered, target);
- }
+ if (launder > 0)
+ target -= min(vm_pageout_launder(domain, launder),
+ target);
tsleep(&vm_cnt.v_laundry_count, PVM, "laundr",
hz / VM_LAUNDER_INTERVAL);
More information about the svn-src-user
mailing list