]> granicus.if.org Git - spl/commitdiff
Debug cv_destroy() with mutex held
authorBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 7 Sep 2012 18:05:46 +0000 (11:05 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 10 Sep 2012 17:23:26 +0000 (10:23 -0700)
There still appears to be a race in the condition variables where
->cv_mutex is set after we are woken from the cv_destroy wait queue.
This might be possible when cv_destroy() is called immediately after
cv_broadcast().  We had some troubles with this previously but
there may still be a small race, see commit d599e4f.

The following patch closes one small race and improves the ASSERTs
such that they log the offending value.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
zfsonlinux/zfs#943

module/spl/spl-condvar.c

index 52131c1e8788dfe08cd0ea715e8e8e5aa8ef752a..e9f727d72dbbc13b797df3c53cb7054e4b889489 100644 (file)
@@ -63,7 +63,8 @@ EXPORT_SYMBOL(__cv_init);
 static int
 cv_destroy_wakeup(kcondvar_t *cvp)
 {
-       if ((waitqueue_active(&cvp->cv_event)) ||
+       if ((cvp->cv_mutex != NULL) ||
+           (waitqueue_active(&cvp->cv_event)) ||
            (atomic_read(&cvp->cv_waiters) > 0))
                return 0;
 
@@ -81,9 +82,9 @@ __cv_destroy(kcondvar_t *cvp)
        while (cv_destroy_wakeup(cvp) == 0)
                wait_event_timeout(cvp->cv_destroy, cv_destroy_wakeup(cvp), 1);
 
-       ASSERT(cvp->cv_mutex == NULL);
-       ASSERT(atomic_read(&cvp->cv_waiters) == 0);
-       ASSERT(!waitqueue_active(&cvp->cv_event));
+       ASSERT3P(cvp->cv_mutex, ==, NULL);
+       ASSERT3S(atomic_read(&cvp->cv_waiters), ==, 0);
+       ASSERT3S(waitqueue_active(&cvp->cv_event), ==, 0);
 
        SEXIT;
 }