From 99db9bfde70440475a37c0e1b985efbec4850a8c Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 15 Oct 2012 13:36:26 -0700 Subject: [PATCH 1/3] Condition variable usage, zevent_cv The following incorrect usage of cv_broadcast() was caught by code inspection. The cv_broadcast() function must be called under the associated mutex to preventing racing with cv_wait(). Signed-off-by: Brian Behlendorf --- module/zfs/fm.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/module/zfs/fm.c b/module/zfs/fm.c index ce0ebe0c1..c004032f8 100644 --- a/module/zfs/fm.c +++ b/module/zfs/fm.c @@ -481,14 +481,13 @@ zfs_zevent_drain_all(int *count) static void zfs_zevent_insert(zevent_t *ev) { - mutex_enter(&zevent_lock); + ASSERT(MUTEX_HELD(&zevent_lock)); list_insert_head(&zevent_list, ev); + if (zevent_len_cur >= zfs_zevent_len_max) zfs_zevent_drain(list_tail(&zevent_list)); else zevent_len_cur++; - - mutex_exit(&zevent_lock); } /* @@ -528,8 +527,11 @@ zfs_zevent_post(nvlist_t *nvl, nvlist_t *detector, zevent_cb_t *cb) ev->ev_nvl = nvl; ev->ev_detector = detector; ev->ev_cb = cb; + + mutex_enter(&zevent_lock); zfs_zevent_insert(ev); cv_broadcast(&zevent_cv); + mutex_exit(&zevent_lock); } static int @@ -1520,9 +1522,10 @@ fm_fini(void) int count; zfs_zevent_drain_all(&count); - cv_broadcast(&zevent_cv); mutex_enter(&zevent_lock); + cv_broadcast(&zevent_cv); + zevent_flags |= ZEVENT_SHUTDOWN; while (zevent_waiters > 0) { mutex_exit(&zevent_lock); From 8c0712fd88d3cf60dc9db5392b005583d540dc69 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 15 Oct 2012 13:40:07 -0700 Subject: [PATCH 2/3] Condition variable usage, zilog->zl_cv_batch The following incorrect usage of cv_signal and cv_broadcast() was caught by code inspection. The cv_signal and cv_broadcast() functions must be called under the associated mutex to preventing racing with cv_wait(). Signed-off-by: Brian Behlendorf --- module/zfs/zil.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/zfs/zil.c b/module/zfs/zil.c index 292aea27d..e76e5ecf1 100644 --- a/module/zfs/zil.c +++ b/module/zfs/zil.c @@ -1560,13 +1560,14 @@ zil_commit(zilog_t *zilog, uint64_t foid) zil_commit_writer(zilog); zilog->zl_com_batch = mybatch; zilog->zl_writer = B_FALSE; - mutex_exit(&zilog->zl_lock); /* wake up one thread to become the next writer */ cv_signal(&zilog->zl_cv_batch[(mybatch+1) & 1]); /* wake up all threads waiting for this batch to be committed */ cv_broadcast(&zilog->zl_cv_batch[mybatch & 1]); + + mutex_exit(&zilog->zl_lock); } /* From a298dbde92c68022a06ef51f2bb559b0975e4920 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 15 Oct 2012 13:41:44 -0700 Subject: [PATCH 3/3] Condition variable usage, zp->r_{rd,wr}_cv The following incorrect usage of cv_broadcast() was caught by code inspection. The cv_broadcast() function must be called under the associated mutex to preventing racing with cv_wait(). Signed-off-by: Brian Behlendorf --- module/zfs/zfs_rlock.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/module/zfs/zfs_rlock.c b/module/zfs/zfs_rlock.c index 208de10f3..c278035b1 100644 --- a/module/zfs/zfs_rlock.c +++ b/module/zfs/zfs_rlock.c @@ -486,7 +486,7 @@ zfs_range_unlock_reader(znode_t *zp, rl_t *remove, list_t *free_list) */ if (remove->r_cnt == 1) { avl_remove(tree, remove); - mutex_exit(&zp->z_range_lock); + if (remove->r_write_wanted) cv_broadcast(&remove->r_wr_cv); @@ -530,7 +530,6 @@ zfs_range_unlock_reader(znode_t *zp, rl_t *remove, list_t *free_list) } } - mutex_exit(&zp->z_range_lock); kmem_free(remove, sizeof (rl_t)); } } @@ -554,7 +553,6 @@ zfs_range_unlock(rl_t *rl) if (rl->r_type == RL_WRITER) { /* writer locks can't be shared or split */ avl_remove(&zp->z_range_avl, rl); - mutex_exit(&zp->z_range_lock); if (rl->r_write_wanted) cv_broadcast(&rl->r_wr_cv); @@ -569,6 +567,7 @@ zfs_range_unlock(rl_t *rl) */ zfs_range_unlock_reader(zp, rl, &free_list); } + mutex_exit(&zp->z_range_lock); while ((free_rl = list_head(&free_list)) != NULL) { list_remove(&free_list, free_rl); @@ -599,11 +598,13 @@ zfs_range_reduce(rl_t *rl, uint64_t off, uint64_t len) mutex_enter(&zp->z_range_lock); rl->r_off = off; rl->r_len = len; - mutex_exit(&zp->z_range_lock); + if (rl->r_write_wanted) cv_broadcast(&rl->r_wr_cv); if (rl->r_read_wanted) cv_broadcast(&rl->r_rd_cv); + + mutex_exit(&zp->z_range_lock); } /*