summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAxel Davy <[email protected]>2017-03-15 22:45:03 +0100
committerAxel Davy <[email protected]>2017-03-26 23:10:38 +0200
commitbd85bb51c717a1858157c73adcb689e3986b2134 (patch)
tree7a9954aaaa694edf5cd64c25e865200a3f37f377
parent31f8b3babb5a2d685d6e8b8ed0a2120c7966e9b1 (diff)
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" <[email protected]> Signed-off-by: Axel Davy <[email protected]> Tested-by: James Harvey <[email protected]>
-rw-r--r--src/gallium/state_trackers/nine/nine_csmt_helper.h2
-rw-r--r--src/gallium/state_trackers/nine/surface9.c10
-rw-r--r--src/gallium/state_trackers/nine/volume9.c10
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 b0bbc054fc3..dc46bbd3a28 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 836369cafdb..d917fa1f868 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 11236a02e75..62af3e62251 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);