From owner-svn-src-head@FreeBSD.ORG Sat May 2 20:27:38 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 6DFA7F9A; Sat, 2 May 2015 20:27:38 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::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 5BD3D1190; Sat, 2 May 2015 20:27:38 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t42KRclA077996; Sat, 2 May 2015 20:27:38 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t42KRcMT077995; Sat, 2 May 2015 20:27:38 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201505022027.t42KRcMT077995@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Sat, 2 May 2015 20:27:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r282353 - head/sys/vm X-SVN-Group: head 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.20 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: Sat, 02 May 2015 20:27:38 -0000 Author: glebius Date: Sat May 2 20:27:37 2015 New Revision: 282353 URL: https://svnweb.freebsd.org/changeset/base/282353 Log: Instead of reading, validating and adjusting value of the vm.swap_async_max in the main swapper work cycle, do it in the sysctl handler. This removes extra mutex acquisition from the main cycle and makes the sysctl knob return error on an invalid value, instead of accepting and fixing it. Reviewed by: kib Sponsored by: Netflix Sponsored by: Nginx, Inc. Modified: head/sys/vm/swap_pager.c Modified: head/sys/vm/swap_pager.c ============================================================================== --- head/sys/vm/swap_pager.c Sat May 2 20:14:43 2015 (r282352) +++ head/sys/vm/swap_pager.c Sat May 2 20:27:37 2015 (r282353) @@ -328,17 +328,16 @@ static int nsw_wcount_async; /* limit wr static int nsw_wcount_async_max;/* assigned maximum */ static int nsw_cluster_max; /* maximum VOP I/O allowed */ +static int sysctl_swap_async_max(SYSCTL_HANDLER_ARGS); +SYSCTL_PROC(_vm, OID_AUTO, swap_async_max, CTLTYPE_INT | CTLFLAG_RW, + NULL, 0, sysctl_swap_async_max, "I", "Maximum running async swap ops"); + static struct swblock **swhash; static int swhash_mask; static struct mtx swhash_mtx; -static int swap_async_max = 4; /* maximum in-progress async I/O's */ static struct sx sw_alloc_sx; - -SYSCTL_INT(_vm, OID_AUTO, swap_async_max, - CTLFLAG_RW, &swap_async_max, 0, "Maximum running async swap ops"); - /* * "named" and "unnamed" anon region objects. Try to reduce the overhead * of searching a named list by hashing it just a little. @@ -1350,39 +1349,6 @@ swap_pager_putpages(vm_object_t object, /* * Step 2 * - * Update nsw parameters from swap_async_max sysctl values. - * Do not let the sysop crash the machine with bogus numbers. - */ - mtx_lock(&pbuf_mtx); - if (swap_async_max != nsw_wcount_async_max) { - int n; - - /* - * limit range - */ - if ((n = swap_async_max) > nswbuf / 2) - n = nswbuf / 2; - if (n < 1) - n = 1; - swap_async_max = n; - - /* - * Adjust difference ( if possible ). If the current async - * count is too low, we may not be able to make the adjustment - * at this time. - */ - n -= nsw_wcount_async_max; - if (nsw_wcount_async + n >= 0) { - nsw_wcount_async += n; - nsw_wcount_async_max += n; - wakeup(&nsw_wcount_async); - } - } - mtx_unlock(&pbuf_mtx); - - /* - * Step 3 - * * Assign swap blocks and issue I/O. We reallocate swap on the fly. * The page is left dirty until the pageout operation completes * successfully. @@ -2835,3 +2801,40 @@ swaponvp(struct thread *td, struct vnode NODEV, 0); return (0); } + +static int +sysctl_swap_async_max(SYSCTL_HANDLER_ARGS) +{ + int error, new, n; + + new = nsw_wcount_async_max; + error = sysctl_handle_int(oidp, &new, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + + if (new > nswbuf / 2 || new < 1) + return (EINVAL); + + mtx_lock(&pbuf_mtx); + while (nsw_wcount_async_max != new) { + /* + * Adjust difference. If the current async count is too low, + * we will need to sqeeze our update slowly in. Sleep with a + * higher priority than getpbuf() to finish faster. + */ + n = new - nsw_wcount_async_max; + if (nsw_wcount_async + n >= 0) { + nsw_wcount_async += n; + nsw_wcount_async_max += n; + wakeup(&nsw_wcount_async); + } else { + nsw_wcount_async_max -= nsw_wcount_async; + nsw_wcount_async = 0; + msleep(&nsw_wcount_async, &pbuf_mtx, PSWP, + "swpsysctl", 0); + } + } + mtx_unlock(&pbuf_mtx); + + return (0); +}