From 0b37a9a9ebdf47dc9d5290a1c69bd944dde5cc15 Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Fri, 20 Mar 2015 09:41:03 +0000 Subject: [PATCH] drm/i915: Do not leak objects after capturing error state While running kmemleak chasing a different memleak, I saw that the capture_error_state function was leaking some objects, for example: unreferenced object 0xffff8800a9b72148 (size 8192): comm "kworker/u16:0", pid 1499, jiffies 4295201243 (age 990.096s) hex dump (first 32 bytes): 00 00 04 00 00 00 00 00 5d f4 ff ff 00 00 00 00 ........]....... 00 30 b0 01 00 00 00 00 37 00 00 00 00 00 00 00 .0......7....... backtrace: [] create_object+0x104/0x2c0 [] kmemleak_alloc+0x7a/0xc0 [] __kmalloc+0xeb/0x220 [] kcalloc.constprop.12+0x2d/0x2f [i915] [] i915_capture_error_state+0x3f4/0x1660 [i915] [] i915_handle_error+0x7f/0x660 [i915] [] i915_hangcheck_elapsed+0x2e7/0x470 [i915] [] process_one_work+0x144/0x490 [] worker_thread+0x11d/0x530 [] kthread+0xc9/0xe0 [] ret_from_fork+0x58/0x90 [] 0xffffffffffffffff The following objects are allocated in i915_gem_capture_buffers, but not released in i915_error_state_free: - error->active_bo_count - error->pinned_bo - error->pinned_bo_count - error->active_bo[vm_count] (allocated in i915_gem_capture_vm). The leaks were introduced by commit 95f5301dd880da2dea2c9a9c29750064536d426a Author: Ben Widawsky Date: Wed Jul 31 17:00:15 2013 -0700 drm/i915: Update error capture for VMs v2: Reuse iterator and add culprit commit details (Chris) Cc: Chris Wilson Signed-off-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gpu_error.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index a982849a5edd..2f7cbd3d5524 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -555,7 +555,14 @@ static void i915_error_state_free(struct kref *error_ref) } i915_error_object_free(error->semaphore_obj); + + for (i = 0; i < error->vm_count; i++) + kfree(error->active_bo[i]); + kfree(error->active_bo); + kfree(error->active_bo_count); + kfree(error->pinned_bo); + kfree(error->pinned_bo_count); kfree(error->overlay); kfree(error->display); kfree(error); -- 2.20.1