Date: Thu, 21 May 2009 14:51:32 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r192538 - in stable/7/sys: . contrib/pf dev/ath/ath_hal dev/cxgb kern Message-ID: <200905211451.n4LEpWDu069827@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Thu May 21 14:51:31 2009 New Revision: 192538 URL: http://svn.freebsd.org/changeset/base/192538 Log: MFC: Use a separate sx lock to try to limit wiring too much user memory for userland sysctl requests. "Small" userland requests can now run concurrently. Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/ath/ath_hal/ (props changed) stable/7/sys/dev/cxgb/ (props changed) stable/7/sys/kern/kern_sysctl.c Modified: stable/7/sys/kern/kern_sysctl.c ============================================================================== --- stable/7/sys/kern/kern_sysctl.c Thu May 21 14:43:12 2009 (r192537) +++ stable/7/sys/kern/kern_sysctl.c Thu May 21 14:51:31 2009 (r192538) @@ -76,11 +76,12 @@ static MALLOC_DEFINE(M_SYSCTLTMP, "sysct * API rather than using the dynamic API. Use of the dynamic API is * strongly encouraged for most code. * - * This lock is also used to serialize userland sysctl requests. Some - * sysctls wire user memory, and serializing the requests limits the - * amount of wired user memory in use. + * The sysctlmemlock is used to limit the amount of user memory wired for + * sysctl requests. This is implemented by serializing any userland + * sysctl requests larger than a single page via an exclusive lock. */ static struct sx sysctllock; +static struct sx sysctlmemlock; #define SYSCTL_SLOCK() sx_slock(&sysctllock) #define SYSCTL_SUNLOCK() sx_sunlock(&sysctllock) @@ -542,6 +543,7 @@ sysctl_register_all(void *arg) { struct sysctl_oid **oidp; + sx_init(&sysctlmemlock, "sysctl mem"); SYSCTL_INIT(); SYSCTL_XLOCK(); SET_FOREACH(oidp, sysctl_set) @@ -1466,7 +1468,7 @@ userland_sysctl(struct thread *td, int * size_t *oldlenp, int inkernel, void *new, size_t newlen, size_t *retval, int flags) { - int error = 0; + int error = 0, memlocked; struct sysctl_req req; bzero(&req, sizeof req); @@ -1506,13 +1508,19 @@ userland_sysctl(struct thread *td, int * if (KTRPOINT(curthread, KTR_SYSCTL)) ktrsysctl(name, namelen); #endif - - SYSCTL_XLOCK(); + + if (req.oldlen > PAGE_SIZE) { + memlocked = 1; + sx_xlock(&sysctlmemlock); + } else + memlocked = 0; for (;;) { req.oldidx = 0; req.newidx = 0; + SYSCTL_SLOCK(); error = sysctl_root(0, name, namelen, &req); + SYSCTL_SUNLOCK(); if (error != EAGAIN) break; uio_yield(); @@ -1521,7 +1529,8 @@ userland_sysctl(struct thread *td, int * if (req.lock == REQ_WIRED && req.validlen > 0) vsunlock(req.oldptr, req.validlen); - SYSCTL_XUNLOCK(); + if (memlocked) + sx_xunlock(&sysctlmemlock); if (error && error != ENOMEM) return (error);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905211451.n4LEpWDu069827>