svn commit: r190179 - in stable/6/sys: . contrib/pf dev/cxgb kern

Konstantin Belousov kib at FreeBSD.org
Fri Mar 20 14:47:28 PDT 2009


Author: kib
Date: Fri Mar 20 21:47:26 2009
New Revision: 190179
URL: http://svn.freebsd.org/changeset/base/190179

Log:
  MFC r185983:
  The userland_sysctl() function retries sysctl_root() until returned
  error is not EAGAIN. Several sysctls that inspect another process use
  p_candebug() for checking access right for the curproc. p_candebug()
  returns EAGAIN for some reasons, in particular, for the process doing
  exec() now. If execing process tries to lock Giant, we get a livelock,
  because sysctl handlers are covered by Giant, and often do not sleep.
  
  Break the livelock by dropping Giant and allowing other threads to
  execute in the EAGAIN loop.
  
  This commit does not merge the following change, as was discussed with jhb:
  [Also, do not return EAGAIN from p_candebug() when process is executing,
  use more appropriate EBUSY error.]
  
  MFC r185987:
  Uio_yield() already does DROP_GIANT/PICKUP_GIANT, no need to repeat this
  around the call.
  
  Tested by:	Eugene Grosbein <eugen kuzbass ru>

Modified:
  stable/6/sys/   (props changed)
  stable/6/sys/contrib/pf/   (props changed)
  stable/6/sys/dev/cxgb/   (props changed)
  stable/6/sys/kern/kern_sysctl.c

Modified: stable/6/sys/kern/kern_sysctl.c
==============================================================================
--- stable/6/sys/kern/kern_sysctl.c	Fri Mar 20 21:46:28 2009	(r190178)
+++ stable/6/sys/kern/kern_sysctl.c	Fri Mar 20 21:47:26 2009	(r190179)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mutex.h>
 #include <sys/sx.h>
 #include <sys/sysproto.h>
+#include <sys/uio.h>
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
 
@@ -1374,11 +1375,14 @@ userland_sysctl(struct thread *td, int *
 
 	SYSCTL_LOCK();
 
-	do {
+	for (;;) {
 		req.oldidx = 0;
 		req.newidx = 0;
 		error = sysctl_root(0, name, namelen, &req);
-	} while (error == EAGAIN);
+		if (error != EAGAIN)
+			break;
+		uio_yield();
+	}
 
 	if (req.lock == REQ_WIRED && req.validlen > 0)
 		vsunlock(req.oldptr, req.validlen);


More information about the svn-src-all mailing list