SLAB: Record actual last user of freed objects.
authorSuleiman Souhlal <ssouhlal@FreeBSD.org>
Thu, 2 Jun 2011 07:16:42 +0000 (00:16 -0700)
committerPekka Enberg <penberg@kernel.org>
Fri, 3 Jun 2011 16:33:50 +0000 (19:33 +0300)
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>
mm/slab.c

index bcfa498..d96e223 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3604,13 +3604,14 @@ free_done:
  * Release an obj back to its cache. If the obj has a constructed state, it must
  * be in this state _before_ it is released.  Called with disabled ints.
  */
  * Release an obj back to its cache. If the obj has a constructed state, it must
  * be in this state _before_ it is released.  Called with disabled ints.
  */
-static inline void __cache_free(struct kmem_cache *cachep, void *objp)
+static inline void __cache_free(struct kmem_cache *cachep, void *objp,
+    void *caller)
 {
        struct array_cache *ac = cpu_cache_get(cachep);
 
        check_irq_off();
        kmemleak_free_recursive(objp, cachep->flags);
 {
        struct array_cache *ac = cpu_cache_get(cachep);
 
        check_irq_off();
        kmemleak_free_recursive(objp, cachep->flags);
-       objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
+       objp = cache_free_debugcheck(cachep, objp, caller);
 
        kmemcheck_slab_free(cachep, objp, obj_size(cachep));
 
 
        kmemcheck_slab_free(cachep, objp, obj_size(cachep));
 
@@ -3801,7 +3802,7 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
        debug_check_no_locks_freed(objp, obj_size(cachep));
        if (!(cachep->flags & SLAB_DEBUG_OBJECTS))
                debug_check_no_obj_freed(objp, obj_size(cachep));
        debug_check_no_locks_freed(objp, obj_size(cachep));
        if (!(cachep->flags & SLAB_DEBUG_OBJECTS))
                debug_check_no_obj_freed(objp, obj_size(cachep));
-       __cache_free(cachep, objp);
+       __cache_free(cachep, objp, __builtin_return_address(0));
        local_irq_restore(flags);
 
        trace_kmem_cache_free(_RET_IP_, objp);
        local_irq_restore(flags);
 
        trace_kmem_cache_free(_RET_IP_, objp);
@@ -3831,7 +3832,7 @@ void kfree(const void *objp)
        c = virt_to_cache(objp);
        debug_check_no_locks_freed(objp, obj_size(c));
        debug_check_no_obj_freed(objp, obj_size(c));
        c = virt_to_cache(objp);
        debug_check_no_locks_freed(objp, obj_size(c));
        debug_check_no_obj_freed(objp, obj_size(c));
-       __cache_free(c, (void *)objp);
+       __cache_free(c, (void *)objp, __builtin_return_address(0));
        local_irq_restore(flags);
 }
 EXPORT_SYMBOL(kfree);
        local_irq_restore(flags);
 }
 EXPORT_SYMBOL(kfree);