]> git.proxmox.com Git - mirror_spl.git/blobdiff - module/spl/spl-condvar.c
Fix cv_timedwait timeout
[mirror_spl.git] / module / spl / spl-condvar.c
index 1e2d0fc10d2ffd65ea19e9c870ce29054340bd36..80c2ef09051fd79129ae20d14bf33ae46f8852ea 100644 (file)
@@ -166,22 +166,19 @@ __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp, clock_t expire_time,
        ASSERT(mp);
        ASSERT(cvp->cv_magic == CV_MAGIC);
        ASSERT(mutex_owned(mp));
-       atomic_inc(&cvp->cv_refs);
 
+       /* XXX - Does not handle jiffie wrap properly */
+       time_left = expire_time - jiffies;
+       if (time_left <= 0)
+               return (-1);
+
+       atomic_inc(&cvp->cv_refs);
        m = ACCESS_ONCE(cvp->cv_mutex);
        if (!m)
                m = xchg(&cvp->cv_mutex, mp);
        /* Ensure the same mutex is used by all callers */
        ASSERT(m == NULL || m == mp);
 
-       /* XXX - Does not handle jiffie wrap properly */
-       time_left = expire_time - jiffies;
-       if (time_left <= 0) {
-               /* XXX - doesn't reset cv_mutex */
-               atomic_dec(&cvp->cv_refs);
-               return (-1);
-       }
-
        prepare_to_wait_exclusive(&cvp->cv_event, &wait, state);
        atomic_inc(&cvp->cv_waiters);
 
@@ -238,28 +235,25 @@ __cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t expire_time,
 {
        DEFINE_WAIT(wait);
        kmutex_t *m;
-       hrtime_t time_left, now;
+       hrtime_t time_left;
        ktime_t ktime_left;
 
        ASSERT(cvp);
        ASSERT(mp);
        ASSERT(cvp->cv_magic == CV_MAGIC);
        ASSERT(mutex_owned(mp));
-       atomic_inc(&cvp->cv_refs);
 
+       time_left = expire_time - gethrtime();
+       if (time_left <= 0)
+               return (-1);
+
+       atomic_inc(&cvp->cv_refs);
        m = ACCESS_ONCE(cvp->cv_mutex);
        if (!m)
                m = xchg(&cvp->cv_mutex, mp);
        /* Ensure the same mutex is used by all callers */
        ASSERT(m == NULL || m == mp);
 
-       now = gethrtime();
-       time_left = expire_time - now;
-       if (time_left <= 0) {
-               atomic_dec(&cvp->cv_refs);
-               return (-1);
-       }
-
        prepare_to_wait_exclusive(&cvp->cv_event, &wait, state);
        atomic_inc(&cvp->cv_waiters);
 
@@ -311,9 +305,8 @@ cv_timedwait_hires_common(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, hrtime_t
                tim = (tim / res) * res;
        }
 
-       ASSERT(!(flag & CALLOUT_FLAG_ABSOLUTE));
-       /* get abs expire time */
-       tim += gethrtime();
+       if (!(flag & CALLOUT_FLAG_ABSOLUTE))
+               tim += gethrtime();
 
        return (__cv_timedwait_hires(cvp, mp, tim, state));
 }