Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 20 Sep 2015 19:20:04 +0000 (UTC)
From:      Alan Cox <alc@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r288025 - head/sys/vm
Message-ID:  <201509201920.t8KJK4I3048409@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: alc
Date: Sun Sep 20 19:20:03 2015
New Revision: 288025
URL: https://svnweb.freebsd.org/changeset/base/288025

Log:
  Correct a non-fatal error in vm_pageout_worker().  vm_pageout_worker()
  should not assume that vm_pages_needed will remain set while it sleeps.
  Other threads can clear vm_pages_needed by performing a sufficient
  number of vm_page_free() calls, e.g., process termination.  The effect
  of this error was that vm_pageout_worker() would free and/or launder
  pages when, in fact, there was no shortage of free pages.
  
  Rewrite a nearby comment to describe all of the possible cases and not
  just the most common case.  The problem being that the comment made
  the most common case seem like the only case.
  
  Reviewed by:	kib
  MFC after:	1 week
  Sponsored by:	EMC / Isilon Storage Division

Modified:
  head/sys/vm/vm_pageout.c

Modified: head/sys/vm/vm_pageout.c
==============================================================================
--- head/sys/vm/vm_pageout.c	Sun Sep 20 14:28:06 2015	(r288024)
+++ head/sys/vm/vm_pageout.c	Sun Sep 20 19:20:03 2015	(r288025)
@@ -1638,9 +1638,15 @@ vm_pageout_worker(void *arg)
 		}
 		if (vm_pages_needed) {
 			/*
-			 * Still not done, take a second pass without waiting
-			 * (unlimited dirty cleaning), otherwise sleep a bit
-			 * and try again.
+			 * We're still not done.  Either vm_pages_needed was
+			 * set by another thread during the previous scan
+			 * (typically, this happens during a level 0 scan) or
+			 * vm_pages_needed was already set and the scan failed
+			 * to free enough pages.  If we haven't yet performed
+			 * a level >= 2 scan (unlimited dirty cleaning), then
+			 * upgrade the level and scan again now.  Otherwise,
+			 * sleep a bit and try again later.  While sleeping,
+			 * vm_pages_needed can be cleared.
 			 */
 			if (domain->vmd_pass > 1)
 				msleep(&vm_pages_needed,
@@ -1651,15 +1657,14 @@ vm_pageout_worker(void *arg)
 			 * Good enough, sleep until required to refresh
 			 * stats.
 			 */
-			domain->vmd_pass = 0;
 			msleep(&vm_pages_needed, &vm_page_queue_free_mtx,
 			    PVM, "psleep", hz);
-
 		}
 		if (vm_pages_needed) {
 			vm_cnt.v_pdwakeups++;
 			domain->vmd_pass++;
-		}
+		} else
+			domain->vmd_pass = 0;
 		mtx_unlock(&vm_page_queue_free_mtx);
 		vm_pageout_scan(domain, domain->vmd_pass);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201509201920.t8KJK4I3048409>