Commit ffe2c748e283c5dc1b9b9ac116299dbfc11a609b
Committed by
Linus Torvalds
1 parent
aae0ad7ae5
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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: Catalin Marinas <catalin.marinas@arm.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 3 changed files with 39 additions and 0 deletions Side-by-side Diff
Documentation/kmemleak.txt
... | ... | @@ -142,6 +142,7 @@ |
142 | 142 | kmemleak_free - notify of a memory block freeing |
143 | 143 | kmemleak_free_part - notify of a partial memory block freeing |
144 | 144 | kmemleak_free_percpu - notify of a percpu memory block freeing |
145 | +kmemleak_update_trace - update object allocation stack trace | |
145 | 146 | kmemleak_not_leak - mark an object as not a leak |
146 | 147 | kmemleak_ignore - do not scan or report an object as leak |
147 | 148 | kmemleak_scan_area - add scan areas inside a memory block |
include/linux/kmemleak.h
... | ... | @@ -30,6 +30,7 @@ |
30 | 30 | extern void kmemleak_free(const void *ptr) __ref; |
31 | 31 | extern void kmemleak_free_part(const void *ptr, size_t size) __ref; |
32 | 32 | extern void kmemleak_free_percpu(const void __percpu *ptr) __ref; |
33 | +extern void kmemleak_update_trace(const void *ptr) __ref; | |
33 | 34 | extern void kmemleak_not_leak(const void *ptr) __ref; |
34 | 35 | extern void kmemleak_ignore(const void *ptr) __ref; |
35 | 36 | extern void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) __ref; |
... | ... | @@ -81,6 +82,9 @@ |
81 | 82 | { |
82 | 83 | } |
83 | 84 | static inline void kmemleak_free_percpu(const void __percpu *ptr) |
85 | +{ | |
86 | +} | |
87 | +static inline void kmemleak_update_trace(const void *ptr) | |
84 | 88 | { |
85 | 89 | } |
86 | 90 | static inline void kmemleak_not_leak(const void *ptr) |
mm/kmemleak.c
... | ... | @@ -990,6 +990,40 @@ |
990 | 990 | EXPORT_SYMBOL_GPL(kmemleak_free_percpu); |
991 | 991 | |
992 | 992 | /** |
993 | + * kmemleak_update_trace - update object allocation stack trace | |
994 | + * @ptr: pointer to beginning of the object | |
995 | + * | |
996 | + * Override the object allocation stack trace for cases where the actual | |
997 | + * allocation place is not always useful. | |
998 | + */ | |
999 | +void __ref kmemleak_update_trace(const void *ptr) | |
1000 | +{ | |
1001 | + struct kmemleak_object *object; | |
1002 | + unsigned long flags; | |
1003 | + | |
1004 | + pr_debug("%s(0x%p)\n", __func__, ptr); | |
1005 | + | |
1006 | + if (!kmemleak_enabled || IS_ERR_OR_NULL(ptr)) | |
1007 | + return; | |
1008 | + | |
1009 | + object = find_and_get_object((unsigned long)ptr, 1); | |
1010 | + if (!object) { | |
1011 | +#ifdef DEBUG | |
1012 | + kmemleak_warn("Updating stack trace for unknown object at %p\n", | |
1013 | + ptr); | |
1014 | +#endif | |
1015 | + return; | |
1016 | + } | |
1017 | + | |
1018 | + spin_lock_irqsave(&object->lock, flags); | |
1019 | + object->trace_len = __save_stack_trace(object->trace); | |
1020 | + spin_unlock_irqrestore(&object->lock, flags); | |
1021 | + | |
1022 | + put_object(object); | |
1023 | +} | |
1024 | +EXPORT_SYMBOL(kmemleak_update_trace); | |
1025 | + | |
1026 | +/** | |
993 | 1027 | * kmemleak_not_leak - mark an allocated object as false positive |
994 | 1028 | * @ptr: pointer to beginning of the object |
995 | 1029 | * |