From owner-svn-src-user@freebsd.org Wed Jul 20 00:43:27 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 AF2A6B9DB9C for ; Wed, 20 Jul 2016 00:43:27 +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 7D13E16BB; Wed, 20 Jul 2016 00:43:27 +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 u6K0hQrb047242; Wed, 20 Jul 2016 00:43:26 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u6K0hQ7e047240; Wed, 20 Jul 2016 00:43:26 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201607200043.u6K0hQ7e047240@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Wed, 20 Jul 2016 00:43:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r303055 - in user/alc/PQ_LAUNDRY/sys: 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: Wed, 20 Jul 2016 00:43:27 -0000 Author: markj Date: Wed Jul 20 00:43:26 2016 New Revision: 303055 URL: https://svnweb.freebsd.org/changeset/base/303055 Log: Rework shortfall laundering. - Redefine the shortfall threshold using the vm_laundering_needed() predicate. Now, we are in shortfall when the inactive queue is below its target and the free page count is below the pagedaemon wakeup threshold. In this state we attempt to launder enough pages to meet the inactive and free page targets. This improves behaviour in the case where almost all of the system's non-wired memory is active, but there is little memory pressure. In particular, there's no need to launder aggressively if v_inact_count < v_inact_target and v_free_count is above the pagedaemon wakeup threshold. - The performance is unchanged when the system is persistently in shortfall, for example when many threads are writing sequentially to large memory-mapped files. - Add some comments which hopefully make the logic easier to follow. Reviewed by: alc Modified: user/alc/PQ_LAUNDRY/sys/sys/vmmeter.h user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c Modified: user/alc/PQ_LAUNDRY/sys/sys/vmmeter.h ============================================================================== --- user/alc/PQ_LAUNDRY/sys/sys/vmmeter.h Wed Jul 20 00:37:03 2016 (r303054) +++ user/alc/PQ_LAUNDRY/sys/sys/vmmeter.h Wed Jul 20 00:43:26 2016 (r303055) @@ -198,6 +198,17 @@ vm_laundry_target(void) } /* + * Return true if we are in shortfall and must begin laundering dirty memory. + */ +static inline int +vm_laundering_needed(void) +{ + + return (vm_cnt.v_inactive_count < vm_cnt.v_inactive_target && + vm_paging_needed()); +} + +/* * Obtain the value of a per-CPU counter. */ #define VM_METER_PCPU_CNT(member) \ Modified: user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c ============================================================================== --- user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c Wed Jul 20 00:37:03 2016 (r303054) +++ user/alc/PQ_LAUNDRY/sys/vm/vm_pageout.c Wed Jul 20 00:43:26 2016 (r303055) @@ -1122,30 +1122,38 @@ vm_pageout_laundry_worker(void *arg) launder = 0; /* - * First determine whether we're in shortfall. If so, there's - * an impending need for clean pages. We attempt to launder the - * target within one pagedaemon sleep period. + * First determine whether we need to launder pages to meet a + * shortage of free pages. */ - shortfall = vm_laundry_target() + vm_pageout_deficit; - if (shortfall > 0) { + if (vm_laundering_needed()) { + shortfall = vm_laundry_target() + vm_pageout_deficit; /* - * If the shortfall has grown since the last cycle or - * we're still in shortfall despite a previous - * laundering run, start a new run. + * If we're in shortfall and we haven't yet started a + * laundering cycle to get us out of it, begin a run. + * If we're still in shortfall despite a previous + * laundering run, start a new one. */ - if (shortfall > prev_shortfall || cycle == tcycle) { + if (prev_shortfall == 0 || cycle == tcycle) { target = shortfall; cycle = 0; tcycle = VM_LAUNDER_RATE; } prev_shortfall = shortfall; - launder = target / (tcycle - (cycle % tcycle)); - goto launder; - } else { - if (prev_shortfall > 0) - /* We're out of shortfall; the target is met. */ - target = 0; - shortfall = prev_shortfall = 0; + } + if (prev_shortfall > 0) { + /* + * We entered shortfall at some point in the recent + * past. If we have reached our target, or the + * laundering run is finished and we're not currently in + * shortfall, we have no immediate need to launder + * pages. Otherwise keep laundering. + */ + if (vm_laundry_target() <= 0 || cycle == tcycle) { + shortfall = prev_shortfall = target = 0; + } else { + launder = target / (tcycle - cycle); + goto dolaundry; + } } /* @@ -1165,7 +1173,7 @@ vm_pageout_laundry_worker(void *arg) if (target > 0 && cycle != tcycle) { /* Continue an ongoing background run. */ launder = target / (tcycle - (cycle % tcycle)); - goto launder; + goto dolaundry; } ninact = vm_cnt.v_inactive_count; @@ -1190,7 +1198,7 @@ vm_pageout_laundry_worker(void *arg) launder = target / (tcycle - (cycle % tcycle)); } -launder: +dolaundry: if (launder > 0) { laundered = vm_pageout_launder(domain, launder); target -= min(laundered, target);