svn commit: r303055 - in user/alc/PQ_LAUNDRY/sys: sys vm

Mark Johnston markj at FreeBSD.org
Wed Jul 20 00:43:27 UTC 2016


Author: markj
Date: Wed Jul 20 00:43:26 2016
New Revision: 303055
URL: https://svnweb.freebsd.org/changeset/base/303055

Log:
  Rework shortfall laundering.
  
  - Redefine the shortfall threshold using the vm_laundering_needed()
    predicate. Now, we are in shortfall when the inactive queue is below
    its target and the free page count is below the pagedaemon wakeup
    threshold. In this state we attempt to launder enough pages to meet
    the inactive and free page targets. This improves behaviour in the
    case where almost all of the system's non-wired memory is active, but
    there is little memory pressure. In particular, there's no need to
    launder aggressively if v_inact_count < v_inact_target and
    v_free_count is above the pagedaemon wakeup threshold.
  - The performance is unchanged when the system is persistently in
    shortfall, for example when many threads are writing sequentially to
    large memory-mapped files.
  - Add some comments which hopefully make the logic easier to follow.
  
  Reviewed by:	alc

Modified:
  user/alc/PQ_LAUNDRY/sys/sys/vmmeter.h
  user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c

Modified: user/alc/PQ_LAUNDRY/sys/sys/vmmeter.h
==============================================================================
--- user/alc/PQ_LAUNDRY/sys/sys/vmmeter.h	Wed Jul 20 00:37:03 2016	(r303054)
+++ user/alc/PQ_LAUNDRY/sys/sys/vmmeter.h	Wed Jul 20 00:43:26 2016	(r303055)
@@ -198,6 +198,17 @@ vm_laundry_target(void)
 }
 
 /*
+ * Return true if we are in shortfall and must begin laundering dirty memory.
+ */
+static inline int
+vm_laundering_needed(void)
+{
+
+	return (vm_cnt.v_inactive_count < vm_cnt.v_inactive_target &&
+	    vm_paging_needed());
+}
+
+/*
  * Obtain the value of a per-CPU counter.
  */
 #define	VM_METER_PCPU_CNT(member)					\

Modified: user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c
==============================================================================
--- user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c	Wed Jul 20 00:37:03 2016	(r303054)
+++ user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c	Wed Jul 20 00:43:26 2016	(r303055)
@@ -1122,30 +1122,38 @@ vm_pageout_laundry_worker(void *arg)
 		launder = 0;
 
 		/*
-		 * First determine whether we're in shortfall.  If so, there's
-		 * an impending need for clean pages.  We attempt to launder the
-		 * target within one pagedaemon sleep period.
+		 * First determine whether we need to launder pages to meet a
+		 * shortage of free pages.
 		 */
-		shortfall = vm_laundry_target() + vm_pageout_deficit;
-		if (shortfall > 0) {
+		if (vm_laundering_needed()) {
+			shortfall = vm_laundry_target() + vm_pageout_deficit;
 			/*
-			 * If the shortfall has grown since the last cycle or
-			 * we're still in shortfall despite a previous
-			 * laundering run, start a new run.
+			 * If we're in shortfall and we haven't yet started a
+			 * laundering cycle to get us out of it, begin a run.
+			 * If we're still in shortfall despite a previous
+			 * laundering run, start a new one.
 			 */
-			if (shortfall > prev_shortfall || cycle == tcycle) {
+			if (prev_shortfall == 0 || cycle == tcycle) {
 				target = shortfall;
 				cycle = 0;
 				tcycle = VM_LAUNDER_RATE;
 			}
 			prev_shortfall = shortfall;
-			launder = target / (tcycle - (cycle % tcycle));
-			goto launder;
-		} else {
-			if (prev_shortfall > 0)
-				/* We're out of shortfall; the target is met. */
-				target = 0;
-			shortfall = prev_shortfall = 0;
+		}
+		if (prev_shortfall > 0) {
+			/*
+			 * We entered shortfall at some point in the recent
+			 * past.  If we have reached our target, or the
+			 * laundering run is finished and we're not currently in
+			 * shortfall, we have no immediate need to launder
+			 * pages.  Otherwise keep laundering.
+			 */
+			if (vm_laundry_target() <= 0 || cycle == tcycle) {
+				shortfall = prev_shortfall = target = 0;
+			} else {
+				launder = target / (tcycle - cycle);
+				goto dolaundry;
+			}
 		}
 
 		/*
@@ -1165,7 +1173,7 @@ vm_pageout_laundry_worker(void *arg)
 		if (target > 0 && cycle != tcycle) {
 			/* Continue an ongoing background run. */
 			launder = target / (tcycle - (cycle % tcycle));
-			goto launder;
+			goto dolaundry;
 		}
 
 		ninact = vm_cnt.v_inactive_count;
@@ -1190,7 +1198,7 @@ vm_pageout_laundry_worker(void *arg)
 			launder = target / (tcycle - (cycle % tcycle));
 		}
 
-launder:
+dolaundry:
 		if (launder > 0) {
 			laundered = vm_pageout_launder(domain, launder);
 			target -= min(laundered, target);


More information about the svn-src-user mailing list