diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-07-24 22:28:25 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-08-02 10:13:56 +1000 |
commit | ddd3d069c08bb1ba83aa4d522fc1360ce4afc270 (patch) | |
tree | de16542f3e250eb621c75df487c584d785366ed3 /drivers/gpu/drm | |
parent | c39721c775f7ac20af5ff1cbbd11f80aeec91baa (diff) |
drm: Free the idr layers before calling idr_destroy()
/* A typical clean-up sequence for objects stored in an idr tree, will
* use idr_for_each() to free all objects, if necessary, then
* idr_remove_all() to remove all ids, and idr_destroy() to free
* up the cached idr_layers.
*/
We were missing the vital idr_rmove_all() step and so were leaking
the used layers for every dri client:
unreferenced object 0xf32133c0 (size 148):
comm "plymouthd", pid 131, jiffies 4294678490 (age 2308.030s)
hex dump (first 32 bytes):
04 00 00 00 00 00 00 00 00 00 00 00 00 40 19 f3 .............@..
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<c04e5657>] create_object+0x124/0x1f1
[<c07cf100>] kmemleak_alloc+0x4c/0x90
[<c04db6a9>] kmem_cache_alloc+0xee/0x13c
[<c05c3d25>] idr_pre_get+0x24/0x61
[<f8315c9c>] drm_gem_handle_create+0x27/0x7f [drm]
[<f89925b2>] i915_gem_create_ioctl+0x4f/0x71 [i915]
[<f83148ac>] drm_ioctl+0x272/0x356 [drm]
[<c04f27c4>] vfs_ioctl+0x33/0x91
[<c04f31cf>] do_vfs_ioctl+0x46b/0x496
[<c04f3240>] sys_ioctl+0x46/0x66
[<c040325f>] sysenter_do_call+0x12/0x38
[<ffffffff>] 0xffffffff
Fixes https://bugzilla.kernel.org/show_bug.cgi?id=15803
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_gem.c | 1 |
2 files changed, 2 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 510bc87d98f6..b5a51686f492 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -335,6 +335,7 @@ static void __exit drm_core_exit(void) unregister_chrdev(DRM_MAJOR, "drm"); + idr_remove_all(&drm_minors_idr); idr_destroy(&drm_minors_idr); } diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 8601b72b6f26..4f1b86714489 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -429,6 +429,7 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private) idr_for_each(&file_private->object_idr, &drm_gem_object_release_handle, NULL); + idr_remove_all(&file_private->object_idr); idr_destroy(&file_private->object_idr); } |