From owner-svn-src-user@freebsd.org  Mon Oct 17 07:23:08 2016
Return-Path: <owner-svn-src-user@freebsd.org>
Delivered-To: svn-src-user@mailman.ysv.freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org
 [IPv6:2001:1900:2254:206a::19:1])
 by mailman.ysv.freebsd.org (Postfix) with ESMTP id 76766C13C76
 for <svn-src-user@mailman.ysv.freebsd.org>;
 Mon, 17 Oct 2016 07:23:08 +0000 (UTC)
 (envelope-from markj@FreeBSD.org)
Received: from repo.freebsd.org (repo.freebsd.org
 [IPv6:2610:1c1:1:6068::e6a:0])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (Client did not present a certificate)
 by mx1.freebsd.org (Postfix) with ESMTPS id 51C7D1608;
 Mon, 17 Oct 2016 07:23:08 +0000 (UTC)
 (envelope-from markj@FreeBSD.org)
Received: from repo.freebsd.org ([127.0.1.37])
 by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9H7N7pt009574;
 Mon, 17 Oct 2016 07:23:07 GMT (envelope-from markj@FreeBSD.org)
Received: (from markj@localhost)
 by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9H7N7bi009573;
 Mon, 17 Oct 2016 07:23:07 GMT (envelope-from markj@FreeBSD.org)
Message-Id: <201610170723.u9H7N7bi009573@repo.freebsd.org>
X-Authentication-Warning: repo.freebsd.org: markj set sender to
 markj@FreeBSD.org using -f
From: Mark Johnston <markj@FreeBSD.org>
Date: Mon, 17 Oct 2016 07:23:07 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-user@freebsd.org
Subject: svn commit: r307488 - user/alc/PQ_LAUNDRY/sys/vm
X-SVN-Group: user
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-BeenThere: svn-src-user@freebsd.org
X-Mailman-Version: 2.1.23
Precedence: list
List-Id: "SVN commit messages for the experimental &quot; user&quot;
 src tree" <svn-src-user.freebsd.org>
List-Unsubscribe: <https://lists.freebsd.org/mailman/options/svn-src-user>,
 <mailto:svn-src-user-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-user/>
List-Post: <mailto:svn-src-user@freebsd.org>
List-Help: <mailto:svn-src-user-request@freebsd.org?subject=help>
List-Subscribe: <https://lists.freebsd.org/mailman/listinfo/svn-src-user>,
 <mailto:svn-src-user-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Mon, 17 Oct 2016 07:23:08 -0000

Author: markj
Date: Mon Oct 17 07:23:07 2016
New Revision: 307488
URL: https://svnweb.freebsd.org/changeset/base/307488

Log:
  Handle laundering run preemption properly.
  
  Shortfall can preempt a background laundering, but not a shortfall
  laundering. Therefore:
  - make sure we don't reset the shortfall target if a shortfall request
    arrives while the system is already in shortfall, and
  - make sure we acknowledge a shortfall request by resetting
    vm_laundry_request if it arrives during background laundering.
  
  Also ensure that we sleep uninterruptibly between laundry cycles, and
  rename "cycle" to make its use more clear.
  
  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	Mon Oct 17 07:20:01 2016	(r307487)
+++ user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c	Mon Oct 17 07:23:07 2016	(r307488)
@@ -1115,8 +1115,7 @@ vm_pageout_laundry_worker(void *arg)
 	struct vm_pagequeue *pq;
 	uint64_t nclean, ndirty;
 	u_int last_launder, wakeups;
-	int cycle, domidx, last_target, launder, shortfall;
-	int sleeptime, target;
+	int domidx, last_target, launder, shortfall, shortfall_cycle, target;
 	bool in_shortfall;
 
 	domidx = (uintptr_t)arg;
@@ -1127,8 +1126,8 @@ vm_pageout_laundry_worker(void *arg)
 
 	shortfall = 0;
 	in_shortfall = false;
+	shortfall_cycle = 0;
 	target = 0;
-	cycle = 0;
 	last_launder = 0;
 
 	/*
@@ -1136,7 +1135,8 @@ vm_pageout_laundry_worker(void *arg)
 	 */
 	for (;;) {
 		KASSERT(target >= 0, ("negative target %d", target));
-		KASSERT(cycle >= 0, ("negative cycle %d", cycle));
+		KASSERT(shortfall_cycle >= 0,
+		    ("negative cycle %d", shortfall_cycle));
 		launder = 0;
 		wakeups = VM_METER_PCPU_CNT(v_pdwakeups);
 
@@ -1146,11 +1146,11 @@ vm_pageout_laundry_worker(void *arg)
 		 */
 		if (shortfall > 0) {
 			in_shortfall = true;
+			shortfall_cycle = VM_LAUNDER_RATE;
 			target = shortfall;
-			cycle = VM_LAUNDER_RATE;
 		} else if (!in_shortfall)
 			goto trybackground;
-		else if (cycle == 0 || vm_laundry_target() <= 0) {
+		else if (shortfall_cycle == 0 || vm_laundry_target() <= 0) {
 			/*
 			 * We recently entered shortfall and began laundering
 			 * pages.  If we have completed that laundering run
@@ -1163,7 +1163,7 @@ vm_pageout_laundry_worker(void *arg)
 			goto trybackground;
 		}
 		last_launder = wakeups;
-		launder = target / cycle--;
+		launder = target / shortfall_cycle--;
 		goto dolaundry;
 
 		/*
@@ -1229,16 +1229,26 @@ dolaundry:
 		 * started.  Otherwise, wait for a kick from the pagedaemon.
 		 */
 		vm_pagequeue_lock(pq);
-		if (target > 0 || vm_laundry_request != VM_LAUNDRY_IDLE)
-			sleeptime = hz / VM_LAUNDER_INTERVAL;
-		else
-			sleeptime = 0;
-		(void)mtx_sleep(&vm_laundry_request, vm_pagequeue_lockptr(pq),
-		    PVM, "laundr", sleeptime);
-		if (vm_laundry_request == VM_LAUNDRY_SHORTFALL)
+		if (target > 0 || vm_laundry_request != VM_LAUNDRY_IDLE) {
+			vm_pagequeue_unlock(pq);
+			pause("laundr", hz / VM_LAUNDER_INTERVAL);
+			vm_pagequeue_lock(pq);
+		} else
+			(void)mtx_sleep(&vm_laundry_request,
+			    vm_pagequeue_lockptr(pq), PVM, "laundr", 0);
+
+		/*
+		 * If the pagedaemon has indicated that it's in shortfall, start
+		 * a shortfall laundering unless we're already in the middle of
+		 * one.  This may preempt a background laundering.
+		 */
+		if (vm_laundry_request == VM_LAUNDRY_SHORTFALL &&
+		    (!in_shortfall || shortfall_cycle == 0)) {
 			shortfall = vm_laundry_target() + vm_pageout_deficit;
-		else
+			target = 0;
+		} else
 			shortfall = 0;
+
 		if (target == 0)
 			vm_laundry_request = VM_LAUNDRY_IDLE;
 		vm_pagequeue_unlock(pq);