From 6ac133c646dd4f6f9d8f644b24da6aeae95c1ce3 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 1 Nov 2023 09:42:21 -0700 Subject: [PATCH] freedreno/drm: Fix race in zombie import The check for the zombie case (racing with final unref of the bo vs removal from table) must be atomic. Fixes spec@ext_image_dma_buf_import@ext_image_dma_buf_import-refcount-multithread Fixes: a192923f99e1 ("freedreno/drm: Restart import on zombie race") Signed-off-by: Rob Clark Part-of: --- src/freedreno/drm/freedreno_bo.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/freedreno/drm/freedreno_bo.c b/src/freedreno/drm/freedreno_bo.c index 3f15f52e799..3c8ed16a59f 100644 --- a/src/freedreno/drm/freedreno_bo.c +++ b/src/freedreno/drm/freedreno_bo.c @@ -61,15 +61,12 @@ lookup_bo(struct hash_table *tbl, uint32_t key) * remove an object it is about to free. Fortunately since table * lookup and removal are protected by the same lock (and table * removal happens before obj free) we can easily detect this by - * checking for refcnt==0. + * checking for refcnt==0 (ie. 1 after p_atomic_inc_return). */ - if (bo->refcnt == 0) { + if (p_atomic_inc_return(&bo->refcnt) == 1) { return &zombie; } - /* found, incr refcnt and return: */ - fd_bo_ref(bo); - if (!list_is_empty(&bo->node)) { mesa_logw("bo was in cache, size=%u, alloc_flags=0x%x\n", bo->size, bo->alloc_flags);