aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Kconfig.debug5
-rw-r--r--mm/kmemleak.c52
2 files changed, 27 insertions, 30 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 23067ab1a73c..4c32b1a1a06e 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -340,8 +340,6 @@ config DEBUG_KMEMLEAK
340 bool "Kernel memory leak detector" 340 bool "Kernel memory leak detector"
341 depends on DEBUG_KERNEL && EXPERIMENTAL && (X86 || ARM) && \ 341 depends on DEBUG_KERNEL && EXPERIMENTAL && (X86 || ARM) && \
342 !MEMORY_HOTPLUG 342 !MEMORY_HOTPLUG
343 select DEBUG_SLAB if SLAB
344 select SLUB_DEBUG if SLUB
345 select DEBUG_FS if SYSFS 343 select DEBUG_FS if SYSFS
346 select STACKTRACE if STACKTRACE_SUPPORT 344 select STACKTRACE if STACKTRACE_SUPPORT
347 select KALLSYMS 345 select KALLSYMS
@@ -355,6 +353,9 @@ config DEBUG_KMEMLEAK
355 allocations. See Documentation/kmemleak.txt for more 353 allocations. See Documentation/kmemleak.txt for more
356 details. 354 details.
357 355
356 Enabling DEBUG_SLAB or SLUB_DEBUG may increase the chances
357 of finding leaks due to the slab objects poisoning.
358
358 In order to access the kmemleak file, debugfs needs to be 359 In order to access the kmemleak file, debugfs needs to be
359 mounted (usually at /sys/kernel/debug). 360 mounted (usually at /sys/kernel/debug).
360 361
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index ec759b60077a..c96f2c8700aa 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -61,6 +61,8 @@
61 * structure. 61 * structure.
62 */ 62 */
63 63
64#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
65
64#include <linux/init.h> 66#include <linux/init.h>
65#include <linux/kernel.h> 67#include <linux/kernel.h>
66#include <linux/list.h> 68#include <linux/list.h>
@@ -311,7 +313,7 @@ static int unreferenced_object(struct kmemleak_object *object)
311 313
312static void print_referenced(struct kmemleak_object *object) 314static void print_referenced(struct kmemleak_object *object)
313{ 315{
314 pr_info("kmemleak: referenced object 0x%08lx (size %zu)\n", 316 pr_info("referenced object 0x%08lx (size %zu)\n",
315 object->pointer, object->size); 317 object->pointer, object->size);
316} 318}
317 319
@@ -320,7 +322,7 @@ static void print_unreferenced(struct seq_file *seq,
320{ 322{
321 int i; 323 int i;
322 324
323 print_helper(seq, "kmemleak: unreferenced object 0x%08lx (size %zu):\n", 325 print_helper(seq, "unreferenced object 0x%08lx (size %zu):\n",
324 object->pointer, object->size); 326 object->pointer, object->size);
325 print_helper(seq, " comm \"%s\", pid %d, jiffies %lu\n", 327 print_helper(seq, " comm \"%s\", pid %d, jiffies %lu\n",
326 object->comm, object->pid, object->jiffies); 328 object->comm, object->pid, object->jiffies);
@@ -344,7 +346,7 @@ static void dump_object_info(struct kmemleak_object *object)
344 trace.nr_entries = object->trace_len; 346 trace.nr_entries = object->trace_len;
345 trace.entries = object->trace; 347 trace.entries = object->trace;
346 348
347 pr_notice("kmemleak: Object 0x%08lx (size %zu):\n", 349 pr_notice("Object 0x%08lx (size %zu):\n",
348 object->tree_node.start, object->size); 350 object->tree_node.start, object->size);
349 pr_notice(" comm \"%s\", pid %d, jiffies %lu\n", 351 pr_notice(" comm \"%s\", pid %d, jiffies %lu\n",
350 object->comm, object->pid, object->jiffies); 352 object->comm, object->pid, object->jiffies);
@@ -372,7 +374,7 @@ static struct kmemleak_object *lookup_object(unsigned long ptr, int alias)
372 object = prio_tree_entry(node, struct kmemleak_object, 374 object = prio_tree_entry(node, struct kmemleak_object,
373 tree_node); 375 tree_node);
374 if (!alias && object->pointer != ptr) { 376 if (!alias && object->pointer != ptr) {
375 kmemleak_warn("kmemleak: Found object by alias"); 377 kmemleak_warn("Found object by alias");
376 object = NULL; 378 object = NULL;
377 } 379 }
378 } else 380 } else
@@ -467,8 +469,7 @@ static void create_object(unsigned long ptr, size_t size, int min_count,
467 469
468 object = kmem_cache_alloc(object_cache, gfp & GFP_KMEMLEAK_MASK); 470 object = kmem_cache_alloc(object_cache, gfp & GFP_KMEMLEAK_MASK);
469 if (!object) { 471 if (!object) {
470 kmemleak_stop("kmemleak: Cannot allocate a kmemleak_object " 472 kmemleak_stop("Cannot allocate a kmemleak_object structure\n");
471 "structure\n");
472 return; 473 return;
473 } 474 }
474 475
@@ -527,8 +528,8 @@ static void create_object(unsigned long ptr, size_t size, int min_count,
527 if (node != &object->tree_node) { 528 if (node != &object->tree_node) {
528 unsigned long flags; 529 unsigned long flags;
529 530
530 kmemleak_stop("kmemleak: Cannot insert 0x%lx into the object " 531 kmemleak_stop("Cannot insert 0x%lx into the object search tree "
531 "search tree (already existing)\n", ptr); 532 "(already existing)\n", ptr);
532 object = lookup_object(ptr, 1); 533 object = lookup_object(ptr, 1);
533 spin_lock_irqsave(&object->lock, flags); 534 spin_lock_irqsave(&object->lock, flags);
534 dump_object_info(object); 535 dump_object_info(object);
@@ -553,7 +554,7 @@ static void delete_object(unsigned long ptr)
553 write_lock_irqsave(&kmemleak_lock, flags); 554 write_lock_irqsave(&kmemleak_lock, flags);
554 object = lookup_object(ptr, 0); 555 object = lookup_object(ptr, 0);
555 if (!object) { 556 if (!object) {
556 kmemleak_warn("kmemleak: Freeing unknown object at 0x%08lx\n", 557 kmemleak_warn("Freeing unknown object at 0x%08lx\n",
557 ptr); 558 ptr);
558 write_unlock_irqrestore(&kmemleak_lock, flags); 559 write_unlock_irqrestore(&kmemleak_lock, flags);
559 return; 560 return;
@@ -588,8 +589,7 @@ static void make_gray_object(unsigned long ptr)
588 589
589 object = find_and_get_object(ptr, 0); 590 object = find_and_get_object(ptr, 0);
590 if (!object) { 591 if (!object) {
591 kmemleak_warn("kmemleak: Graying unknown object at 0x%08lx\n", 592 kmemleak_warn("Graying unknown object at 0x%08lx\n", ptr);
592 ptr);
593 return; 593 return;
594 } 594 }
595 595
@@ -610,8 +610,7 @@ static void make_black_object(unsigned long ptr)
610 610
611 object = find_and_get_object(ptr, 0); 611 object = find_and_get_object(ptr, 0);
612 if (!object) { 612 if (!object) {
613 kmemleak_warn("kmemleak: Blacking unknown object at 0x%08lx\n", 613 kmemleak_warn("Blacking unknown object at 0x%08lx\n", ptr);
614 ptr);
615 return; 614 return;
616 } 615 }
617 616
@@ -634,21 +633,20 @@ static void add_scan_area(unsigned long ptr, unsigned long offset,
634 633
635 object = find_and_get_object(ptr, 0); 634 object = find_and_get_object(ptr, 0);
636 if (!object) { 635 if (!object) {
637 kmemleak_warn("kmemleak: Adding scan area to unknown " 636 kmemleak_warn("Adding scan area to unknown object at 0x%08lx\n",
638 "object at 0x%08lx\n", ptr); 637 ptr);
639 return; 638 return;
640 } 639 }
641 640
642 area = kmem_cache_alloc(scan_area_cache, gfp & GFP_KMEMLEAK_MASK); 641 area = kmem_cache_alloc(scan_area_cache, gfp & GFP_KMEMLEAK_MASK);
643 if (!area) { 642 if (!area) {
644 kmemleak_warn("kmemleak: Cannot allocate a scan area\n"); 643 kmemleak_warn("Cannot allocate a scan area\n");
645 goto out; 644 goto out;
646 } 645 }
647 646
648 spin_lock_irqsave(&object->lock, flags); 647 spin_lock_irqsave(&object->lock, flags);
649 if (offset + length > object->size) { 648 if (offset + length > object->size) {
650 kmemleak_warn("kmemleak: Scan area larger than object " 649 kmemleak_warn("Scan area larger than object 0x%08lx\n", ptr);
651 "0x%08lx\n", ptr);
652 dump_object_info(object); 650 dump_object_info(object);
653 kmem_cache_free(scan_area_cache, area); 651 kmem_cache_free(scan_area_cache, area);
654 goto out_unlock; 652 goto out_unlock;
@@ -677,8 +675,7 @@ static void object_no_scan(unsigned long ptr)
677 675
678 object = find_and_get_object(ptr, 0); 676 object = find_and_get_object(ptr, 0);
679 if (!object) { 677 if (!object) {
680 kmemleak_warn("kmemleak: Not scanning unknown object at " 678 kmemleak_warn("Not scanning unknown object at 0x%08lx\n", ptr);
681 "0x%08lx\n", ptr);
682 return; 679 return;
683 } 680 }
684 681
@@ -699,7 +696,7 @@ static void log_early(int op_type, const void *ptr, size_t size,
699 struct early_log *log; 696 struct early_log *log;
700 697
701 if (crt_early_log >= ARRAY_SIZE(early_log)) { 698 if (crt_early_log >= ARRAY_SIZE(early_log)) {
702 kmemleak_stop("kmemleak: Early log buffer exceeded\n"); 699 kmemleak_stop("Early log buffer exceeded\n");
703 return; 700 return;
704 } 701 }
705 702
@@ -966,7 +963,7 @@ static void kmemleak_scan(void)
966 * 1 reference to any object at this point. 963 * 1 reference to any object at this point.
967 */ 964 */
968 if (atomic_read(&object->use_count) > 1) { 965 if (atomic_read(&object->use_count) > 1) {
969 pr_debug("kmemleak: object->use_count = %d\n", 966 pr_debug("object->use_count = %d\n",
970 atomic_read(&object->use_count)); 967 atomic_read(&object->use_count));
971 dump_object_info(object); 968 dump_object_info(object);
972 } 969 }
@@ -1062,7 +1059,7 @@ static int kmemleak_scan_thread(void *arg)
1062{ 1059{
1063 static int first_run = 1; 1060 static int first_run = 1;
1064 1061
1065 pr_info("kmemleak: Automatic memory scanning thread started\n"); 1062 pr_info("Automatic memory scanning thread started\n");
1066 1063
1067 /* 1064 /*
1068 * Wait before the first scan to allow the system to fully initialize. 1065 * Wait before the first scan to allow the system to fully initialize.
@@ -1108,7 +1105,7 @@ static int kmemleak_scan_thread(void *arg)
1108 timeout = schedule_timeout_interruptible(timeout); 1105 timeout = schedule_timeout_interruptible(timeout);
1109 } 1106 }
1110 1107
1111 pr_info("kmemleak: Automatic memory scanning thread ended\n"); 1108 pr_info("Automatic memory scanning thread ended\n");
1112 1109
1113 return 0; 1110 return 0;
1114} 1111}
@@ -1123,7 +1120,7 @@ void start_scan_thread(void)
1123 return; 1120 return;
1124 scan_thread = kthread_run(kmemleak_scan_thread, NULL, "kmemleak"); 1121 scan_thread = kthread_run(kmemleak_scan_thread, NULL, "kmemleak");
1125 if (IS_ERR(scan_thread)) { 1122 if (IS_ERR(scan_thread)) {
1126 pr_warning("kmemleak: Failed to create the scan thread\n"); 1123 pr_warning("Failed to create the scan thread\n");
1127 scan_thread = NULL; 1124 scan_thread = NULL;
1128 } 1125 }
1129} 1126}
@@ -1367,7 +1364,7 @@ static void kmemleak_cleanup(void)
1367 cleanup_thread = kthread_run(kmemleak_cleanup_thread, NULL, 1364 cleanup_thread = kthread_run(kmemleak_cleanup_thread, NULL,
1368 "kmemleak-clean"); 1365 "kmemleak-clean");
1369 if (IS_ERR(cleanup_thread)) 1366 if (IS_ERR(cleanup_thread))
1370 pr_warning("kmemleak: Failed to create the clean-up thread\n"); 1367 pr_warning("Failed to create the clean-up thread\n");
1371} 1368}
1372 1369
1373/* 1370/*
@@ -1488,8 +1485,7 @@ static int __init kmemleak_late_init(void)
1488 dentry = debugfs_create_file("kmemleak", S_IRUGO, NULL, NULL, 1485 dentry = debugfs_create_file("kmemleak", S_IRUGO, NULL, NULL,
1489 &kmemleak_fops); 1486 &kmemleak_fops);
1490 if (!dentry) 1487 if (!dentry)
1491 pr_warning("kmemleak: Failed to create the debugfs kmemleak " 1488 pr_warning("Failed to create the debugfs kmemleak file\n");
1492 "file\n");
1493 mutex_lock(&kmemleak_mutex); 1489 mutex_lock(&kmemleak_mutex);
1494 start_scan_thread(); 1490 start_scan_thread();
1495 mutex_unlock(&kmemleak_mutex); 1491 mutex_unlock(&kmemleak_mutex);