]> granicus.if.org Git - spl/commitdiff
Fix race in rwlock implementation which can occur when
authorbehlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>
Mon, 7 Apr 2008 23:54:34 +0000 (23:54 +0000)
committerbehlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>
Mon, 7 Apr 2008 23:54:34 +0000 (23:54 +0000)
your task is rescheduled to a different cpu after you've
taken the lock but before calling RW_LOCK_HELD is called.
We need the spinlock to ensure there is a wmb() there.

git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@68 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c

include/sys/rwlock.h
modules/spl/spl-rwlock.c

index 6407e632dc1a7f3d796dab2c728454b66c0dc33f..83106846c0d13cface94dcd1df4bbb6d830f6233 100644 (file)
@@ -163,6 +163,8 @@ rw_tryenter(krwlock_t *rwlp, krw_t rw)
                                rwlp->rw_owner = current;
                        }
                        break;
+               default:
+                       BUG_ON(1);
        }
 
        return result;
@@ -193,6 +195,8 @@ rw_enter(krwlock_t *rwlp, krw_t rw)
                        BUG_ON(rwlp->rw_owner != NULL);
                        rwlp->rw_owner = current;
                        break;
+               default:
+                       BUG_ON(1);
        }
 }
 
index fa78d4c14935664feba4f669c91ff00451a992dd..2ca8306f73975beb3eb881e91de78e41094b0fc4 100644 (file)
@@ -29,16 +29,21 @@ EXPORT_SYMBOL(__rw_write_held);
 int
 __rw_lock_held(krwlock_t *rwlp)
 {
+       int rc = 0;
+
        BUG_ON(rwlp->rw_magic != RW_MAGIC);
 
+       spin_lock_irq(&(rwlp->rw_sem.wait_lock));
 #ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
        if (rwlp->rw_sem.activity != 0) {
 #else
        if (rwlp->rw_sem.count != 0) {
 #endif
-               return 1;
+               rc = 1;
        }
 
-       return 0;
+       spin_unlock_irq(&(rwlp->rw_sem.wait_lock));
+
+       return rc;
 }
 EXPORT_SYMBOL(__rw_lock_held);