From 7294206e88d06563588bed1e11664a6edaaf0dc9 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Thu, 23 Apr 2026 11:14:44 +0200 Subject: [PATCH] zink: Guard bo map/unmap on map_count. Otherwise zink_bo_map can return cpu_ptr being destroyed by zink_bo_unmap. Cc: mesa-stable (cherry picked from commit ce45069c49cdc0eb5c1bb14a548740de23cd1908) Part-of: --- .pick_status.json | 2 +- src/gallium/drivers/zink/zink_bo.c | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 2809b5641e1..58ceb6463ee 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1774,7 +1774,7 @@ "description": "zink: Guard bo map/unmap on map_count.", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/gallium/drivers/zink/zink_bo.c b/src/gallium/drivers/zink/zink_bo.c index 96ce57534c1..c9e35e8287e 100644 --- a/src/gallium/drivers/zink/zink_bo.c +++ b/src/gallium/drivers/zink/zink_bo.c @@ -707,8 +707,8 @@ zink_bo_map(struct zink_screen *screen, struct zink_bo *bo) offset = bo->offset - real->offset; } - p_atomic_inc(&real->u.real.map_count); - cpu = p_atomic_read(&real->u.real.cpu_ptr); + if (p_atomic_inc_return(&real->u.real.map_count) > 1) + cpu = p_atomic_read(&real->u.real.cpu_ptr); if (!cpu) { simple_mtx_lock(&real->lock); /* Must re-check due to the possibility of a race. Re-check need not @@ -743,12 +743,15 @@ zink_bo_unmap(struct zink_screen *screen, struct zink_bo *bo) if (p_atomic_dec_zero(&real->u.real.map_count)) { simple_mtx_lock(&real->lock); - p_atomic_set(&real->u.real.cpu_ptr, NULL); - if (unlikely(zink_debug & ZINK_DEBUG_MAP)) { - p_atomic_add(&screen->mapped_vram, -real->base.base.size); - mesa_loge("UNMAP(%"PRIu64") TOTAL(%"PRIu64")", real->base.base.size, screen->mapped_vram); + /* Re-check in case of race with zink_bo_map */ + if (!p_atomic_read(&real->u.real.map_count)) { + p_atomic_set(&real->u.real.cpu_ptr, NULL); + if (unlikely(zink_debug & ZINK_DEBUG_MAP)) { + p_atomic_add(&screen->mapped_vram, -real->base.base.size); + mesa_loge("UNMAP(%"PRIu64") TOTAL(%"PRIu64")", real->base.base.size, screen->mapped_vram); + } + VKSCR(UnmapMemory)(screen->dev, real->mem); } - VKSCR(UnmapMemory)(screen->dev, real->mem); simple_mtx_unlock(&real->lock); } }