From: Brian Behlendorf Date: Fri, 7 Sep 2012 18:05:46 +0000 (-0700) Subject: Debug cv_destroy() with mutex held X-Git-Tag: zfs-0.8.0-rc1~152^2~346 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3c60f5054cf567ddc4a87e72d16d0a425721e422;p=zfs Debug cv_destroy() with mutex held 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 zfsonlinux/zfs#943 --- diff --git a/module/spl/spl-condvar.c b/module/spl/spl-condvar.c index 52131c1e8..e9f727d72 100644 --- a/module/spl/spl-condvar.c +++ b/module/spl/spl-condvar.c @@ -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; }