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.
This commit is contained in:
Gleb Smirnoff 2015-05-02 20:27:37 +00:00
parent c8af988eae
commit 89c241d1a6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=282353

View File

@ -328,17 +328,16 @@ static int nsw_wcount_async; /* limit write buffers / asynchronous */
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, vm_page_t *m, int count,
/*
* 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 *vp, u_long nblks)
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);
}