Commit ffe2c748 authored by Catalin Marinas's avatar Catalin Marinas Committed by Linus Torvalds

mm: introduce kmemleak_update_trace()

The memory allocation stack trace is not always useful for debugging a
memory leak (e.g.  radix_tree_preload).  This function, when called,
updates the stack trace for an already allocated object.
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent aae0ad7a
...@@ -142,6 +142,7 @@ kmemleak_alloc_percpu - notify of a percpu memory block allocation ...@@ -142,6 +142,7 @@ kmemleak_alloc_percpu - notify of a percpu memory block allocation
kmemleak_free - notify of a memory block freeing kmemleak_free - notify of a memory block freeing
kmemleak_free_part - notify of a partial memory block freeing kmemleak_free_part - notify of a partial memory block freeing
kmemleak_free_percpu - notify of a percpu memory block freeing kmemleak_free_percpu - notify of a percpu memory block freeing
kmemleak_update_trace - update object allocation stack trace
kmemleak_not_leak - mark an object as not a leak kmemleak_not_leak - mark an object as not a leak
kmemleak_ignore - do not scan or report an object as leak kmemleak_ignore - do not scan or report an object as leak
kmemleak_scan_area - add scan areas inside a memory block kmemleak_scan_area - add scan areas inside a memory block
......
...@@ -30,6 +30,7 @@ extern void kmemleak_alloc_percpu(const void __percpu *ptr, size_t size) __ref; ...@@ -30,6 +30,7 @@ extern void kmemleak_alloc_percpu(const void __percpu *ptr, size_t size) __ref;
extern void kmemleak_free(const void *ptr) __ref; extern void kmemleak_free(const void *ptr) __ref;
extern void kmemleak_free_part(const void *ptr, size_t size) __ref; extern void kmemleak_free_part(const void *ptr, size_t size) __ref;
extern void kmemleak_free_percpu(const void __percpu *ptr) __ref; extern void kmemleak_free_percpu(const void __percpu *ptr) __ref;
extern void kmemleak_update_trace(const void *ptr) __ref;
extern void kmemleak_not_leak(const void *ptr) __ref; extern void kmemleak_not_leak(const void *ptr) __ref;
extern void kmemleak_ignore(const void *ptr) __ref; extern void kmemleak_ignore(const void *ptr) __ref;
extern void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) __ref; extern void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) __ref;
...@@ -83,6 +84,9 @@ static inline void kmemleak_free_recursive(const void *ptr, unsigned long flags) ...@@ -83,6 +84,9 @@ static inline void kmemleak_free_recursive(const void *ptr, unsigned long flags)
static inline void kmemleak_free_percpu(const void __percpu *ptr) static inline void kmemleak_free_percpu(const void __percpu *ptr)
{ {
} }
static inline void kmemleak_update_trace(const void *ptr)
{
}
static inline void kmemleak_not_leak(const void *ptr) static inline void kmemleak_not_leak(const void *ptr)
{ {
} }
......
...@@ -989,6 +989,40 @@ void __ref kmemleak_free_percpu(const void __percpu *ptr) ...@@ -989,6 +989,40 @@ void __ref kmemleak_free_percpu(const void __percpu *ptr)
} }
EXPORT_SYMBOL_GPL(kmemleak_free_percpu); EXPORT_SYMBOL_GPL(kmemleak_free_percpu);
/**
* kmemleak_update_trace - update object allocation stack trace
* @ptr: pointer to beginning of the object
*
* Override the object allocation stack trace for cases where the actual
* allocation place is not always useful.
*/
void __ref kmemleak_update_trace(const void *ptr)
{
struct kmemleak_object *object;
unsigned long flags;
pr_debug("%s(0x%p)\n", __func__, ptr);
if (!kmemleak_enabled || IS_ERR_OR_NULL(ptr))
return;
object = find_and_get_object((unsigned long)ptr, 1);
if (!object) {
#ifdef DEBUG
kmemleak_warn("Updating stack trace for unknown object at %p\n",
ptr);
#endif
return;
}
spin_lock_irqsave(&object->lock, flags);
object->trace_len = __save_stack_trace(object->trace);
spin_unlock_irqrestore(&object->lock, flags);
put_object(object);
}
EXPORT_SYMBOL(kmemleak_update_trace);
/** /**
* kmemleak_not_leak - mark an allocated object as false positive * kmemleak_not_leak - mark an allocated object as false positive
* @ptr: pointer to beginning of the object * @ptr: pointer to beginning of the object
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment