From owner-svn-src-user@freebsd.org Mon Mar 14 22:26:07 2016 Return-Path: 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 C4BA5AD1436 for ; Mon, 14 Mar 2016 22:26:07 +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 83E5ADEF; Mon, 14 Mar 2016 22:26:07 +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 u2EMQ6Mi055655; Mon, 14 Mar 2016 22:26:06 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u2EMQ6YG055654; Mon, 14 Mar 2016 22:26:06 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201603142226.u2EMQ6YG055654@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Mon, 14 Mar 2016 22:26:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r296874 - 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.21 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Mar 2016 22:26:08 -0000 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++;