drm/i915/gvt: fix lock not released bug for dispatch_workload() err path
authorZhenyu Wang <zhenyuw@linux.intel.com>
Thu, 24 Nov 2016 07:55:49 +0000 (15:55 +0800)
committerZhenyu Wang <zhenyuw@linux.intel.com>
Fri, 25 Nov 2016 01:18:11 +0000 (09:18 +0800)
Need to be careful to release struct_mutext when request alloc
failed and take consistent handling for return status as with
normal go out path. Ensure to check correct workload request in
complete path too.

v2: Add Fixes note

Fixes: 90d27a1b180e ("drm/i915/gvt: fix deadlock in workload_thread")
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Pei Zhang <pei.zhang@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
drivers/gpu/drm/i915/gvt/scheduler.c

index f898df38dd9a79f8b6dbc208ed803dba76b78635..4db24225023520b879b12fce1a924cc236384bd5 100644 (file)
@@ -177,8 +177,8 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
        rq = i915_gem_request_alloc(dev_priv->engine[ring_id], shadow_ctx);
        if (IS_ERR(rq)) {
                gvt_err("fail to allocate gem request\n");
-               workload->status = PTR_ERR(rq);
-               return workload->status;
+               ret = PTR_ERR(rq);
+               goto out;
        }
 
        gvt_dbg_sched("ring id %d get i915 gem request %p\n", ring_id, rq);
@@ -212,7 +212,8 @@ out:
        if (ret)
                workload->status = ret;
 
-       i915_add_request_no_flush(rq);
+       if (!IS_ERR_OR_NULL(rq))
+               i915_add_request_no_flush(rq);
        mutex_unlock(&dev_priv->drm.struct_mutex);
        return ret;
 }
@@ -460,7 +461,8 @@ complete:
 
                complete_current_workload(gvt, ring_id);
 
-               i915_gem_request_put(fetch_and_zero(&workload->req));
+               if (workload->req)
+                       i915_gem_request_put(fetch_and_zero(&workload->req));
 
                if (need_force_wake)
                        intel_uncore_forcewake_put(gvt->dev_priv,