From 3ff3d59ed96f71523e0aa52461b01a1b1168c5e0 Mon Sep 17 00:00:00 2001 From: Eric Engestrom Date: Wed, 15 Mar 2017 23:27:25 +0000 Subject: [PATCH] atomic: fix atomic_add_unless() fallback's return value 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 Reviewed-by: Eric Engestrom [Eric: fix its callers to maintain current behaviour] Signed-off-by: Eric Engestrom --- intel/intel_bufmgr_gem.c | 38 ++++++++++++++++++++------------------ xf86atomic.h | 2 +- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c index b28ea74d..e208c68d 100644 --- a/intel/intel_bufmgr_gem.c +++ b/intel/intel_bufmgr_gem.c @@ -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) diff --git a/xf86atomic.h b/xf86atomic.h index efa47a77..c19e493b 100644 --- a/xf86atomic.h +++ b/xf86atomic.h @@ -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