svn commit: r188730 - in stable/7: share/man/man9 sys sys/contrib/pf sys/dev/ath/ath_hal sys/dev/cxgb sys/kern

John Baldwin jhb at FreeBSD.org
Tue Feb 17 13:02:38 PST 2009


Author: jhb
Date: Tue Feb 17 21:02:35 2009
New Revision: 188730
URL: http://svn.freebsd.org/changeset/base/188730

Log:
  MFC: Permit Giant to be passed as the explicit interlock either to
  msleep/mtx_sleep or the various cv_*wait*() routines.

Modified:
  stable/7/share/man/man9/   (props changed)
  stable/7/share/man/man9/condvar.9
  stable/7/share/man/man9/sleep.9
  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_condvar.c
  stable/7/sys/kern/kern_synch.c

Modified: stable/7/share/man/man9/condvar.9
==============================================================================
--- stable/7/share/man/man9/condvar.9	Tue Feb 17 20:35:11 2009	(r188729)
+++ stable/7/share/man/man9/condvar.9	Tue Feb 17 21:02:35 2009	(r188730)
@@ -136,9 +136,27 @@ When a thread waits on a condition,
 .Fa lock
 is atomically released before the thread is blocked, then reacquired
 before the function call returns.
+In addition, the thread will fully drop the
+.Va Giant
+mutex
+(even if recursed)
+while the it is suspended and will reacquire the
+.Va Giant
+mutex before the function returns.
 The
 .Fn cv_wait_unlock
 function does not reacquire the lock before returning.
+Note that the
+.Va Giant
+mutex may be specified as
+.Fa lock .
+However,
+.Va Giant
+may not be used as
+.Fa lock
+for the
+.Fn cv_wait_unlock
+function.
 All waiters must pass the same
 .Fa lock
 in conjunction with

Modified: stable/7/share/man/man9/sleep.9
==============================================================================
--- stable/7/share/man/man9/sleep.9	Tue Feb 17 20:35:11 2009	(r188729)
+++ stable/7/share/man/man9/sleep.9	Tue Feb 17 21:02:35 2009	(r188730)
@@ -153,6 +153,12 @@ mutex
 while the thread is suspended and will reacquire the
 .Va Giant
 mutex before the function returns.
+Note that the
+.Va Giant
+mutex may be specified as the lock to drop.
+In that case, however, the
+.Dv PDROP
+flag is not allowed.
 .Pp
 To avoid lost wakeups,
 either a lock should be used to protect against races,

