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