summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDon Lewis <truckman@FreeBSD.org>2006-01-25 01:03:34 +0000
committerDon Lewis <truckman@FreeBSD.org>2006-01-25 01:03:34 +0000
commitf4af687a3b1661f426397859bb0c47d658edcedc (patch)
treeaa35f34c3e4e057ece92157cdb9b46303d9f5677
parent67f7fe8c01d7f92f8446f4a88cde8ec1e95f1b95 (diff)
Notes
-rw-r--r--sys/kern/kern_sysctl.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 6a64a1a475ab..38fb5dc86edb 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1118,7 +1118,8 @@ int
sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
{
int ret;
- size_t wiredlen;
+ size_t i, wiredlen;
+ char *cp, dummy;
wiredlen = (len > 0 && len < req->oldlen) ? len : req->oldlen;
ret = 0;
@@ -1131,6 +1132,16 @@ sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
return (ret);
wiredlen = 0;
}
+ /*
+ * Touch all the wired pages to avoid PTE modified
+ * bit emulation traps on Alpha while holding locks
+ * in the sysctl handler.
+ */
+ for (i = (wiredlen + PAGE_SIZE - 1) / PAGE_SIZE,
+ cp = req->oldptr; i > 0; i--, cp += PAGE_SIZE) {
+ copyin(cp, &dummy, 1);
+ copyout(&dummy, cp, 1);
+ }
}
req->lock = REQ_WIRED;
req->validlen = wiredlen;