drm/i915/gvt: Add VM healthy check for workload_thread
authorfred gao <fred.gao@intel.com>
Tue, 19 Sep 2017 07:11:28 +0000 (15:11 +0800)
committerZhenyu Wang <zhenyuw@linux.intel.com>
Thu, 16 Nov 2017 03:46:51 +0000 (11:46 +0800)
When a scan error occurs in dispatch_workload, this patch is to
check the healthy state and free all the queued workloads before
the failsafe mode is entered.

Signed-off-by: fred gao <fred.gao@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
drivers/gpu/drm/i915/gvt/gvt.h
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/gvt/scheduler.c

index 7a770b1c99d6a66ea42bc90259f566e4e10576c4..be1bb6dbcbd27d20c175390dc92f2a7aa835a5eb 100644 (file)
@@ -193,6 +193,10 @@ struct intel_vgpu {
 #endif
 };
 
+/* validating GM healthy status*/
+#define vgpu_is_vm_unhealthy(ret_val) \
+       (((ret_val) == -EBADRQC) || ((ret_val) == -EFAULT))
+
 struct intel_gvt_gm {
        unsigned long vgpu_allocated_low_gm_size;
        unsigned long vgpu_allocated_high_gm_size;
@@ -497,6 +501,7 @@ int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci);
 void populate_pvinfo_page(struct intel_vgpu *vgpu);
 
 int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload);
+void enter_failsafe_mode(struct intel_vgpu *vgpu, int reason);
 
 struct intel_gvt_ops {
        int (*emulate_cfg_read)(struct intel_vgpu *, unsigned int, void *,
@@ -519,6 +524,7 @@ struct intel_gvt_ops {
 enum {
        GVT_FAILSAFE_UNSUPPORTED_GUEST,
        GVT_FAILSAFE_INSUFFICIENT_RESOURCE,
+       GVT_FAILSAFE_GUEST_ERR,
 };
 
 static inline void mmio_hw_access_pre(struct drm_i915_private *dev_priv)
index c78e45058219df4c5f140679e38220a9e2b91864..acc1cf4fa6f53360efe85d15c8d104aff3bf8277 100644 (file)
@@ -157,7 +157,7 @@ static int render_mmio_to_ring_id(struct intel_gvt *gvt, unsigned int reg)
        (num * 8 + i915_mmio_reg_offset(FENCE_REG_GEN6_LO(0)))
 
 
-static void enter_failsafe_mode(struct intel_vgpu *vgpu, int reason)
+void enter_failsafe_mode(struct intel_vgpu *vgpu, int reason)
 {
        switch (reason) {
        case GVT_FAILSAFE_UNSUPPORTED_GUEST:
@@ -165,6 +165,8 @@ static void enter_failsafe_mode(struct intel_vgpu *vgpu, int reason)
                break;
        case GVT_FAILSAFE_INSUFFICIENT_RESOURCE:
                pr_err("Graphics resource is not enough for the guest\n");
+       case GVT_FAILSAFE_GUEST_ERR:
+               pr_err("GVT Internal error  for the guest\n");
        default:
                break;
        }
index 0771b715f825cf1deccb9c7cb7f0f1964bee5244..02af140233836fa3f38da4dcf2ae88f8416b7a8c 100644 (file)
@@ -634,6 +634,13 @@ complete:
                                        FORCEWAKE_ALL);
 
                intel_runtime_pm_put(gvt->dev_priv);
+               if (ret && (vgpu_is_vm_unhealthy(ret))) {
+                       mutex_lock(&gvt->lock);
+                       intel_vgpu_clean_execlist(vgpu);
+                       mutex_unlock(&gvt->lock);
+                       enter_failsafe_mode(vgpu, GVT_FAILSAFE_GUEST_ERR);
+               }
+
        }
        return 0;
 }