Modified: stable/7/sys/kern/kern_condvar.c
==============================================================================
--- stable/7/sys/kern/kern_condvar.c	Tue Feb 17 20:35:11 2009	(r188729)
+++ stable/7/sys/kern/kern_condvar.c	Tue Feb 17 21:02:35 2009	(r188730)
@@ -100,6 +100,7 @@ _cv_wait(struct cv *cvp, struct lock_obj
 	int lock_state;
 
 	td = curthread;
+	lock_state = 0;
 #ifdef KTRACE
 	if (KTRPOINT(td, KTR_CSW))
 		ktrcsw(1, 0);
@@ -126,11 +127,13 @@ _cv_wait(struct cv *cvp, struct lock_obj
 	DROP_GIANT();
 
 	sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0);
-	if (class->lc_flags & LC_SLEEPABLE)
-		sleepq_release(cvp);
-	lock_state = class->lc_unlock(lock);
-	if (class->lc_flags & LC_SLEEPABLE)
-		sleepq_lock(cvp);
+	if (lock != &Giant.lock_object) {
+		if (class->lc_flags & LC_SLEEPABLE)
+			sleepq_release(cvp);
+		lock_state = class->lc_unlock(lock);
+		if (class->lc_flags & LC_SLEEPABLE)
+			sleepq_lock(cvp);
+	}
 	sleepq_wait(cvp);
 
 #ifdef KTRACE
@@ -138,8 +141,10 @@ _cv_wait(struct cv *cvp, struct lock_obj
 		ktrcsw(0, 0);
 #endif
 	PICKUP_GIANT();
-	class->lc_lock(lock, lock_state);
-	WITNESS_RESTORE(lock, lock_witness);
+	if (lock != &Giant.lock_object) {
+		class->lc_lock(lock, lock_state);
+		WITNESS_RESTORE(lock, lock_witness);
+	}
 }
 
 /*
@@ -160,6 +165,8 @@ _cv_wait_unlock(struct cv *cvp, struct l
 	CV_ASSERT(cvp, lock, td);
 	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
 	    "Waiting on \"%s\"", cvp->cv_description);
+	KASSERT(lock != &Giant.lock_object,
+	    ("cv_wait_unlock cannot be used with Giant"));
 	class = LOCK_CLASS(lock);
 
 	if (cold || panicstr) {
@@ -210,6 +217,7 @@ _cv_wait_sig(struct cv *cvp, struct lock
 
 	td = curthread;
 	p = td->td_proc;
+	lock_state = 0;
 #ifdef KTRACE
 	if (KTRPOINT(td, KTR_CSW))
 		ktrcsw(1, 0);
@@ -237,11 +245,13 @@ _cv_wait_sig(struct cv *cvp, struct lock
 
 	sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR |
 	    SLEEPQ_INTERRUPTIBLE, 0);
-	if (class->lc_flags & LC_SLEEPABLE)
-		sleepq_release(cvp);
-	lock_state = class->lc_unlock(lock);
-	if (class->lc_flags & LC_SLEEPABLE)
-		sleepq_lock(cvp);
+	if (lock != &Giant.lock_object) {
+		if (class->lc_flags & LC_SLEEPABLE)
+			sleepq_release(cvp);
+		lock_state = class->lc_unlock(lock);
+		if (class->lc_flags & LC_SLEEPABLE)
+			sleepq_lock(cvp);
+	}
 	rval = sleepq_wait_sig(cvp);
 
 #ifdef KTRACE
@@ -249,8 +259,10 @@ _cv_wait_sig(struct cv *cvp, struct lock
 		ktrcsw(0, 0);
 #endif
 	PICKUP_GIANT();
-	class->lc_lock(lock, lock_state);
-	WITNESS_RESTORE(lock, lock_witness);
+	if (lock != &Giant.lock_object) {
+		class->lc_lock(lock, lock_state);
+		WITNESS_RESTORE(lock, lock_witness);
+	}
 
 	return (rval);
 }
@@ -270,6 +282,7 @@ _cv_timedwait(struct cv *cvp, struct loc
 
 	td = curthread;
 	rval = 0;
+	lock_state = 0;
 #ifdef KTRACE
 	if (KTRPOINT(td, KTR_CSW))
 		ktrcsw(1, 0);
@@ -297,11 +310,13 @@ _cv_timedwait(struct cv *cvp, struct loc
 
 	sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0);
 	sleepq_set_timeout(cvp, timo);
-	if (class->lc_flags & LC_SLEEPABLE)
-		sleepq_release(cvp);
-	lock_state = class->lc_unlock(lock);
-	if (class->lc_flags & LC_SLEEPABLE)
-		sleepq_lock(cvp);
+	if (lock != &Giant.lock_object) {
+		if (class->lc_flags & LC_SLEEPABLE)
+			sleepq_release(cvp);
+		lock_state = class->lc_unlock(lock);
+		if (class->lc_flags & LC_SLEEPABLE)
+			sleepq_lock(cvp);
+	}
 	rval = sleepq_timedwait(cvp);
 
 #ifdef KTRACE
@@ -309,8 +324,10 @@ _cv_timedwait(struct cv *cvp, struct loc
 		ktrcsw(0, 0);
 #endif
 	PICKUP_GIANT();
-	class->lc_lock(lock, lock_state);
-	WITNESS_RESTORE(lock, lock_witness);
+	if (lock != &Giant.lock_object) {
+		class->lc_lock(lock, lock_state);
+		WITNESS_RESTORE(lock, lock_witness);
+	}
 
 	return (rval);
 }
@@ -333,6 +350,7 @@ _cv_timedwait_sig(struct cv *cvp, struct
 	td = curthread;
 	p = td->td_proc;
 	rval = 0;
+	lock_state = 0;
 #ifdef KTRACE
 	if (KTRPOINT(td, KTR_CSW))
 		ktrcsw(1, 0);
@@ -361,11 +379,13 @@ _cv_timedwait_sig(struct cv *cvp, struct
 	sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR |
 	    SLEEPQ_INTERRUPTIBLE, 0);
 	sleepq_set_timeout(cvp, timo);
-	if (class->lc_flags & LC_SLEEPABLE)
-		sleepq_release(cvp);
-	lock_state = class->lc_unlock(lock);
-	if (class->lc_flags & LC_SLEEPABLE)
-		sleepq_lock(cvp);
+	if (lock != &Giant.lock_object) {
+		if (class->lc_flags & LC_SLEEPABLE)
+			sleepq_release(cvp);
+		lock_state = class->lc_unlock(lock);
+		if (class->lc_flags & LC_SLEEPABLE)
+			sleepq_lock(cvp);
+	}
 	rval = sleepq_timedwait_sig(cvp);
 
 #ifdef KTRACE
@@ -373,8 +393,10 @@ _cv_timedwait_sig(struct cv *cvp, struct
 		ktrcsw(0, 0);
 #endif
 	PICKUP_GIANT();
-	class->lc_lock(lock, lock_state);
-	WITNESS_RESTORE(lock, lock_witness);
+	if (lock != &Giant.lock_object) {
+		class->lc_lock(lock, lock_state);
+		WITNESS_RESTORE(lock, lock_witness);
+	}
 
 	return (rval);
 }

Modified: stable/7/sys/kern/kern_synch.c
==============================================================================
--- stable/7/sys/kern/kern_synch.c	Tue Feb 17 20:35:11 2009	(r188729)
+++ stable/7/sys/kern/kern_synch.c	Tue Feb 17 21:02:35 2009	(r188730)
@@ -139,6 +139,9 @@ _sleep(void *ident, struct lock_object *
 	    ident == &lbolt, ("sleeping without a lock"));
 	KASSERT(p != NULL, ("msleep1"));
 	KASSERT(ident != NULL && TD_IS_RUNNING(td), ("msleep"));
+	if (priority & PDROP)
+		KASSERT(lock != NULL && lock != &Giant.lock_object,
+		    ("PDROP requires a non-Giant lock"));
 	if (lock != NULL)
 		class = LOCK_CLASS(lock);
 	else
@@ -180,7 +183,8 @@ _sleep(void *ident, struct lock_object *
 	    td->td_tid, p->p_pid, p->p_comm, wmesg, ident);
 
 	DROP_GIANT();
-	if (lock != NULL && !(class->lc_flags & LC_SLEEPABLE)) {
+	if (lock != NULL && lock != &Giant.lock_object &&
+	    !(class->lc_flags & LC_SLEEPABLE)) {
 		WITNESS_SAVE(lock, lock_witness);
 		lock_state = class->lc_unlock(lock);
 	} else
@@ -231,7 +235,7 @@ _sleep(void *ident, struct lock_object *
 		ktrcsw(0, 0);
 #endif
 	PICKUP_GIANT();
-	if (lock != NULL && !(priority & PDROP)) {
+	if (lock != NULL && lock != &Giant.lock_object && !(priority & PDROP)) {
 		class->lc_lock(lock, lock_state);
 		WITNESS_RESTORE(lock, lock_witness);
 	}


More information about the svn-src-all mailing list