drm/i915/gvt: Stop waiting whilst holding struct_mutex
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 19 Oct 2016 10:11:44 +0000 (11:11 +0100)
committerZhenyu Wang <zhenyuw@linux.intel.com>
Thu, 20 Oct 2016 09:31:34 +0000 (17:31 +0800)
For whatever reason, the gvt scheduler runs synchronously. At the very
least, lets run synchronously without holding the struct_mutex.

v2: cut'n'paste mutex_lock instead of unlock.
Replace long hold of struct_mutex with a mutex to serialise the worker
threads.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
drivers/gpu/drm/i915/gvt/scheduler.c

index 9c508c3..12f8255 100644 (file)
@@ -390,6 +390,8 @@ struct workload_thread_param {
        int ring_id;
 };
 
+static DEFINE_MUTEX(scheduler_mutex);
+
 static int workload_thread(void *priv)
 {
        struct workload_thread_param *p = (struct workload_thread_param *)priv;
@@ -414,17 +416,14 @@ static int workload_thread(void *priv)
                if (kthread_should_stop())
                        break;
 
+               mutex_lock(&scheduler_mutex);
+
                gvt_dbg_sched("ring id %d next workload %p vgpu %d\n",
                                workload->ring_id, workload,
                                workload->vgpu->id);
 
                intel_runtime_pm_get(gvt->dev_priv);
 
-               /*
-                * Always take i915 big lock first
-                */
-               mutex_lock(&gvt->dev_priv->drm.struct_mutex);
-
                gvt_dbg_sched("ring id %d will dispatch workload %p\n",
                                workload->ring_id, workload);
 
@@ -432,7 +431,10 @@ static int workload_thread(void *priv)
                        intel_uncore_forcewake_get(gvt->dev_priv,
                                        FORCEWAKE_ALL);
 
+               mutex_lock(&gvt->dev_priv->drm.struct_mutex);
                ret = dispatch_workload(workload);
+               mutex_unlock(&gvt->dev_priv->drm.struct_mutex);
+
                if (ret) {
                        gvt_err("fail to dispatch workload, skip\n");
                        goto complete;
@@ -442,8 +444,7 @@ static int workload_thread(void *priv)
                                workload->ring_id, workload);
 
                workload->status = i915_wait_request(workload->req,
-                                                    I915_WAIT_LOCKED,
-                                                    NULL, NULL);
+                                                    0, NULL, NULL);
                if (workload->status != 0)
                        gvt_err("fail to wait workload, skip\n");
 
@@ -451,7 +452,9 @@ complete:
                gvt_dbg_sched("will complete workload %p\n, status: %d\n",
                                workload, workload->status);
 
+               mutex_lock(&gvt->dev_priv->drm.struct_mutex);
                complete_current_workload(gvt, ring_id);
+               mutex_unlock(&gvt->dev_priv->drm.struct_mutex);
 
                i915_gem_request_put(fetch_and_zero(&workload->req));
 
@@ -459,9 +462,10 @@ complete:
                        intel_uncore_forcewake_put(gvt->dev_priv,
                                        FORCEWAKE_ALL);
 
-               mutex_unlock(&gvt->dev_priv->drm.struct_mutex);
-
                intel_runtime_pm_put(gvt->dev_priv);
+
+               mutex_unlock(&scheduler_mutex);
+
        }
        return 0;
 }