aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.4/0097-drm-vc4-Drop-struct_mutex-around-CL-validation.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-4.4/0097-drm-vc4-Drop-struct_mutex-around-CL-validation.patch')
-rw-r--r--target/linux/brcm2708/patches-4.4/0097-drm-vc4-Drop-struct_mutex-around-CL-validation.patch74
1 files changed, 74 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.4/0097-drm-vc4-Drop-struct_mutex-around-CL-validation.patch b/target/linux/brcm2708/patches-4.4/0097-drm-vc4-Drop-struct_mutex-around-CL-validation.patch
new file mode 100644
index 0000000000..5275fb5e17
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.4/0097-drm-vc4-Drop-struct_mutex-around-CL-validation.patch
@@ -0,0 +1,74 @@
+From 4cc42228e828c8cba5e2f712fd92fe3e0bb8b09d Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 19 Oct 2015 08:44:35 -0700
+Subject: [PATCH 097/127] drm/vc4: Drop struct_mutex around CL validation.
+
+We were using it so that we could make sure that shader validation
+state didn't change while we were validating, but now shader
+validation state is immutable. The bcl/rcl generation doesn't do any
+other BO dereferencing, and seems to have no other global state
+dependency not covered by job_lock / bo_lock. We only need to hold
+struct_mutex for object unreferencing.
+
+Fixes a lock order reversal between mmap_sem and struct_mutex.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ drivers/gpu/drm/vc4/vc4_gem.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_gem.c
++++ b/drivers/gpu/drm/vc4/vc4_gem.c
+@@ -439,10 +439,12 @@ fail:
+ }
+
+ static void
+-vc4_complete_exec(struct vc4_exec_info *exec)
++vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
+ {
+ unsigned i;
+
++ /* Need the struct lock for drm_gem_object_unreference(). */
++ mutex_lock(&dev->struct_mutex);
+ if (exec->bo) {
+ for (i = 0; i < exec->bo_count; i++)
+ drm_gem_object_unreference(&exec->bo[i].bo->base);
+@@ -455,6 +457,7 @@ vc4_complete_exec(struct vc4_exec_info *
+ list_del(&bo->unref_head);
+ drm_gem_object_unreference(&bo->base.base);
+ }
++ mutex_unlock(&dev->struct_mutex);
+
+ kfree(exec);
+ }
+@@ -473,7 +476,7 @@ vc4_job_handle_completed(struct vc4_dev
+ list_del(&exec->head);
+
+ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+- vc4_complete_exec(exec);
++ vc4_complete_exec(vc4->dev, exec);
+ spin_lock_irqsave(&vc4->job_lock, irqflags);
+ }
+
+@@ -525,12 +528,8 @@ vc4_job_done_work(struct work_struct *wo
+ {
+ struct vc4_dev *vc4 =
+ container_of(work, struct vc4_dev, job_done_work);
+- struct drm_device *dev = vc4->dev;
+
+- /* Need the struct lock for drm_gem_object_unreference(). */
+- mutex_lock(&dev->struct_mutex);
+ vc4_job_handle_completed(vc4);
+- mutex_unlock(&dev->struct_mutex);
+ }
+
+ static int
+@@ -639,7 +638,7 @@ vc4_submit_cl_ioctl(struct drm_device *d
+ return 0;
+
+ fail:
+- vc4_complete_exec(exec);
++ vc4_complete_exec(vc4->dev, exec);
+
+ return ret;
+ }