From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Fei Jiang Date: Fri, 14 Sep 2018 16:10:20 +0800 Subject: [PATCH] drm/i915/gvt: cached read_gpa optimization in shadow ppgtt update During shadow ppgtt update, we need call intel_gvt_hypervisor_read_gpa every entry for whole ppgtt page, for performance consideration, optmize it by firstly reading whole page ppgtt gpa content into one scratch page, then following read_gpa directly read from scratch page. Have vgpu->ge_cache_enable to control, currently we only cache in ppgtt_populate_shadow_page for pte update case. Signed-off-by: Fei Jiang Reviewed-by: Min He Reviewed-by: Zhao Yakui --- drivers/gpu/drm/i915/gvt/gtt.c | 23 +++++++++++++++++++++++ drivers/gpu/drm/i915/gvt/gvt.h | 3 +++ 2 files changed, 26 insertions(+) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 30688295c458..963cd9fab3ce 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -303,6 +303,18 @@ static inline int gtt_get_entry64(void *pt, return -EINVAL; if (hypervisor_access) { + if (vgpu->ge_cache_enable && vgpu->cached_guest_entry) { + if (index == 0) { + ret = intel_gvt_hypervisor_read_gpa(vgpu, gpa, + vgpu->cached_guest_entry, + I915_GTT_PAGE_SIZE); + if (WARN_ON(ret)) + return ret; + } + e->val64 = *(vgpu->cached_guest_entry + index); + return 0; + } + ret = intel_gvt_hypervisor_read_gpa(vgpu, gpa + (index << info->gtt_entry_size_shift), &e->val64, 8); @@ -1277,8 +1289,10 @@ static int ppgtt_populate_spt(struct intel_vgpu_ppgtt_spt *spt) trace_spt_change(spt->vgpu->id, "born", spt, spt->guest_page.gfn, spt->shadow_page.type); + vgpu->ge_cache_enable = true; for_each_present_guest_entry(spt, &ge, i) { if (gtt_type_is_pt(get_next_pt_type(ge.type))) { + vgpu->ge_cache_enable = false; s = ppgtt_populate_spt_by_guest_entry(vgpu, &ge); if (IS_ERR(s)) { ret = PTR_ERR(s); @@ -1300,6 +1314,7 @@ static int ppgtt_populate_spt(struct intel_vgpu_ppgtt_spt *spt) goto fail; } } + vgpu->ge_cache_enable = false; return 0; fail: gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d\n", @@ -2430,6 +2445,13 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu) intel_vgpu_reset_ggtt(vgpu, false); + vgpu->cached_guest_entry = kzalloc(I915_GTT_PAGE_SIZE, GFP_KERNEL); + if (!vgpu->cached_guest_entry) { + gvt_vgpu_err("fail to allocate cached_guest_entry page\n"); + return -ENOMEM; + } + vgpu->ge_cache_enable = false; + return create_scratch_page_tree(vgpu); } @@ -2472,6 +2494,7 @@ void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu) { intel_vgpu_destroy_all_ppgtt_mm(vgpu); intel_vgpu_destroy_ggtt_mm(vgpu); + kfree(vgpu->cached_guest_entry); release_scratch_page_tree(vgpu); } diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index ba88f722d602..1a287ba76923 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -235,6 +235,9 @@ struct intel_vgpu { struct completion vblank_done; u32 scan_nonprivbb; + + unsigned long long *cached_guest_entry; + bool ge_cache_enable; }; /* validating GM healthy status*/ -- https://clearlinux.org