atomic: fix atomic_add_unless() fallback's return value
authorEric Engestrom <eric@engestrom.ch>
Wed, 15 Mar 2017 23:27:25 +0000 (23:27 +0000)
committerMatt Turner <mattst88@gmail.com>
Tue, 23 Aug 2022 22:49:34 +0000 (22:49 +0000)
According to the kernel documentation:
  Returns non-zero if @v was not @u, and zero otherwise.

Fixes: 63fc571863aa64683400 ("atomic: add atomic_add_unless()")
Closes: https://gitlab.freedesktop.org/mesa/drm/issues/17
Signed-off-by: David Shao <davshao@gmail.com>
Reviewed-by: Eric Engestrom <eric@engestrom.ch>
[Eric: fix its callers to maintain current behaviour]
Signed-off-by: Eric Engestrom <eric@engestrom.ch>
intel/intel_bufmgr_gem.c
xf86atomic.h

index b28ea74..e208c68 100644 (file)
@@ -1382,22 +1382,23 @@ static void drm_intel_gem_bo_unreference(drm_intel_bo *bo)
 
        assert(atomic_read(&bo_gem->refcount) > 0);
 
-       if (atomic_add_unless(&bo_gem->refcount, -1, 1)) {
-               drm_intel_bufmgr_gem *bufmgr_gem =
-                   (drm_intel_bufmgr_gem *) bo->bufmgr;
-               struct timespec time;
+       if (atomic_add_unless(&bo_gem->refcount, -1, 1))
+               return;
 
-               clock_gettime(CLOCK_MONOTONIC, &time);
+       drm_intel_bufmgr_gem *bufmgr_gem =
+               (drm_intel_bufmgr_gem *) bo->bufmgr;
+       struct timespec time;
 
-               pthread_mutex_lock(&bufmgr_gem->lock);
+       clock_gettime(CLOCK_MONOTONIC, &time);
 
-               if (atomic_dec_and_test(&bo_gem->refcount)) {
-                       drm_intel_gem_bo_unreference_final(bo, time.tv_sec);
-                       drm_intel_gem_cleanup_bo_cache(bufmgr_gem, time.tv_sec);
-               }
+       pthread_mutex_lock(&bufmgr_gem->lock);
 
-               pthread_mutex_unlock(&bufmgr_gem->lock);
+       if (atomic_dec_and_test(&bo_gem->refcount)) {
+               drm_intel_gem_bo_unreference_final(bo, time.tv_sec);
+               drm_intel_gem_cleanup_bo_cache(bufmgr_gem, time.tv_sec);
        }
+
+       pthread_mutex_unlock(&bufmgr_gem->lock);
 }
 
 static int drm_intel_gem_bo_map(drm_intel_bo *bo, int write_enable)
@@ -3377,16 +3378,17 @@ drm_intel_bufmgr_gem_unref(drm_intel_bufmgr *bufmgr)
 {
        drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
 
-       if (atomic_add_unless(&bufmgr_gem->refcount, -1, 1)) {
-               pthread_mutex_lock(&bufmgr_list_mutex);
+       if (atomic_add_unless(&bufmgr_gem->refcount, -1, 1))
+               return;
 
-               if (atomic_dec_and_test(&bufmgr_gem->refcount)) {
-                       DRMLISTDEL(&bufmgr_gem->managers);
-                       drm_intel_bufmgr_gem_destroy(bufmgr);
-               }
+       pthread_mutex_lock(&bufmgr_list_mutex);
 
-               pthread_mutex_unlock(&bufmgr_list_mutex);
+       if (atomic_dec_and_test(&bufmgr_gem->refcount)) {
+               DRMLISTDEL(&bufmgr_gem->managers);
+               drm_intel_bufmgr_gem_destroy(bufmgr);
        }
+
+       pthread_mutex_unlock(&bufmgr_list_mutex);
 }
 
 drm_public void *drm_intel_gem_bo_map__gtt(drm_intel_bo *bo)
index efa47a7..c19e493 100644 (file)
@@ -108,7 +108,7 @@ static inline int atomic_add_unless(atomic_t *v, int add, int unless)
        c = atomic_read(v);
        while (c != unless && (old = atomic_cmpxchg(v, c, c + add)) != c)
                c = old;
-       return c == unless;
+       return c != unless;
 }
 
 #endif