From 2c8c434fa446d03382c8981b8039da8809759625 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sun, 17 Jan 2010 13:32:18 -0800 Subject: [PATCH] kernel - do not wire user pages in sysctl * sysctl processes have not assumed that user pages would be wired for a long time. * This also prevents sysctl from causing VM faults on the user memory after returning due to wiring changes. For example 'vmstat 1' no longer produces faults in the flt column generated by vmstat itself on every iteration. --- sys/kern/kern_sysctl.c | 12 ++++++++++-- sys/sys/sysctl.h | 3 +-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index cd118d6ca0..24bf124abf 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1017,14 +1017,18 @@ kernel_sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, s req.oldfunc = sysctl_old_kernel; req.newfunc = sysctl_new_kernel; +#if 0 req.lock = 1; +#endif sysctl_lock(LK_SHARED); error = sysctl_root(0, name, namelen, &req); +#if 0 if (req.lock == 2) vsunlock(req.oldptr, req.oldlen); +#endif sysctl_unlock(); @@ -1071,10 +1075,12 @@ sysctl_old_user(struct sysctl_req *req, const void *p, size_t l) int error = 0; size_t i = 0; +#if 0 if (req->lock == 1 && req->oldptr) { vslock(req->oldptr, req->oldlen); req->lock = 2; } +#endif if (req->oldptr) { i = l; if (i > req->oldlen - req->oldidx) @@ -1118,8 +1124,6 @@ sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid, while (oid && indx < CTL_MAXNAME) { if (oid->oid_number == name[indx]) { indx++; - if (oid->oid_kind & CTLFLAG_NOLOCK) - req->lock = 0; if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { if (oid->oid_handler != NULL || indx == namelen) { @@ -1268,7 +1272,9 @@ userland_sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, int inkern req.oldfunc = sysctl_old_user; req.newfunc = sysctl_new_user; +#if 0 req.lock = 1; +#endif req.td = curthread; sysctl_lock(LK_SHARED); @@ -1279,8 +1285,10 @@ userland_sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, int inkern } while (error == EAGAIN); req = req2; +#if 0 if (req.lock == 2) vsunlock(req.oldptr, req.oldlen); +#endif sysctl_unlock(); diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index f8023fb146..f6646b142a 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -89,7 +89,6 @@ struct ctlname { #define CTLFLAG_RD 0x80000000 /* Allow reads of variable */ #define CTLFLAG_WR 0x40000000 /* Allow writes to the variable */ #define CTLFLAG_RW (CTLFLAG_RD|CTLFLAG_WR) -#define CTLFLAG_NOLOCK 0x20000000 /* XXX Don't Lock */ #define CTLFLAG_ANYBODY 0x10000000 /* All users can set this var */ #define CTLFLAG_SECURE 0x08000000 /* Permit set only if securelevel<=0 */ #define CTLFLAG_PRISON 0x04000000 /* Prisoned roots can fiddle */ @@ -117,7 +116,7 @@ struct ctlname { */ struct sysctl_req { struct thread *td; - int lock; + int unused01; /* was lock */ void *oldptr; size_t oldlen; size_t oldidx; -- 2.11.4.GIT