Commit ffe2c748e283c5dc1b9b9ac116299dbfc11a609b

Authored by Catalin Marinas
Committed by Linus Torvalds
1 parent aae0ad7ae5

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)
... ... @@ -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 *