svn commit: r296874 - user/alc/PQ_LAUNDRY/sys/vm

Mark Johnston markj at FreeBSD.org
Mon Mar 14 22:26:08 UTC 2016


Author: markj
Date: Mon Mar 14 22:26:06 2016
New Revision: 296874
URL: https://svnweb.freebsd.org/changeset/base/296874

Log:
  Decrement maxscan by the number of clustered pages.
  
  This helps ensure that pages in the laundry queue are not examined more
  than once during a scan. However, because pages are not removed from the
  queue until they have been laundered (i.e., the pageout I/O completes), this
  could cause the scan to stop before it has reached the end of the queue.
  Thus, dequeue all clustered pages before passing them to the pager. This
  moves some work out of the completion handler, which is usually invoked
  asynchronously. In a benchmark where multiple threads sequentially write
  to MAP_NOSYNC-mapped files, this change has no significant effect on
  runtime but reduces contention on the laundry queue lock (as measured with
  lockstat -e 0). Note however that this represents only a very small
  fraction of the total lock contention in the benchmark.
  
  Discussed with:	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 Mar 14 22:20:22 2016	(r296873)
+++ user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c	Mon Mar 14 22:26:06 2016	(r296874)
@@ -394,6 +394,7 @@ vm_pageout_cluster(vm_page_t m)
 	 */
 	vm_page_assert_unbusied(m);
 	KASSERT(m->hold_count == 0, ("vm_pageout_clean: page %p is held", m));
+	vm_page_dequeue(m);
 	vm_page_unlock(m);
 
 	mc[vm_pageout_page_count] = pb = ps = m;
@@ -445,6 +446,7 @@ more:
 			ib = 0;
 			break;
 		}
+		vm_page_dequeue(p);
 		vm_page_unlock(p);
 		mc[--page_base] = pb = p;
 		++pageout_count;
@@ -472,6 +474,7 @@ more:
 			vm_page_unlock(p);
 			break;
 		}
+		vm_page_dequeue(p);
 		vm_page_unlock(p);
 		mc[page_base + pageout_count] = ps = p;
 		++pageout_count;
@@ -903,7 +906,14 @@ vm_pageout_launder(struct vm_domain *vmd
 	vnodes_skipped = 0;
 
 	/*
-	 * XXX
+	 * Scan the laundry queue for pages eligible to be laundered.  We stop
+	 * once the target number of dirty pages have been laundered, or once
+	 * we've reached the end of the queue.  A single iteration of this loop
+	 * may cause more than one page to be laundered because of clustering.
+	 *
+	 * maxscan ensures that we don't re-examine requeued pages.  Any
+	 * additional pages written as part of a cluster are subtracted from
+	 * maxscan since they must be taken from the laundry queue.
 	 */
 	pq = &vmd->vmd_pagequeues[PQ_LAUNDRY];
 	maxscan = pq->pq_cnt;
@@ -1026,8 +1036,10 @@ requeue_page:
 				goto drop_page;
 			}
 			error = vm_pageout_clean(m, &numpagedout);
-			if (error == 0)
+			if (error == 0) {
 				launder -= numpagedout;
+				maxscan -= numpagedout - 1;
+			}
 			else if (error == EDEADLK) {
 				pageout_lock_miss++;
 				vnodes_skipped++;


More information about the svn-src-user mailing list