drm/i915/gvt: Audit and shadow workload during ELSP writing
authorPing Gao <ping.a.gao@intel.com>
Thu, 29 Jun 2017 04:22:43 +0000 (12:22 +0800)
committerZhenyu Wang <zhenyuw@linux.intel.com>
Thu, 10 Aug 2017 02:26:07 +0000 (10:26 +0800)
Let the workload audit and shadow ahead of vGPU scheduling, that
will eliminate GPU idle time and improve performance for multi-VM.

The performance of Heaven running simultaneously in 3VMs has
improved 20% after this patch.

v2:Remove condition current->vgpu==vgpu when shadow during ELSP
writing.

Signed-off-by: Ping Gao <ping.a.gao@intel.com>
Reviewed-by: Zhi Wang <zhi.a.wang@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
drivers/gpu/drm/i915/gvt/execlist.c
drivers/gpu/drm/i915/gvt/scheduler.c
drivers/gpu/drm/i915/gvt/scheduler.h

index 700050556242480e6fbf8eb4a8d97c6307e9390d..28a2c7e8bee1412466a2bf5cf01c33c7a711dc96 100644 (file)
@@ -605,6 +605,7 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
        struct list_head *q = workload_q_head(vgpu, ring_id);
        struct intel_vgpu_workload *last_workload = get_last_workload(q);
        struct intel_vgpu_workload *workload = NULL;
+       struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
        u64 ring_context_gpa;
        u32 head, tail, start, ctl, ctx_ctl, per_ctx, indirect_ctx;
        int ret;
@@ -668,6 +669,7 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
        workload->complete = complete_execlist_workload;
        workload->status = -EINPROGRESS;
        workload->emulate_schedule_in = emulate_schedule_in;
+       workload->shadowed = false;
 
        if (ring_id == RCS) {
                intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
@@ -701,6 +703,15 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
                return ret;
        }
 
+       /* Only scan and shadow the first workload in the queue
+        * as there is only one pre-allocated buf-obj for shadow.
+        */
+       if (list_empty(workload_q_head(vgpu, ring_id))) {
+               mutex_lock(&dev_priv->drm.struct_mutex);
+               intel_gvt_scan_and_shadow_workload(workload);
+               mutex_unlock(&dev_priv->drm.struct_mutex);
+       }
+
        queue_workload(workload);
        return 0;
 }
index 7929c0285d1d42d9b6dd3744edef451048be28a6..bd59c6d093191ba9140a510342dedf9da47be8d9 100644 (file)
@@ -201,6 +201,9 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
        struct intel_vgpu *vgpu = workload->vgpu;
        int ret;
 
+       if (workload->shadowed)
+               return 0;
+
        shadow_ctx->desc_template &= ~(0x3 << GEN8_CTX_ADDRESSING_MODE_SHIFT);
        shadow_ctx->desc_template |= workload->ctx_desc.addressing_mode <<
                                    GEN8_CTX_ADDRESSING_MODE_SHIFT;
@@ -228,6 +231,10 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
        }
 
        ret = populate_shadow_context(workload);
+       if (ret)
+               goto out;
+
+       workload->shadowed = true;
 
 out:
        return ret;
index 9b6bf51e9b9b0b1f20ec609e50131261c1f4dec0..0d431a968a32970f07cda55bb37f55a0634afc98 100644 (file)
@@ -82,6 +82,7 @@ struct intel_vgpu_workload {
        struct drm_i915_gem_request *req;
        /* if this workload has been dispatched to i915? */
        bool dispatched;
+       bool shadowed;
        int status;
 
        struct intel_vgpu_mm *shadow_mm;