DragonFly kernel List (threaded) for 2008-06
DragonFly BSD
DragonFly kernel List (threaded) for 2008-06
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

spin_trylock_wr() patch


From: "Nicolas Thery" <nthery@xxxxxxxxx>
Date: Tue, 3 Jun 2008 22:35:04 +0200

Hello,

While studying the spinlock implementation, I found that
spin_trylock_wr() does not decrement back
globaldata.gd_spinlock_wr if it fails to get the lock.

This looks like a bug because gd_spinlock_wr is tested in several
locations to check if a lock is held.

The following patch changes this.  I'll commit it if nobody objects.

Cheers,
Nicolas

Index: src2/sys/kern/kern_spinlock.c
===================================================================
--- src2.orig/sys/kern/kern_spinlock.c	2008-05-26 01:42:36.000000000 +0200
+++ src2/sys/kern/kern_spinlock.c	2008-06-03 22:12:33.000000000 +0200
@@ -125,7 +125,7 @@ exponential_init(struct exponential_back
  * 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;

@@ -135,12 +135,14 @@ spin_trylock_wr_contested(struct spinloc
 			bit = bsfl(value);
 			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);
 }

Index: src2/sys/sys/spinlock2.h
===================================================================
--- src2.orig/sys/sys/spinlock2.h	2008-06-03 22:20:27.000000000 +0200
+++ src2/sys/sys/spinlock2.h	2008-06-03 22:21:15.000000000 +0200
@@ -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);
 }



[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]