diff options
-rw-r--r-- | include/sys/condvar.h | 1 | ||||
-rw-r--r-- | module/spl/spl-condvar.c | 20 |
2 files changed, 10 insertions, 11 deletions
diff --git a/include/sys/condvar.h b/include/sys/condvar.h index d854026ac..18e5a6fcf 100644 --- a/include/sys/condvar.h +++ b/include/sys/condvar.h @@ -44,7 +44,6 @@ typedef struct { wait_queue_head_t cv_event; atomic_t cv_waiters; kmutex_t *cv_mutex; - spinlock_t cv_lock; } kcondvar_t; typedef enum { CV_DEFAULT=0, CV_DRIVER } kcv_type_t; diff --git a/module/spl/spl-condvar.c b/module/spl/spl-condvar.c index 6b4512472..edf048bb7 100644 --- a/module/spl/spl-condvar.c +++ b/module/spl/spl-condvar.c @@ -46,7 +46,6 @@ __cv_init(kcondvar_t *cvp, char *name, kcv_type_t type, void *arg) cvp->cv_magic = CV_MAGIC; init_waitqueue_head(&cvp->cv_event); - spin_lock_init(&cvp->cv_lock); atomic_set(&cvp->cv_waiters, 0); cvp->cv_mutex = NULL; cvp->cv_name = NULL; @@ -72,15 +71,14 @@ __cv_destroy(kcondvar_t *cvp) SENTRY; ASSERT(cvp); ASSERT(cvp->cv_magic == CV_MAGIC); - spin_lock(&cvp->cv_lock); + ASSERT(cvp->cv_mutex == NULL); ASSERT(atomic_read(&cvp->cv_waiters) == 0); ASSERT(!waitqueue_active(&cvp->cv_event)); if (cvp->cv_name) kmem_free(cvp->cv_name, cvp->cv_name_size); - spin_unlock(&cvp->cv_lock); - memset(cvp, CV_POISON, sizeof(*cvp)); + ASSERT3P(memset(cvp, CV_POISON, sizeof(*cvp)), ==, cvp); SEXIT; } EXPORT_SYMBOL(__cv_destroy); @@ -94,7 +92,6 @@ cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state) ASSERT(cvp); ASSERT(mp); ASSERT(cvp->cv_magic == CV_MAGIC); - spin_lock(&cvp->cv_lock); ASSERT(mutex_owned(mp)); if (cvp->cv_mutex == NULL) @@ -102,7 +99,6 @@ cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state) /* Ensure the same mutex is used by all callers */ ASSERT(cvp->cv_mutex == mp); - spin_unlock(&cvp->cv_lock); prepare_to_wait_exclusive(&cvp->cv_event, &wait, state); atomic_inc(&cvp->cv_waiters); @@ -114,7 +110,10 @@ cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state) schedule(); mutex_enter(mp); - atomic_dec(&cvp->cv_waiters); + /* No more waiters a different mutex could be used */ + if (atomic_dec_and_test(&cvp->cv_waiters)) + cvp->cv_mutex = NULL; + finish_wait(&cvp->cv_event, &wait); SEXIT; } @@ -146,7 +145,6 @@ __cv_timedwait(kcondvar_t *cvp, kmutex_t *mp, clock_t expire_time) ASSERT(cvp); ASSERT(mp); ASSERT(cvp->cv_magic == CV_MAGIC); - spin_lock(&cvp->cv_lock); ASSERT(mutex_owned(mp)); if (cvp->cv_mutex == NULL) @@ -154,7 +152,6 @@ __cv_timedwait(kcondvar_t *cvp, kmutex_t *mp, clock_t expire_time) /* Ensure the same mutex is used by all callers */ ASSERT(cvp->cv_mutex == mp); - spin_unlock(&cvp->cv_lock); /* XXX - Does not handle jiffie wrap properly */ time_left = expire_time - jiffies; @@ -172,7 +169,10 @@ __cv_timedwait(kcondvar_t *cvp, kmutex_t *mp, clock_t expire_time) time_left = schedule_timeout(time_left); mutex_enter(mp); - atomic_dec(&cvp->cv_waiters); + /* No more waiters a different mutex could be used */ + if (atomic_dec_and_test(&cvp->cv_waiters)) + cvp->cv_mutex = NULL; + finish_wait(&cvp->cv_event, &wait); SRETURN(time_left > 0 ? time_left : -1); |