Mesa (master): st/nine: Resolve deadlock in surface/ volume dtors when using csmt

Axel Davy axeldavy at kemper.freedesktop.org
Sun Mar 26 21:11:03 UTC 2017


Module: Mesa
Branch: master
Commit: bd85bb51c717a1858157c73adcb689e3986b2134
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=bd85bb51c717a1858157c73adcb689e3986b2134

Author: Axel Davy <axel.davy at ens.fr>
Date:   Wed Mar 15 22:45:03 2017 +0100

st/nine: Resolve deadlock in surface/volume dtors when using csmt

Surfaces and Volumes can be freed in the worker thread.

Without this patch, pending_uploads_counter could be non-zero
in the Surfaces or Volumes dtor, leading to deadlock.
Instead decrease properly the counter before releasing the
item.

Also avoid another potential deadlock if the item is not
properly unlocked: Do not call UnlockRect which will cause deadlock,
but free directly using the deadlock safe
nine_context_get_pipe_multithread.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99246

CC: "17.0" <mesa-stable at lists.freedesktop.org>
Signed-off-by: Axel Davy <axel.davy at ens.fr>
Tested-by: James Harvey <lothmordor at gmail.com>

---

 src/gallium/state_trackers/nine/nine_csmt_helper.h |  2 +-
 src/gallium/state_trackers/nine/surface9.c         | 10 ++++++++--
 src/gallium/state_trackers/nine/volume9.c          | 10 ++++++++--
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/src/gallium/state_trackers/nine/nine_csmt_helper.h b/src/gallium/state_trackers/nine/nine_csmt_helper.h
index b0bbc054fc..dc46bbd3a2 100644
--- a/src/gallium/state_trackers/nine/nine_csmt_helper.h
+++ b/src/gallium/state_trackers/nine/nine_csmt_helper.h
@@ -233,8 +233,8 @@ name##_rx( struct NineDevice9 *device, struct csmt_instruction *instr ) \
     name##_priv( \
         device ARGS_FOR_CALL( __VA_ARGS__ ) \
     ); \
-    ARGS_FOR_UNBIND( __VA_ARGS__ ) \
     p_atomic_dec(args->counter); \
+    ARGS_FOR_UNBIND( __VA_ARGS__ ) \
     return 0; \
 } \
 \
diff --git a/src/gallium/state_trackers/nine/surface9.c b/src/gallium/state_trackers/nine/surface9.c
index 836369cafd..d917fa1f86 100644
--- a/src/gallium/state_trackers/nine/surface9.c
+++ b/src/gallium/state_trackers/nine/surface9.c
@@ -204,9 +204,15 @@ NineSurface9_dtor( struct NineSurface9 *This )
 {
     DBG("This=%p\n", This);
 
-    if (This->transfer)
-        NineSurface9_UnlockRect(This);
+    if (This->transfer) {
+        struct pipe_context *pipe = nine_context_get_pipe_multithread(This->base.base.device);
+        pipe->transfer_unmap(pipe, This->transfer);
+        This->transfer = NULL;
+    }
 
+    /* Note: Following condition cannot happen currently, since we
+     * refcount the surface in the functions increasing
+     * pending_uploads_counter. */
     if (p_atomic_read(&This->pending_uploads_counter))
         nine_csmt_process(This->base.base.device);
 
diff --git a/src/gallium/state_trackers/nine/volume9.c b/src/gallium/state_trackers/nine/volume9.c
index 11236a02e7..62af3e6225 100644
--- a/src/gallium/state_trackers/nine/volume9.c
+++ b/src/gallium/state_trackers/nine/volume9.c
@@ -142,9 +142,15 @@ NineVolume9_dtor( struct NineVolume9 *This )
 {
     DBG("This=%p\n", This);
 
-    if (This->transfer)
-        NineVolume9_UnlockBox(This);
+    if (This->transfer) {
+        struct pipe_context *pipe = nine_context_get_pipe_multithread(This->base.device);
+        pipe->transfer_unmap(pipe, This->transfer);
+        This->transfer = NULL;
+    }
 
+    /* Note: Following condition cannot happen currently, since we
+     * refcount the volume in the functions increasing
+     * pending_uploads_counter. */
     if (p_atomic_read(&This->pending_uploads_counter))
         nine_csmt_process(This->base.device);
 




More information about the mesa-commit mailing list