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


  59 
  60 void
  61 zrl_destroy(zrlock_t *zrl)
  62 {
  63         ASSERT(zrl->zr_refcount == 0);
  64 
  65         mutex_destroy(&zrl->zr_mtx);
  66         zrl->zr_refcount = ZRL_DESTROYED;
  67         cv_destroy(&zrl->zr_cv);
  68 }
  69 
  70 void
  71 #ifdef  ZFS_DEBUG
  72 zrl_add_debug(zrlock_t *zrl, const char *zc)
  73 #else
  74 zrl_add(zrlock_t *zrl)
  75 #endif
  76 {
  77         uint32_t n = (uint32_t)zrl->zr_refcount;
  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;
  91 #endif
  92                         return;
  93                 }
  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);
 100         }
 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 }
 109 
 110 void
 111 zrl_remove(zrlock_t *zrl)
 112 {
 113         uint32_t n;
 114 
 115         n = atomic_dec_32_nv((uint32_t *)&zrl->zr_refcount);
 116         ASSERT((int32_t)n >= 0);
 117 #ifdef  ZFS_DEBUG
 118         if (zrl->zr_owner == curthread) {
 119                 zrl->zr_owner = NULL;
 120                 zrl->zr_caller = NULL;
 121         }
 122 #endif
 123 }
 124 
 125 int
 126 zrl_tryenter(zrlock_t *zrl)
 127 {




  59 
  60 void
  61 zrl_destroy(zrlock_t *zrl)
  62 {
  63         ASSERT(zrl->zr_refcount == 0);
  64 
  65         mutex_destroy(&zrl->zr_mtx);
  66         zrl->zr_refcount = ZRL_DESTROYED;
  67         cv_destroy(&zrl->zr_cv);
  68 }
  69 
  70 void
  71 #ifdef  ZFS_DEBUG
  72 zrl_add_debug(zrlock_t *zrl, const char *zc)
  73 #else
  74 zrl_add(zrlock_t *zrl)
  75 #endif
  76 {
  77         uint32_t n = (uint32_t)zrl->zr_refcount;
  78 
  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;
  92 #endif
  93                                 return;
  94                         }
  95                         n = cas;
  96                 }

  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);
 102         }
 103 }
 104 
 105 void
 106 zrl_remove(zrlock_t *zrl)
 107 {
 108         uint32_t n;
 109 
 110         n = atomic_dec_32_nv((uint32_t *)&zrl->zr_refcount);
 111         ASSERT((int32_t)n >= 0);
 112 #ifdef  ZFS_DEBUG
 113         if (zrl->zr_owner == curthread) {
 114                 zrl->zr_owner = NULL;
 115                 zrl->zr_caller = NULL;
 116         }
 117 #endif
 118 }
 119 
 120 int
 121 zrl_tryenter(zrlock_t *zrl)
 122 {