|
@@ -989,6 +989,40 @@ void __ref kmemleak_free_percpu(const void __percpu *ptr)
|
|
|
}
|
|
|
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
|
|
|
* @ptr: pointer to beginning of the object
|