summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_rman.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-10-26 06:09:01 +0000
committerjhb <jhb@FreeBSD.org>2001-10-26 06:09:01 +0000
commitd410ad416617dd759436028e1cb0f545fe5f5d07 (patch)
tree040d2032f8f4bf1ba3f704fc7a04dc4ed5919a64 /sys/kern/subr_rman.c
parente655c7bdcaf79400600c7acbb120adeeaf3dfc6d (diff)
downloadFreeBSD-src-d410ad416617dd759436028e1cb0f545fe5f5d07.zip
FreeBSD-src-d410ad416617dd759436028e1cb0f545fe5f5d07.tar.gz
Use msleep() to avoid lost wakeup's instead of doing an ineffective
splhigh() before the mtx_unlock and tsleep(). The splhigh() was probably correct in the original code using simplelocks but is not correct in 5.0-current. Noticed by: Andrew Reiter <awr@FreeBSD.org>
Diffstat (limited to 'sys/kern/subr_rman.c')
-rw-r--r--sys/kern/subr_rman.c20
1 files changed, 5 insertions, 15 deletions
diff --git a/sys/kern/subr_rman.c b/sys/kern/subr_rman.c
index 1fbafd3..67791c2 100644
--- a/sys/kern/subr_rman.c
+++ b/sys/kern/subr_rman.c
@@ -426,35 +426,25 @@ rman_activate_resource(struct resource *r)
int
rman_await_resource(struct resource *r, int pri, int timo)
{
- int rv, s;
+ int rv;
struct resource *whohas;
struct rman *rm;
rm = r->r_rm;
+ mtx_lock(rm->rm_mtx);
for (;;) {
- mtx_lock(rm->rm_mtx);
rv = int_rman_activate_resource(rm, r, &whohas);
if (rv != EBUSY)
return (rv); /* returns with mutex held */
if (r->r_sharehead == 0)
panic("rman_await_resource");
- /*
- * splhigh hopefully will prevent a race between
- * mtx_unlock and tsleep where a process
- * could conceivably get in and release the resource
- * before we have a chance to sleep on it.
- */
- s = splhigh();
whohas->r_flags |= RF_WANTED;
- mtx_unlock(rm->rm_mtx);
- rv = tsleep(r->r_sharehead, pri, "rmwait", timo);
+ rv = msleep(r->r_sharehead, rm->rm_mtx, pri, "rmwait", timo);
if (rv) {
- splx(s);
- return rv;
+ mtx_unlock(rm->rm_mtx);
+ return (rv);
}
- mtx_lock(rm->rm_mtx);
- splx(s);
}
}
OpenPOWER on IntegriCloud