| From ab4062bff4c65d86d1e1ee66480a41170f17277f Mon Sep 17 00:00:00 2001 |
| From: Xiaolin Zhang <xiaolin.zhang@intel.com> |
| Date: Tue, 27 Aug 2019 16:39:23 +0800 |
| Subject: [PATCH] drm/i915/gvt: update vgpu workload head pointer correctly |
| |
| commit 0a3242bdb47713e09cb004a0ba4947d3edf82d8a upstream. |
| |
| when creating a vGPU workload, the guest context head pointer should |
| be updated correctly by comparing with the exsiting workload in the |
| guest worklod queue including the current running context. |
| |
| in some situation, there is a running context A and then received 2 new |
| vGPU workload context B and A. in the new workload context A, it's head |
| pointer should be updated with the running context A's tail. |
| |
| v2: walk through guest workload list in backward way. |
| |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Xiaolin Zhang <xiaolin.zhang@intel.com> |
| Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com> |
| Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c |
| index 0f919f0a43d4..754c1debd7b0 100644 |
| --- a/drivers/gpu/drm/i915/gvt/scheduler.c |
| +++ b/drivers/gpu/drm/i915/gvt/scheduler.c |
| @@ -1409,9 +1409,6 @@ static int prepare_mm(struct intel_vgpu_workload *workload) |
| #define same_context(a, b) (((a)->context_id == (b)->context_id) && \ |
| ((a)->lrca == (b)->lrca)) |
| |
| -#define get_last_workload(q) \ |
| - (list_empty(q) ? NULL : container_of(q->prev, \ |
| - struct intel_vgpu_workload, list)) |
| /** |
| * intel_vgpu_create_workload - create a vGPU workload |
| * @vgpu: a vGPU |
| @@ -1431,7 +1428,7 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, |
| { |
| struct intel_vgpu_submission *s = &vgpu->submission; |
| struct list_head *q = workload_q_head(vgpu, ring_id); |
| - struct intel_vgpu_workload *last_workload = get_last_workload(q); |
| + struct intel_vgpu_workload *last_workload = NULL; |
| struct intel_vgpu_workload *workload = NULL; |
| struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; |
| u64 ring_context_gpa; |
| @@ -1457,15 +1454,20 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, |
| head &= RB_HEAD_OFF_MASK; |
| tail &= RB_TAIL_OFF_MASK; |
| |
| - if (last_workload && same_context(&last_workload->ctx_desc, desc)) { |
| - gvt_dbg_el("ring id %d cur workload == last\n", ring_id); |
| - gvt_dbg_el("ctx head %x real head %lx\n", head, |
| - last_workload->rb_tail); |
| - /* |
| - * cannot use guest context head pointer here, |
| - * as it might not be updated at this time |
| - */ |
| - head = last_workload->rb_tail; |
| + list_for_each_entry_reverse(last_workload, q, list) { |
| + |
| + if (same_context(&last_workload->ctx_desc, desc)) { |
| + gvt_dbg_el("ring id %d cur workload == last\n", |
| + ring_id); |
| + gvt_dbg_el("ctx head %x real head %lx\n", head, |
| + last_workload->rb_tail); |
| + /* |
| + * cannot use guest context head pointer here, |
| + * as it might not be updated at this time |
| + */ |
| + head = last_workload->rb_tail; |
| + break; |
| + } |
| } |
| |
| gvt_dbg_el("ring id %d begin a new workload\n", ring_id); |
| -- |
| 2.7.4 |
| |