kernel - do not wire user pages in sysctl
authorMatthew Dillon <dillon@apollo.backplane.com>
Sun, 17 Jan 2010 21:32:18 +0000 (13:32 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sun, 17 Jan 2010 21:32:18 +0000 (13:32 -0800)
* 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
sys/sys/sysctl.h

index cd118d6..24bf124 100644 (file)
@@ -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();
 
index f8023fb..f6646b1 100644 (file)
@@ -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;