Mesa (staging/20.2): etnaviv: drm: fix BO refcount race

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Nov 2 16:09:39 UTC 2020


Module: Mesa
Branch: staging/20.2
Commit: fd3c49bb7885ff2d27ad8eaa71e0a568044fa047
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=fd3c49bb7885ff2d27ad8eaa71e0a568044fa047

Author: Lucas Stach <l.stach at pengutronix.de>
Date:   Wed Oct 28 19:47:15 2020 +0100

etnaviv: drm: fix BO refcount race

There is a race where the BO refcount might drop to 0 before the
dmabuf/name import paths had a chance to grab a reference for a
BO found in the handle_table. The easiest solution is to keep the
refcount stable as long as the table_lock is held.

While a more involved scheme of rechecking the refcount before
actually destroying the BO might also work, the bo_del path isn't
called very often, so micro-optimizing a single mutex_lock seems
to be over-engineered, so go for the easy solution.

Cc: <mesa-stable at lists.freedesktop.org>
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Reviewed-by: Christian Gmeiner <christian.gmeiner at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7367>
(cherry picked from commit 866bb22d6b91d7a12e62803bacf7d8bc912d3216)

---

 .pick_status.json            |  2 +-
 src/etnaviv/drm/etnaviv_bo.c | 10 +++++++---
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index 774670e039c..196691780ff 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -625,7 +625,7 @@
         "description": "etnaviv: drm: fix BO refcount race",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "master_sha": null,
         "because_sha": null
     },
diff --git a/src/etnaviv/drm/etnaviv_bo.c b/src/etnaviv/drm/etnaviv_bo.c
index 0ec64b780f5..7fde304ed3b 100644
--- a/src/etnaviv/drm/etnaviv_bo.c
+++ b/src/etnaviv/drm/etnaviv_bo.c
@@ -257,11 +257,15 @@ void etna_bo_del(struct etna_bo *bo)
 
 	struct etna_device *dev = bo->dev;
 
-	if (!p_atomic_dec_zero(&bo->refcnt))
-		return;
-
 	pthread_mutex_lock(&etna_drm_table_lock);
 
+	/* Must test under table lock to avoid racing with the from_dmabuf/name
+	 * paths, which rely on the BO refcount to be stable over the lookup, so
+	 * they can grab a reference when the BO is found in the hash.
+	 */
+	if (!p_atomic_dec_zero(&bo->refcnt))
+	   goto out;
+
 	if (bo->reuse && (etna_bo_cache_free(&dev->bo_cache, bo) == 0))
 		goto out;
 



More information about the mesa-commit mailing list