[PATCH v1 1/2] drm/i915/gvt: reorder the shadow ppgtt update process by adding entry first
Zhi Wang
zhi.a.wang at intel.com
Thu May 4 09:43:16 UTC 2017
δΊ 05/04/17 17:35, Tina Zhang ει:
> Guest i915 driver may update the ppgtt table just before this workload
> is going to be submitted to the hardware by device model. This case
> wasn't handled well by device model before, due to the small time
> window between removing old ppgtt entry and adding the new one. Errors
> occur when the workload is executed by hardware during that small time
> window. This patch is to remove this time window by adding the new ppgtt
> entry first and then remove the old one.
>
> Signed-off-by: Tina Zhang <tina.zhang at intel.com>
>
> diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
> index c6f0077..81b01ce 100644
> --- a/drivers/gpu/drm/i915/gvt/gtt.c
> +++ b/drivers/gpu/drm/i915/gvt/gtt.c
> @@ -694,7 +694,6 @@ static void ppgtt_free_all_shadow_page(struct intel_vgpu *vgpu)
> struct hlist_node *n;
> struct intel_vgpu_shadow_page *sp;
> int i;
> -
Do not remove the blank line here, or checkpatch.pl will complain...
> hash_for_each_safe(vgpu->gtt.shadow_page_hash_table, i, n, sp, node)
> ppgtt_free_shadow_page(shadow_page_to_ppgtt_spt(sp));
> }
> @@ -975,29 +974,26 @@ static int ppgtt_populate_shadow_page(struct intel_vgpu_ppgtt_spt *spt)
> }
>
> static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_guest_page *gpt,
> - unsigned long index)
> + struct intel_gvt_gtt_entry *se, unsigned long index)
> {
> struct intel_vgpu_ppgtt_spt *spt = guest_page_to_ppgtt_spt(gpt);
> struct intel_vgpu_shadow_page *sp = &spt->shadow_page;
> struct intel_vgpu *vgpu = spt->vgpu;
> struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
> - struct intel_gvt_gtt_entry e;
> int ret;
>
> - ppgtt_get_shadow_entry(spt, &e, index);
> -
> - trace_gpt_change(spt->vgpu->id, "remove", spt, sp->type, e.val64,
> + trace_gpt_change(spt->vgpu->id, "remove", spt, sp->type, se->val64,
> index);
>
> - if (!ops->test_present(&e))
> + if (!ops->test_present(se))
> return 0;
>
> - if (ops->get_pfn(&e) == vgpu->gtt.scratch_pt[sp->type].page_mfn)
> + if (ops->get_pfn(se) == vgpu->gtt.scratch_pt[sp->type].page_mfn)
> return 0;
>
> - if (gtt_type_is_pt(get_next_pt_type(e.type))) {
> + if (gtt_type_is_pt(get_next_pt_type(se->type))) {
> struct intel_vgpu_ppgtt_spt *s =
> - ppgtt_find_shadow_page(vgpu, ops->get_pfn(&e));
> + ppgtt_find_shadow_page(vgpu, ops->get_pfn(se));
> if (!s) {
> gvt_vgpu_err("fail to find guest page\n");
> ret = -ENXIO;
> @@ -1007,12 +1003,10 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_guest_page *gpt,
> if (ret)
> goto fail;
> }
> - ops->set_pfn(&e, vgpu->gtt.scratch_pt[sp->type].page_mfn);
> - ppgtt_set_shadow_entry(spt, &e, index);
> return 0;
> fail:
> gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d\n",
> - spt, e.val64, e.type);
> + spt, se->val64, se->type);
> return ret;
> }
>
> @@ -1232,22 +1226,32 @@ static int ppgtt_handle_guest_write_page_table(
> {
> struct intel_vgpu_ppgtt_spt *spt = guest_page_to_ppgtt_spt(gpt);
> struct intel_vgpu *vgpu = spt->vgpu;
> + int type = spt->shadow_page.type;
> struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
> + struct intel_gvt_gtt_entry se;
>
> int ret;
> int new_present;
>
> new_present = ops->test_present(we);
>
Better add some comments here. :P
> - ret = ppgtt_handle_guest_entry_removal(gpt, index);
> - if (ret)
> - goto fail;
> + ppgtt_get_shadow_entry(spt, &se, index);
>
> if (new_present) {
> ret = ppgtt_handle_guest_entry_add(gpt, we, index);
> if (ret)
> goto fail;
> }
> +
> + ret = ppgtt_handle_guest_entry_removal(gpt, &se, index);
> + if (ret)
> + goto fail;
> +
> + if (!new_present) {
> + ops->set_pfn(&se, vgpu->gtt.scratch_pt[type].page_mfn);
> + ppgtt_set_shadow_entry(spt, &se, index);
> + }
> +
> return 0;
> fail:
> gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d.\n",
> @@ -1319,7 +1323,7 @@ static int ppgtt_handle_guest_write_page_table_bytes(void *gp,
> struct intel_vgpu *vgpu = spt->vgpu;
> struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
> const struct intel_gvt_device_info *info = &vgpu->gvt->device_info;
> - struct intel_gvt_gtt_entry we;
> + struct intel_gvt_gtt_entry we, se;
> unsigned long index;
> int ret;
>
> @@ -1335,7 +1339,8 @@ static int ppgtt_handle_guest_write_page_table_bytes(void *gp,
> return ret;
> } else {
> if (!test_bit(index, spt->post_shadow_bitmap)) {
> - ret = ppgtt_handle_guest_entry_removal(gpt, index);
> + ppgtt_get_shadow_entry(spt, &se, index);
> + ret = ppgtt_handle_guest_entry_removal(gpt, &se, index);
> if (ret)
> return ret;
> }
More information about the intel-gvt-dev
mailing list