[PATCH] drm/i915/gvt: clean up unsubmited workloads before destroying kmem cache

changbin.du at intel.com changbin.du at intel.com
Mon May 22 09:46:58 UTC 2017


From: Changbin Du <changbin.du at intel.com>

This is to fix a memory leak issue caused by unfreed gvtg workload objects.
Walk through the workload list and free all of the remained workloads
before destroying kmem cache.

[179.885211] INFO: Object 0xffff9cef10003b80 @offset=7040
[179.885657] kmem_cache_destroy gvt-g_vgpu_workload: Slab cache still has objects
[179.886146] CPU: 2 PID: 2318 Comm: win_lucas Tainted: G    B   W       4.11.0+ #1
[179.887223] Call Trace:
[179.887394]  dump_stack+0x63/0x90
[179.887617]  kmem_cache_destroy+0x1cf/0x1e0
[179.887960]  intel_vgpu_clean_execlist+0x15/0x20 [i915]
[179.888365]  intel_gvt_destroy_vgpu+0x4c/0xd0 [i915]
[179.888688]  intel_vgpu_remove+0x2a/0x30 [kvmgt]
[179.888988]  mdev_device_remove_ops+0x23/0x50 [mdev]
[179.889309]  mdev_device_remove+0xe4/0x190 [mdev]
[179.889615]  remove_store+0x7d/0xb0 [mdev]
[179.889885]  dev_attr_store+0x18/0x30
[179.890129]  sysfs_kf_write+0x37/0x40
[179.890371]  kernfs_fop_write+0x107/0x180
[179.890632]  __vfs_write+0x37/0x160
[179.890865]  ? kmem_cache_alloc+0xd7/0x1b0
[179.891116]  ? apparmor_file_permission+0x1a/0x20
[179.891372]  ? security_file_permission+0x3b/0xc0
[179.891628]  vfs_write+0xb8/0x1b0
[179.891812]  SyS_write+0x55/0xc0
[179.891992]  entry_SYSCALL_64_fastpath+0x1e/0xad

Signed-off-by: Changbin Du <changbin.du at intel.com>
---
 drivers/gpu/drm/i915/gvt/execlist.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c
index 8bba38f..7000505 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.c
+++ b/drivers/gpu/drm/i915/gvt/execlist.c
@@ -769,8 +769,26 @@ static void init_vgpu_execlist(struct intel_vgpu *vgpu, int ring_id)
 	vgpu_vreg(vgpu, ctx_status_ptr_reg) = ctx_status_ptr.dw;
 }
 
+static void clean_workloads(struct intel_vgpu *vgpu, unsigned long engine_mask)
+{
+	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
+	struct intel_engine_cs *engine;
+	struct intel_vgpu_workload *pos, *n;
+	unsigned int tmp;
+
+	/* free the unsubmited workloads in the queues. */
+	for_each_engine_masked(engine, dev_priv, engine_mask, tmp) {
+		list_for_each_entry_safe(pos, n,
+			&vgpu->workload_q_head[engine->id], list) {
+			list_del_init(&pos->list);
+			free_workload(pos);
+		}
+	}
+}
+
 void intel_vgpu_clean_execlist(struct intel_vgpu *vgpu)
 {
+	clean_workloads(vgpu, ALL_ENGINES);
 	kmem_cache_destroy(vgpu->workloads);
 }
 
@@ -801,17 +819,9 @@ void intel_vgpu_reset_execlist(struct intel_vgpu *vgpu,
 {
 	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 	struct intel_engine_cs *engine;
-	struct intel_vgpu_workload *pos, *n;
 	unsigned int tmp;
 
-	for_each_engine_masked(engine, dev_priv, engine_mask, tmp) {
-		/* free the unsubmited workload in the queue */
-		list_for_each_entry_safe(pos, n,
-			&vgpu->workload_q_head[engine->id], list) {
-			list_del_init(&pos->list);
-			free_workload(pos);
-		}
-
+	clean_workloads(vgpu, engine_mask);
+	for_each_engine_masked(engine, dev_priv, engine_mask, tmp)
 		init_vgpu_execlist(vgpu, engine->id);
-	}
 }
-- 
2.7.4



More information about the intel-gvt-dev mailing list