drm/i915/gvt: clear the vGPU reset logic
authorPing Gao <ping.a.gao@intel.com>
Tue, 21 Feb 2017 07:52:56 +0000 (15:52 +0800)
committerZhenyu Wang <zhenyuw@linux.intel.com>
Thu, 23 Feb 2017 09:32:17 +0000 (17:32 +0800)
Releasing shadow PPGTT pages is not enough when vGPU reset, the
guest page table tracking data should has same life-cycle with
all the shadow PPGTT pages; Otherwise there is no chance to
re-shadow the PPGTT pages without free the guest page table
tracking data.

This patch clear the PPGTT reset logic and make the vGPU reset in
working order.

v2: refactor some logic to avoid code duplicated.
v3: remove useless macro and add comments from Christophe.
v4: keep reset logic in reset function.

Signed-off-by: Ping Gao <ping.a.gao@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
drivers/gpu/drm/i915/gvt/gtt.c

index 28c92346db0e4e3615c2b5c484b4421eeb097e6e..b5c833287d39f60b0513d855c5e2b5149a5cc9dd 100644 (file)
@@ -2015,6 +2015,22 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
        return create_scratch_page_tree(vgpu);
 }
 
+static void intel_vgpu_free_mm(struct intel_vgpu *vgpu, int type)
+{
+       struct list_head *pos, *n;
+       struct intel_vgpu_mm *mm;
+
+       list_for_each_safe(pos, n, &vgpu->gtt.mm_list_head) {
+               mm = container_of(pos, struct intel_vgpu_mm, list);
+               if (mm->type == type) {
+                       vgpu->gvt->gtt.mm_free_page_table(mm);
+                       list_del(&mm->list);
+                       list_del(&mm->lru_list);
+                       kfree(mm);
+               }
+       }
+}
+
 /**
  * intel_vgpu_clean_gtt - clean up per-vGPU graphics memory virulization
  * @vgpu: a vGPU
@@ -2027,19 +2043,11 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
  */
 void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu)
 {
-       struct list_head *pos, *n;
-       struct intel_vgpu_mm *mm;
-
        ppgtt_free_all_shadow_page(vgpu);
        release_scratch_page_tree(vgpu);
 
-       list_for_each_safe(pos, n, &vgpu->gtt.mm_list_head) {
-               mm = container_of(pos, struct intel_vgpu_mm, list);
-               vgpu->gvt->gtt.mm_free_page_table(mm);
-               list_del(&mm->list);
-               list_del(&mm->lru_list);
-               kfree(mm);
-       }
+       intel_vgpu_free_mm(vgpu, INTEL_GVT_MM_PPGTT);
+       intel_vgpu_free_mm(vgpu, INTEL_GVT_MM_GGTT);
 }
 
 static void clean_spt_oos(struct intel_gvt *gvt)
@@ -2322,6 +2330,13 @@ void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu, bool dmlr)
        int i;
 
        ppgtt_free_all_shadow_page(vgpu);
+
+       /* Shadow pages are only created when there is no page
+        * table tracking data, so remove page tracking data after
+        * removing the shadow pages.
+        */
+       intel_vgpu_free_mm(vgpu, INTEL_GVT_MM_PPGTT);
+
        if (!dmlr)
                return;