summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_sysctl.c
diff options
context:
space:
mode:
authortruckman <truckman@FreeBSD.org>2006-01-25 01:03:34 +0000
committertruckman <truckman@FreeBSD.org>2006-01-25 01:03:34 +0000
commit9f8a407ccb300c9276aa63a86ef00e3a1d8c43ee (patch)
treeaa35f34c3e4e057ece92157cdb9b46303d9f5677 /sys/kern/kern_sysctl.c
parent4730881b84dbcf19ec1fe034d784fcdddf207c96 (diff)
downloadFreeBSD-src-9f8a407ccb300c9276aa63a86ef00e3a1d8c43ee.zip
FreeBSD-src-9f8a407ccb300c9276aa63a86ef00e3a1d8c43ee.tar.gz
Touch all the pages wired by sysctl_wire_old_buffer() to avoid PTE
modified bit emulation traps on Alpha while holding locks in the sysctl handler. A better solution would be to pass a hint to the Alpha pmap code to tell mark these pages as modified when they as they are being wired, but that appears to be more difficult to implement. Suggested by: jhb MFC after: 3 days
Diffstat (limited to 'sys/kern/kern_sysctl.c')
-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 6a64a1a..38fb5dc 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;
OpenPOWER on IntegriCloud