summaryrefslogtreecommitdiffstats
path: root/sys/vm/swap_pager.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm/swap_pager.c')
-rw-r--r--sys/vm/swap_pager.c79
1 files changed, 41 insertions, 38 deletions
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 15e5b24..9a83989 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -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);
+}
OpenPOWER on IntegriCloud