From: Nicolas Thery Date: Wed, 4 Jun 2008 04:34:54 +0000 (+0000) Subject: Fix bugs in spin_trylock_wr(): X-Git-Tag: v2.0.1~473 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/74af985ee0ab2383594c810f54fc07da4f1e1062 Fix bugs in spin_trylock_wr(): - globaldata.gd_spinlock_wr was not decremented back on failure; - incorrect comparison in loop trying to clear cached shared bits (loop must fail if spinlock is still held for read by another cpu). Reviewed-by: dillon@ --- diff --git a/sys/kern/kern_spinlock.c b/sys/kern/kern_spinlock.c index 322f3850b2..02829a6daa 100644 --- a/sys/kern/kern_spinlock.c +++ b/sys/kern/kern_spinlock.c @@ -29,7 +29,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/kern_spinlock.c,v 1.14 2008/05/24 12:52:49 sephe Exp $ + * $DragonFly: src/sys/kern/kern_spinlock.c,v 1.15 2008/06/04 04:34:54 nth Exp $ */ #include @@ -125,7 +125,7 @@ exponential_init(struct exponential_backoff *bo, struct spinlock *mtx) * we couldn't clear (and also clear our exclusive bit). */ int -spin_trylock_wr_contested(struct spinlock *mtx, int value) +spin_trylock_wr_contested(globaldata_t gd, struct spinlock *mtx, int value) { int bit; @@ -133,14 +133,16 @@ spin_trylock_wr_contested(struct spinlock *mtx, int value) if ((value & SPINLOCK_EXCLUSIVE) == 0) { while (value) { bit = bsfl(value); - if (globaldata_find(bit)->gd_spinlock_rd != mtx) { + if (globaldata_find(bit)->gd_spinlock_rd == mtx) { atomic_swap_int(&mtx->lock, value); + --gd->gd_spinlocks_wr; return (FALSE); } value &= ~(1 << bit); } return (TRUE); } + --gd->gd_spinlocks_wr; return (FALSE); } diff --git a/sys/sys/spinlock2.h b/sys/sys/spinlock2.h index a2222cfd5f..b0fe767255 100644 --- a/sys/sys/spinlock2.h +++ b/sys/sys/spinlock2.h @@ -29,7 +29,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/spinlock2.h,v 1.11 2006/06/01 19:02:39 dillon Exp $ + * $DragonFly: src/sys/sys/spinlock2.h,v 1.12 2008/06/04 04:34:54 nth Exp $ */ #ifndef _SYS_SPINLOCK2_H_ @@ -67,7 +67,8 @@ #ifdef SMP -extern int spin_trylock_wr_contested(struct spinlock *mtx, int value); +extern int spin_trylock_wr_contested(globaldata_t gd, struct spinlock *mtx, + int value); extern void spin_lock_wr_contested(struct spinlock *mtx, int value); extern void spin_lock_rd_contested(struct spinlock *mtx); @@ -88,7 +89,7 @@ spin_trylock_wr(struct spinlock *mtx) ++gd->gd_spinlocks_wr; if ((value = atomic_swap_int(&mtx->lock, SPINLOCK_EXCLUSIVE)) != 0) - return (spin_trylock_wr_contested(mtx, value)); + return (spin_trylock_wr_contested(gd, mtx, value)); return (TRUE); }