summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormjg <mjg@FreeBSD.org>2015-07-30 19:52:43 +0000
committermjg <mjg@FreeBSD.org>2015-07-30 19:52:43 +0000
commitc31894c74212e2dde0e307e23eee2228db47979e (patch)
treeb30edd8fce68fa1251c56ab7294588e848a2342d /sys
parent110b4521d0bc3c98ae53306a541fd51f03d0147a (diff)
downloadFreeBSD-src-c31894c74212e2dde0e307e23eee2228db47979e.zip
FreeBSD-src-c31894c74212e2dde0e307e23eee2228db47979e.tar.gz
Revert r285125 until rmlocks get fixed.
Right now there is a chance that sysctl unregister will cause reader to block on the sx lock associated with sysctl rmlock, in which case kernels with debug enabled will panic.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_linker.c8
-rw-r--r--sys/kern/kern_sysctl.c204
-rw-r--r--sys/kern/vfs_init.c4
-rw-r--r--sys/sys/sysctl.h4
4 files changed, 111 insertions, 109 deletions
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index bb92e18..a4fde06 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -292,10 +292,10 @@ linker_file_register_sysctls(linker_file_t lf)
return;
sx_xunlock(&kld_sx);
- sysctl_wlock();
+ sysctl_xlock();
for (oidp = start; oidp < stop; oidp++)
sysctl_register_oid(*oidp);
- sysctl_wunlock();
+ sysctl_xunlock();
sx_xlock(&kld_sx);
}
@@ -313,10 +313,10 @@ linker_file_unregister_sysctls(linker_file_t lf)
return;
sx_xunlock(&kld_sx);
- sysctl_wlock();
+ sysctl_xlock();
for (oidp = start; oidp < stop; oidp++)
sysctl_unregister_oid(*oidp);
- sysctl_wunlock();
+ sysctl_xunlock();
sx_xlock(&kld_sx);
}
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 52075e4..b32198f 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$");
#include <sys/jail.h>
#include <sys/lock.h>
#include <sys/mutex.h>
-#include <sys/rmlock.h>
#include <sys/sbuf.h>
#include <sys/sx.h>
#include <sys/sysproto.h>
@@ -78,7 +77,7 @@ static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer");
* The sysctllock protects the MIB tree. It also protects sysctl
* contexts used with dynamic sysctls. The sysctl_register_oid() and
* sysctl_unregister_oid() routines require the sysctllock to already
- * be held, so the sysctl_wlock() and sysctl_wunlock() routines are
+ * be held, so the sysctl_xlock() and sysctl_xunlock() routines are
* provided for the few places in the kernel which need to use that
* API rather than using the dynamic API. Use of the dynamic API is
* strongly encouraged for most code.
@@ -87,21 +86,20 @@ static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer");
* sysctl requests. This is implemented by serializing any userland
* sysctl requests larger than a single page via an exclusive lock.
*/
-static struct rmlock sysctllock;
+static struct sx sysctllock;
static struct sx sysctlmemlock;
-#define SYSCTL_WLOCK() rm_wlock(&sysctllock)
-#define SYSCTL_WUNLOCK() rm_wunlock(&sysctllock)
-#define SYSCTL_RLOCK(tracker) rm_rlock(&sysctllock, (tracker))
-#define SYSCTL_RUNLOCK(tracker) rm_runlock(&sysctllock, (tracker))
-#define SYSCTL_WLOCKED() rm_wowned(&sysctllock)
-#define SYSCTL_ASSERT_LOCKED() rm_assert(&sysctllock, RA_LOCKED)
-#define SYSCTL_ASSERT_WLOCKED() rm_assert(&sysctllock, RA_WLOCKED)
-#define SYSCTL_ASSERT_RLOCKED() rm_assert(&sysctllock, RA_RLOCKED)
-#define SYSCTL_INIT() rm_init_flags(&sysctllock, "sysctl lock", \
- RM_SLEEPABLE)
+#define SYSCTL_XLOCK() sx_xlock(&sysctllock)
+#define SYSCTL_XUNLOCK() sx_xunlock(&sysctllock)
+#define SYSCTL_SLOCK() sx_slock(&sysctllock)
+#define SYSCTL_SUNLOCK() sx_sunlock(&sysctllock)
+#define SYSCTL_XLOCKED() sx_xlocked(&sysctllock)
+#define SYSCTL_ASSERT_LOCKED() sx_assert(&sysctllock, SA_LOCKED)
+#define SYSCTL_ASSERT_XLOCKED() sx_assert(&sysctllock, SA_XLOCKED)
+#define SYSCTL_ASSERT_SLOCKED() sx_assert(&sysctllock, SA_SLOCKED)
+#define SYSCTL_INIT() sx_init(&sysctllock, "sysctl lock")
#define SYSCTL_SLEEP(ch, wmesg, timo) \
- rm_sleep(ch, &sysctllock, 0, wmesg, timo)
+ sx_sleep(ch, &sysctllock, 0, wmesg, timo)
static int sysctl_root(SYSCTL_HANDLER_ARGS);
@@ -113,6 +111,29 @@ static int sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del,
static int sysctl_old_kernel(struct sysctl_req *, const void *, size_t);
static int sysctl_new_kernel(struct sysctl_req *, void *, size_t);
+static void
+sysctl_lock(bool xlock)
+{
+
+ if (xlock)
+ SYSCTL_XLOCK();
+ else
+ SYSCTL_SLOCK();
+}
+
+static bool
+sysctl_unlock(void)
+{
+ bool xlocked;
+
+ xlocked = SYSCTL_XLOCKED();
+ if (xlocked)
+ SYSCTL_XUNLOCK();
+ else
+ SYSCTL_SUNLOCK();
+ return (xlocked);
+}
+
static struct sysctl_oid *
sysctl_find_oidname(const char *name, struct sysctl_oid_list *list)
{
@@ -133,32 +154,29 @@ sysctl_find_oidname(const char *name, struct sysctl_oid_list *list)
* Order by number in each list.
*/
void
-sysctl_wlock(void)
+sysctl_xlock(void)
{
- SYSCTL_WLOCK();
+ SYSCTL_XLOCK();
}
void
-sysctl_wunlock(void)
+sysctl_xunlock(void)
{
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
}
static int
sysctl_root_handler_locked(struct sysctl_oid *oid, void *arg1, intptr_t arg2,
- struct sysctl_req *req, struct rm_priotracker *tracker)
+ struct sysctl_req *req)
{
int error;
+ bool xlocked;
if (oid->oid_kind & CTLFLAG_DYN)
atomic_add_int(&oid->oid_running, 1);
-
- if (tracker != NULL)
- SYSCTL_RUNLOCK(tracker);
- else
- SYSCTL_WUNLOCK();
+ xlocked = sysctl_unlock();
if (!(oid->oid_kind & CTLFLAG_MPSAFE))
mtx_lock(&Giant);
@@ -166,11 +184,7 @@ sysctl_root_handler_locked(struct sysctl_oid *oid, void *arg1, intptr_t arg2,
if (!(oid->oid_kind & CTLFLAG_MPSAFE))
mtx_unlock(&Giant);
- if (tracker != NULL)
- SYSCTL_RLOCK(tracker);
- else
- SYSCTL_WLOCK();
-
+ sysctl_lock(xlocked);
if (oid->oid_kind & CTLFLAG_DYN) {
if (atomic_fetchadd_int(&oid->oid_running, -1) == 1 &&
(oid->oid_kind & CTLFLAG_DYING) != 0)
@@ -269,7 +283,7 @@ sysctl_load_tunable_by_oid_locked(struct sysctl_oid *oidp)
return;
}
error = sysctl_root_handler_locked(oidp, oidp->oid_arg1,
- oidp->oid_arg2, &req, NULL);
+ oidp->oid_arg2, &req);
if (error != 0)
printf("Setting sysctl %s failed: %d\n", path + rem, error);
if (penv != NULL)
@@ -289,7 +303,7 @@ sysctl_register_oid(struct sysctl_oid *oidp)
* First check if another oid with the same name already
* exists in the parent's list.
*/
- SYSCTL_ASSERT_WLOCKED();
+ SYSCTL_ASSERT_XLOCKED();
p = sysctl_find_oidname(oidp->oid_name, parent);
if (p != NULL) {
if ((p->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
@@ -383,7 +397,7 @@ sysctl_unregister_oid(struct sysctl_oid *oidp)
struct sysctl_oid *p;
int error;
- SYSCTL_ASSERT_WLOCKED();
+ SYSCTL_ASSERT_XLOCKED();
error = ENOENT;
if (oidp->oid_number == OID_AUTO) {
error = EINVAL;
@@ -439,7 +453,7 @@ sysctl_ctx_free(struct sysctl_ctx_list *clist)
* XXX This algorithm is a hack. But I don't know any
* XXX better solution for now...
*/
- SYSCTL_WLOCK();
+ SYSCTL_XLOCK();
TAILQ_FOREACH(e, clist, link) {
error = sysctl_remove_oid_locked(e->entry, 0, 0);
if (error)
@@ -459,7 +473,7 @@ sysctl_ctx_free(struct sysctl_ctx_list *clist)
e1 = TAILQ_PREV(e1, sysctl_ctx_list, link);
}
if (error) {
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
return(EBUSY);
}
/* Now really delete the entries */
@@ -473,7 +487,7 @@ sysctl_ctx_free(struct sysctl_ctx_list *clist)
free(e, M_SYSCTLOID);
e = e1;
}
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
return (error);
}
@@ -483,7 +497,7 @@ sysctl_ctx_entry_add(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
{
struct sysctl_ctx_entry *e;
- SYSCTL_ASSERT_WLOCKED();
+ SYSCTL_ASSERT_XLOCKED();
if (clist == NULL || oidp == NULL)
return(NULL);
e = malloc(sizeof(struct sysctl_ctx_entry), M_SYSCTLOID, M_WAITOK);
@@ -498,7 +512,7 @@ sysctl_ctx_entry_find(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
{
struct sysctl_ctx_entry *e;
- SYSCTL_ASSERT_WLOCKED();
+ SYSCTL_ASSERT_XLOCKED();
if (clist == NULL || oidp == NULL)
return(NULL);
TAILQ_FOREACH(e, clist, link) {
@@ -520,15 +534,15 @@ sysctl_ctx_entry_del(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
if (clist == NULL || oidp == NULL)
return (EINVAL);
- SYSCTL_WLOCK();
+ SYSCTL_XLOCK();
e = sysctl_ctx_entry_find(clist, oidp);
if (e != NULL) {
TAILQ_REMOVE(clist, e, link);
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
free(e, M_SYSCTLOID);
return (0);
} else {
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
return (ENOENT);
}
}
@@ -544,9 +558,9 @@ sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse)
{
int error;
- SYSCTL_WLOCK();
+ SYSCTL_XLOCK();
error = sysctl_remove_oid_locked(oidp, del, recurse);
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
return (error);
}
@@ -558,14 +572,14 @@ sysctl_remove_name(struct sysctl_oid *parent, const char *name,
int error;
error = ENOENT;
- SYSCTL_WLOCK();
+ SYSCTL_XLOCK();
SLIST_FOREACH_SAFE(p, SYSCTL_CHILDREN(parent), oid_link, tmp) {
if (strcmp(p->oid_name, name) == 0) {
error = sysctl_remove_oid_locked(p, del, recurse);
break;
}
}
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
return (error);
}
@@ -577,7 +591,7 @@ sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse)
struct sysctl_oid *p, *tmp;
int error;
- SYSCTL_ASSERT_WLOCKED();
+ SYSCTL_ASSERT_XLOCKED();
if (oidp == NULL)
return(EINVAL);
if ((oidp->oid_kind & CTLFLAG_DYN) == 0) {
@@ -652,7 +666,7 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent,
if (parent == NULL)
return(NULL);
/* Check if the node already exists, otherwise create it */
- SYSCTL_WLOCK();
+ SYSCTL_XLOCK();
oidp = sysctl_find_oidname(name, parent);
if (oidp != NULL) {
if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
@@ -660,10 +674,10 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent,
/* Update the context */
if (clist != NULL)
sysctl_ctx_entry_add(clist, oidp);
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
return (oidp);
} else {
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
printf("can't re-use a leaf (%s)!\n", name);
return (NULL);
}
@@ -686,7 +700,7 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent,
sysctl_ctx_entry_add(clist, oidp);
/* Register this oid */
sysctl_register_oid(oidp);
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
return (oidp);
}
@@ -700,10 +714,10 @@ sysctl_rename_oid(struct sysctl_oid *oidp, const char *name)
char *oldname;
newname = strdup(name, M_SYSCTLOID);
- SYSCTL_WLOCK();
+ SYSCTL_XLOCK();
oldname = __DECONST(char *, oidp->oid_name);
oidp->oid_name = newname;
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
free(oldname, M_SYSCTLOID);
}
@@ -715,21 +729,21 @@ sysctl_move_oid(struct sysctl_oid *oid, struct sysctl_oid_list *parent)
{
struct sysctl_oid *oidp;
- SYSCTL_WLOCK();
+ SYSCTL_XLOCK();
if (oid->oid_parent == parent) {
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
return (0);
}
oidp = sysctl_find_oidname(oid->oid_name, parent);
if (oidp != NULL) {
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
return (EEXIST);
}
sysctl_unregister_oid(oid);
oid->oid_parent = parent;
oid->oid_number = OID_AUTO;
sysctl_register_oid(oid);
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
return (0);
}
@@ -745,10 +759,10 @@ sysctl_register_all(void *arg)
sx_init(&sysctlmemlock, "sysctl mem");
SYSCTL_INIT();
- SYSCTL_WLOCK();
+ SYSCTL_XLOCK();
SET_FOREACH(oidp, sysctl_set)
sysctl_register_oid(*oidp);
- SYSCTL_WUNLOCK();
+ SYSCTL_XUNLOCK();
}
SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_FIRST, sysctl_register_all, 0);
@@ -818,15 +832,14 @@ sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i)
static int
sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS)
{
- struct rm_priotracker tracker;
int error;
error = priv_check(req->td, PRIV_SYSCTL_DEBUG);
if (error)
return (error);
- SYSCTL_RLOCK(&tracker);
+ SYSCTL_SLOCK();
sysctl_sysctl_debug_dump_node(&sysctl__children, 0);
- SYSCTL_RUNLOCK(&tracker);
+ SYSCTL_SUNLOCK();
return (ENOENT);
}
@@ -842,10 +855,9 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
int error = 0;
struct sysctl_oid *oid;
struct sysctl_oid_list *lsp = &sysctl__children, *lsp2;
- struct rm_priotracker tracker;
char buf[10];
- SYSCTL_RLOCK(&tracker);
+ SYSCTL_SLOCK();
while (namelen) {
if (!lsp) {
snprintf(buf,sizeof(buf),"%d",*name);
@@ -888,7 +900,7 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
}
error = SYSCTL_OUT(req, "", 1);
out:
- SYSCTL_RUNLOCK(&tracker);
+ SYSCTL_SUNLOCK();
return (error);
}
@@ -967,12 +979,11 @@ sysctl_sysctl_next(SYSCTL_HANDLER_ARGS)
int i, j, error;
struct sysctl_oid *oid;
struct sysctl_oid_list *lsp = &sysctl__children;
- struct rm_priotracker tracker;
int newoid[CTL_MAXNAME];
- SYSCTL_RLOCK(&tracker);
+ SYSCTL_SLOCK();
i = sysctl_sysctl_next_ls(lsp, name, namelen, newoid, &j, 1, &oid);
- SYSCTL_RUNLOCK(&tracker);
+ SYSCTL_SUNLOCK();
if (i)
return (ENOENT);
error = SYSCTL_OUT(req, newoid, j * sizeof (int));
@@ -1031,7 +1042,6 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS)
char *p;
int error, oid[CTL_MAXNAME], len = 0;
struct sysctl_oid *op = 0;
- struct rm_priotracker tracker;
if (!req->newlen)
return (ENOENT);
@@ -1048,9 +1058,9 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS)
p [req->newlen] = '\0';
- SYSCTL_RLOCK(&tracker);
+ SYSCTL_SLOCK();
error = name2oid(p, oid, &len, &op);
- SYSCTL_RUNLOCK(&tracker);
+ SYSCTL_SUNLOCK();
free(p, M_SYSCTL);
@@ -1073,10 +1083,9 @@ static int
sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
{
struct sysctl_oid *oid;
- struct rm_priotracker tracker;
int error;
- SYSCTL_RLOCK(&tracker);
+ SYSCTL_SLOCK();
error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
if (error)
goto out;
@@ -1090,7 +1099,7 @@ sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
goto out;
error = SYSCTL_OUT(req, oid->oid_fmt, strlen(oid->oid_fmt) + 1);
out:
- SYSCTL_RUNLOCK(&tracker);
+ SYSCTL_SUNLOCK();
return (error);
}
@@ -1102,10 +1111,9 @@ static int
sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS)
{
struct sysctl_oid *oid;
- struct rm_priotracker tracker;
int error;
- SYSCTL_RLOCK(&tracker);
+ SYSCTL_SLOCK();
error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
if (error)
goto out;
@@ -1116,7 +1124,7 @@ sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS)
}
error = SYSCTL_OUT(req, oid->oid_descr, strlen(oid->oid_descr) + 1);
out:
- SYSCTL_RUNLOCK(&tracker);
+ SYSCTL_SUNLOCK();
return (error);
}
@@ -1421,7 +1429,9 @@ kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
req.newfunc = sysctl_new_kernel;
req.lock = REQ_UNWIRED;
+ SYSCTL_SLOCK();
error = sysctl_root(0, name, namelen, &req);
+ SYSCTL_SUNLOCK();
if (req.lock == REQ_WIRED && req.validlen > 0)
vsunlock(req.oldptr, req.validlen);
@@ -1598,14 +1608,13 @@ static int
sysctl_root(SYSCTL_HANDLER_ARGS)
{
struct sysctl_oid *oid;
- struct rm_priotracker tracker;
int error, indx, lvl;
- SYSCTL_RLOCK(&tracker);
+ SYSCTL_ASSERT_SLOCKED();
error = sysctl_find_oid(arg1, arg2, &oid, &indx, req);
if (error)
- goto out;
+ return (error);
if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
/*
@@ -1613,17 +1622,13 @@ sysctl_root(SYSCTL_HANDLER_ARGS)
* no handler. Inform the user that it's a node.
* The indx may or may not be the same as namelen.
*/
- if (oid->oid_handler == NULL) {
- error = EISDIR;
- goto out;
- }
+ if (oid->oid_handler == NULL)
+ return (EISDIR);
}
/* Is this sysctl writable? */
- if (req->newptr && !(oid->oid_kind & CTLFLAG_WR)) {
- error = EPERM;
- goto out;
- }
+ if (req->newptr && !(oid->oid_kind & CTLFLAG_WR))
+ return (EPERM);
KASSERT(req->td != NULL, ("sysctl_root(): req->td == NULL"));
@@ -1633,11 +1638,10 @@ sysctl_root(SYSCTL_HANDLER_ARGS)
* writing unless specifically granted for the node.
*/
if (IN_CAPABILITY_MODE(req->td)) {
- if ((req->oldptr && !(oid->oid_kind & CTLFLAG_CAPRD)) ||
- (req->newptr && !(oid->oid_kind & CTLFLAG_CAPWR))) {
- error = EPERM;
- goto out;
- }
+ if (req->oldptr && !(oid->oid_kind & CTLFLAG_CAPRD))
+ return (EPERM);
+ if (req->newptr && !(oid->oid_kind & CTLFLAG_CAPWR))
+ return (EPERM);
}
#endif
@@ -1646,7 +1650,7 @@ sysctl_root(SYSCTL_HANDLER_ARGS)
lvl = (oid->oid_kind & CTLMASK_SECURE) >> CTLSHIFT_SECURE;
error = securelevel_gt(req->td->td_ucred, lvl);
if (error)
- goto out;
+ return (error);
}
/* Is this sysctl writable by only privileged users? */
@@ -1664,13 +1668,11 @@ sysctl_root(SYSCTL_HANDLER_ARGS)
priv = PRIV_SYSCTL_WRITE;
error = priv_check(req->td, priv);
if (error)
- goto out;
+ return (error);
}
- if (!oid->oid_handler) {
- error = EINVAL;
- goto out;
- }
+ if (!oid->oid_handler)
+ return (EINVAL);
if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
arg1 = (int *)arg1 + indx;
@@ -1683,18 +1685,16 @@ sysctl_root(SYSCTL_HANDLER_ARGS)
error = mac_system_check_sysctl(req->td->td_ucred, oid, arg1, arg2,
req);
if (error != 0)
- goto out;
+ return (error);
#endif
#ifdef VIMAGE
if ((oid->oid_kind & CTLFLAG_VNET) && arg1 != NULL)
arg1 = (void *)(curvnet->vnet_data_base + (uintptr_t)arg1);
#endif
- error = sysctl_root_handler_locked(oid, arg1, arg2, req, &tracker);
+ error = sysctl_root_handler_locked(oid, arg1, arg2, req);
KFAIL_POINT_ERROR(_debug_fail_point, sysctl_running, error);
-out:
- SYSCTL_RUNLOCK(&tracker);
return (error);
}
@@ -1794,7 +1794,9 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
for (;;) {
req.oldidx = 0;
req.newidx = 0;
+ SYSCTL_SLOCK();
error = sysctl_root(0, name, namelen, &req);
+ SYSCTL_SUNLOCK();
if (error != EAGAIN)
break;
kern_yield(PRI_USER);
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c
index 9ac193a..f935954 100644
--- a/sys/kern/vfs_init.c
+++ b/sys/kern/vfs_init.c
@@ -291,7 +291,7 @@ vfs_register(struct vfsconf *vfc)
* preserved by re-registering the oid after modifying its
* number.
*/
- sysctl_wlock();
+ sysctl_xlock();
SLIST_FOREACH(oidp, SYSCTL_CHILDREN(&sysctl___vfs), oid_link) {
if (strcmp(oidp->oid_name, vfc->vfc_name) == 0) {
sysctl_unregister_oid(oidp);
@@ -300,7 +300,7 @@ vfs_register(struct vfsconf *vfc)
break;
}
}
- sysctl_wunlock();
+ sysctl_xunlock();
return (0);
}
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 4c66431..988dbae 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -807,8 +807,8 @@ int userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
size_t *retval, int flags);
int sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid,
int *nindx, struct sysctl_req *req);
-void sysctl_wlock(void);
-void sysctl_wunlock(void);
+void sysctl_xlock(void);
+void sysctl_xunlock(void);
int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len);
struct sbuf;
OpenPOWER on IntegriCloud