Print this page
3746 ZRLs are racy
Submitted by:   Justin Gibbs <justing@spectralogic.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/zrlock.c
          +++ new/usr/src/uts/common/fs/zfs/zrlock.c
↓ open down ↓ 68 lines elided ↑ open up ↑
  69   69  
  70   70  void
  71   71  #ifdef  ZFS_DEBUG
  72   72  zrl_add_debug(zrlock_t *zrl, const char *zc)
  73   73  #else
  74   74  zrl_add(zrlock_t *zrl)
  75   75  #endif
  76   76  {
  77   77          uint32_t n = (uint32_t)zrl->zr_refcount;
  78   78  
  79      -        while (n != ZRL_LOCKED) {
  80      -                uint32_t cas = atomic_cas_32(
  81      -                    (uint32_t *)&zrl->zr_refcount, n, n + 1);
  82      -                if (cas == n) {
  83      -                        ASSERT((int32_t)n >= 0);
  84      -#ifdef  ZFS_DEBUG
  85      -                        if (zrl->zr_owner == curthread) {
  86      -                                DTRACE_PROBE2(zrlock__reentry,
  87      -                                    zrlock_t *, zrl, uint32_t, n);
  88      -                        }
  89      -                        zrl->zr_owner = curthread;
  90      -                        zrl->zr_caller = zc;
       79 +        while (1) {
       80 +                while (n != ZRL_LOCKED) {
       81 +                        uint32_t cas = atomic_cas_32(
       82 +                            (uint32_t *)&zrl->zr_refcount, n, n + 1);
       83 +                        if (cas == n) {
       84 +                                ASSERT((int32_t)n >= 0);
       85 +#ifdef  ZFS_DEBUG
       86 +                                if (zrl->zr_owner == curthread) {
       87 +                                        DTRACE_PROBE2(zrlock__reentry,
       88 +                                            zrlock_t *, zrl, uint32_t, n);
       89 +                                }
       90 +                                zrl->zr_owner = curthread;
       91 +                                zrl->zr_caller = zc;
  91   92  #endif
  92      -                        return;
       93 +                                return;
       94 +                        }
       95 +                        n = cas;
  93   96                  }
  94      -                n = cas;
  95      -        }
  96      -
  97      -        mutex_enter(&zrl->zr_mtx);
  98      -        while (zrl->zr_refcount == ZRL_LOCKED) {
  99      -                cv_wait(&zrl->zr_cv, &zrl->zr_mtx);
       97 +                mutex_enter(&zrl->zr_mtx);
       98 +                while (zrl->zr_refcount == ZRL_LOCKED) {
       99 +                        cv_wait(&zrl->zr_cv, &zrl->zr_mtx);
      100 +                }
      101 +                mutex_exit(&zrl->zr_mtx);
 100  102          }
 101      -        ASSERT(zrl->zr_refcount >= 0);
 102      -        zrl->zr_refcount++;
 103      -#ifdef  ZFS_DEBUG
 104      -        zrl->zr_owner = curthread;
 105      -        zrl->zr_caller = zc;
 106      -#endif
 107      -        mutex_exit(&zrl->zr_mtx);
 108  103  }
 109  104  
 110  105  void
 111  106  zrl_remove(zrlock_t *zrl)
 112  107  {
 113  108          uint32_t n;
 114  109  
 115  110          n = atomic_dec_32_nv((uint32_t *)&zrl->zr_refcount);
 116  111          ASSERT((int32_t)n >= 0);
 117  112  #ifdef  ZFS_DEBUG
↓ open down ↓ 77 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX