From owner-svn-src-head@freebsd.org Fri Oct 2 19:16:07 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 75F3A434577; Fri, 2 Oct 2020 19:16:07 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4C308R2X8tz4Y9k; Fri, 2 Oct 2020 19:16: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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 211B526E14; Fri, 2 Oct 2020 19:16: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 092JG6ru055419; Fri, 2 Oct 2020 19:16:06 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 092JG682055418; Fri, 2 Oct 2020 19:16:06 GMT (envelope-from markj@FreeBSD.org) Message-Id: <202010021916.092JG682055418@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Fri, 2 Oct 2020 19:16:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r366380 - head/sys/vm X-SVN-Group: head X-SVN-Commit-Author: markj X-SVN-Commit-Paths: head/sys/vm X-SVN-Commit-Revision: 366380 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 02 Oct 2020 19:16:07 -0000 Author: markj Date: Fri Oct 2 19:16:06 2020 New Revision: 366380 URL: https://svnweb.freebsd.org/changeset/base/366380 Log: vm_pageout: Avoid rounding down the inactive scan target With helper page daemon threads, enabled by default in r364786, we divide the inactive target by the number of threads, rounding down, and sum the total number of pages freed by the threads. This sum is compared with the original target, but by rounding down we might lose pages, causing the page daemon control loop to conclude that inactive queue scanning isn't keeping up with demand for free pages. Typically this results in excessive swapping. Fix the problem by accounting for the error in the main pagedaemon thread's target. Note that by default the problem will manifest only in systems with >16 CPUs in a NUMA domain. Reviewed by: cem Discussed with: dougm Reported and tested by: dhw, glebius Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D26610 Modified: head/sys/vm/vm_pageout.c Modified: head/sys/vm/vm_pageout.c ============================================================================== --- head/sys/vm/vm_pageout.c Fri Oct 2 19:04:29 2020 (r366379) +++ head/sys/vm/vm_pageout.c Fri Oct 2 19:16:06 2020 (r366380) @@ -1649,25 +1649,26 @@ reinsert: /* * Dispatch a number of inactive threads according to load and collect the - * results to prevent a coherent (CEM: incoherent?) view of paging activity on - * this domain. + * results to present a coherent view of paging activity on this domain. */ static int vm_pageout_inactive_dispatch(struct vm_domain *vmd, int shortage) { - u_int freed, pps, threads, us; + u_int freed, pps, slop, threads, us; vmd->vmd_inactive_shortage = shortage; + slop = 0; /* * If we have more work than we can do in a quarter of our interval, we * fire off multiple threads to process it. */ - if (vmd->vmd_inactive_threads > 1 && vmd->vmd_inactive_pps != 0 && + threads = vmd->vmd_inactive_threads; + if (threads > 1 && vmd->vmd_inactive_pps != 0 && shortage > vmd->vmd_inactive_pps / VM_INACT_SCAN_RATE / 4) { - threads = vmd->vmd_inactive_threads; - vm_domain_pageout_lock(vmd); vmd->vmd_inactive_shortage /= threads; + slop = shortage % threads; + vm_domain_pageout_lock(vmd); blockcount_acquire(&vmd->vmd_inactive_starting, threads - 1); blockcount_acquire(&vmd->vmd_inactive_running, threads - 1); wakeup(&vmd->vmd_inactive_shortage); @@ -1675,7 +1676,7 @@ vm_pageout_inactive_dispatch(struct vm_domain *vmd, in } /* Run the local thread scan. */ - vm_pageout_scan_inactive(vmd, vmd->vmd_inactive_shortage); + vm_pageout_scan_inactive(vmd, vmd->vmd_inactive_shortage + slop); /* * Block until helper threads report results and then accumulate