diff options
author | Suleiman Souhlal <ssouhlal@FreeBSD.org> | 2011-06-02 03:16:42 -0400 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2011-06-03 12:33:50 -0400 |
commit | a947eb95ea03199da7408a64baa97fbb613e9b84 (patch) | |
tree | f3a6c46b2c1b19a332a009d0e5ddb7512e21a40f | |
parent | d4d84fef6d0366b585b7de13527a0faeca84d9ce (diff) |
SLAB: Record actual last user of freed objects.
Currently, when using CONFIG_DEBUG_SLAB, we put in kfree() or
kmem_cache_free() as the last user of free objects, which is not
very useful, so change it to the caller of those functions instead.
Acked-by: David Rientjes <rientjes@google.com>
Acked-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Suleiman Souhlal <suleiman@google.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
-rw-r--r-- | mm/slab.c | 9 |
1 files changed, 5 insertions, 4 deletions
@@ -3604,13 +3604,14 @@ free_done: | |||
3604 | * Release an obj back to its cache. If the obj has a constructed state, it must | 3604 | * Release an obj back to its cache. If the obj has a constructed state, it must |
3605 | * be in this state _before_ it is released. Called with disabled ints. | 3605 | * be in this state _before_ it is released. Called with disabled ints. |
3606 | */ | 3606 | */ |
3607 | static inline void __cache_free(struct kmem_cache *cachep, void *objp) | 3607 | static inline void __cache_free(struct kmem_cache *cachep, void *objp, |
3608 | void *caller) | ||
3608 | { | 3609 | { |
3609 | struct array_cache *ac = cpu_cache_get(cachep); | 3610 | struct array_cache *ac = cpu_cache_get(cachep); |
3610 | 3611 | ||
3611 | check_irq_off(); | 3612 | check_irq_off(); |
3612 | kmemleak_free_recursive(objp, cachep->flags); | 3613 | kmemleak_free_recursive(objp, cachep->flags); |
3613 | objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0)); | 3614 | objp = cache_free_debugcheck(cachep, objp, caller); |
3614 | 3615 | ||
3615 | kmemcheck_slab_free(cachep, objp, obj_size(cachep)); | 3616 | kmemcheck_slab_free(cachep, objp, obj_size(cachep)); |
3616 | 3617 | ||
@@ -3801,7 +3802,7 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp) | |||
3801 | debug_check_no_locks_freed(objp, obj_size(cachep)); | 3802 | debug_check_no_locks_freed(objp, obj_size(cachep)); |
3802 | if (!(cachep->flags & SLAB_DEBUG_OBJECTS)) | 3803 | if (!(cachep->flags & SLAB_DEBUG_OBJECTS)) |
3803 | debug_check_no_obj_freed(objp, obj_size(cachep)); | 3804 | debug_check_no_obj_freed(objp, obj_size(cachep)); |
3804 | __cache_free(cachep, objp); | 3805 | __cache_free(cachep, objp, __builtin_return_address(0)); |
3805 | local_irq_restore(flags); | 3806 | local_irq_restore(flags); |
3806 | 3807 | ||
3807 | trace_kmem_cache_free(_RET_IP_, objp); | 3808 | trace_kmem_cache_free(_RET_IP_, objp); |
@@ -3831,7 +3832,7 @@ void kfree(const void *objp) | |||
3831 | c = virt_to_cache(objp); | 3832 | c = virt_to_cache(objp); |
3832 | debug_check_no_locks_freed(objp, obj_size(c)); | 3833 | debug_check_no_locks_freed(objp, obj_size(c)); |
3833 | debug_check_no_obj_freed(objp, obj_size(c)); | 3834 | debug_check_no_obj_freed(objp, obj_size(c)); |
3834 | __cache_free(c, (void *)objp); | 3835 | __cache_free(c, (void *)objp, __builtin_return_address(0)); |
3835 | local_irq_restore(flags); | 3836 | local_irq_restore(flags); |
3836 | } | 3837 | } |
3837 | EXPORT_SYMBOL(kfree); | 3838 | EXPORT_SYMBOL(kfree); |