From owner-svn-src-user@freebsd.org Mon May 23 06:13:37 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 05030B46FE7 for ; Mon, 23 May 2016 06:13:37 +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 D4AB11F84; Mon, 23 May 2016 06:13:36 +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 u4N6DaVs004176; Mon, 23 May 2016 06:13:36 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u4N6DZa8004174; Mon, 23 May 2016 06:13:35 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201605230613.u4N6DZa8004174@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Mon, 23 May 2016 06:13:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r300477 - 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.22 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, 23 May 2016 06:13:37 -0000 Author: markj Date: Mon May 23 06:13:35 2016 New Revision: 300477 URL: https://svnweb.freebsd.org/changeset/base/300477 Log: Run dirty pages through the inactive queue before the laundry queue. This change modifies the active queue aging scan to place dirty pages in the inactive queue rather than the laundry queue. vm_page_advise() is modified similarly. One side effect of this change is that dirty pages are given more time to be reactivated instead of being paged out. However, this is not its primary motivation. Pushing dirty pages through the inactive queue establishes a temporal relationship between the inactive and laundry queues and results in a more cohesive LRU page replacement mechanism. In the absence of this change, the pagedaemon and laundry threads have little information about each other's activity, and we can say little about the relative ages of the pages at the beginning of the inactive and laundry queues at a given point in time. However, in general we would prefer to avoid laundering a given page until some number of clean pages have been reclaimed in an attempt to satisfy a page shortage. The implemented laundering policy uses the ratio of dirty to clean inactive pages to set a minimum threshold for laundering, but without a shared queue, we cannot be satisfied that all less-recently-used clean pages have been reclaimed before deciding to launder a dirty page. A downside to this change is that the pagedaemons are forced to expend more CPU cycles handling dirty pages, as they must now examine dirty pages twice. However, this cost is small relative to that of a swap pageout. It may be reasonable to move vnode-backed pages directly to the laundry queue, but this change aims to minimize differences in behaviour with respect to HEAD. Reviewed by: alc Modified: user/alc/PQ_LAUNDRY/sys/vm/vm_page.c user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c Modified: user/alc/PQ_LAUNDRY/sys/vm/vm_page.c ============================================================================== --- user/alc/PQ_LAUNDRY/sys/vm/vm_page.c Mon May 23 06:04:38 2016 (r300476) +++ user/alc/PQ_LAUNDRY/sys/vm/vm_page.c Mon May 23 06:13:35 2016 (r300477) @@ -3273,14 +3273,13 @@ vm_page_advise(vm_page_t m, int advice) vm_page_dirty(m); /* - * Place clean pages at the head of the inactive queue rather than the - * tail, thus defeating the queue's LRU operation and ensuring that the - * page will be reused quickly. + * Place clean pages near the head of the inactive queue rather than + * the tail, thus defeating the queue's LRU operation and ensuring that + * the page will be reused quickly. Dirty pages are given a chance to + * cycle once through the inactive queue before becoming eligible for + * laundering. */ - if (m->dirty == 0) - _vm_page_deactivate(m, TRUE); - else - vm_page_launder(m); + _vm_page_deactivate(m, m->dirty == 0); } /* Modified: user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c ============================================================================== --- user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c Mon May 23 06:04:38 2016 (r300476) +++ user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c Mon May 23 06:13:35 2016 (r300477) @@ -1553,15 +1553,35 @@ drop_page: /* Dequeue to avoid later lock recursion. */ vm_page_dequeue_locked(m); #if 0 + /* + * This requires the object write lock. It might be a + * good idea during a page shortage, but might also + * cause contention with a concurrent attempt to launder + * pages from this object. + */ if (m->object->ref_count != 0) vm_page_test_dirty(m); #endif - if (m->dirty == 0) { + /* + * When not short for inactive pages, let dirty pages go + * through the inactive queue before moving to the + * laundry queues. This gives them some extra time to + * be reactivated, potentially avoiding an expensive + * pageout. During a page shortage, the inactive queue + * is necessarily small, so we may move dirty pages + * directly to the laundry queue. + */ + if (page_shortage <= 0) vm_page_deactivate(m); - page_shortage -= act_scan_laundry_weight; - } else { - vm_page_launder(m); - page_shortage--; + else { + if (m->dirty == 0) { + vm_page_deactivate(m); + page_shortage -= + act_scan_laundry_weight; + } else { + vm_page_launder(m); + page_shortage--; + } } } else vm_page_requeue_locked(m);