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-stable-7
mailing list