svn commit: r192538 - in stable/7/sys: . contrib/pf dev/ath/ath_hal
dev/cxgb kern
John Baldwin
jhb at FreeBSD.org
Thu May 21 14:51:33 UTC 2009
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);
More information about the svn-src-stable-7
mailing list