diff options
Diffstat (limited to 'mm/kmemleak.c')
-rw-r--r-- | mm/kmemleak.c | 243 |
1 files changed, 92 insertions, 151 deletions
diff --git a/mm/kmemleak.c b/mm/kmemleak.c index ec759b60077a..e766e1da09d2 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c | |||
@@ -48,10 +48,10 @@ | |||
48 | * scanned. This list is only modified during a scanning episode when the | 48 | * scanned. This list is only modified during a scanning episode when the |
49 | * scan_mutex is held. At the end of a scan, the gray_list is always empty. | 49 | * scan_mutex is held. At the end of a scan, the gray_list is always empty. |
50 | * Note that the kmemleak_object.use_count is incremented when an object is | 50 | * Note that the kmemleak_object.use_count is incremented when an object is |
51 | * added to the gray_list and therefore cannot be freed | 51 | * added to the gray_list and therefore cannot be freed. This mutex also |
52 | * - kmemleak_mutex (mutex): prevents multiple users of the "kmemleak" debugfs | 52 | * prevents multiple users of the "kmemleak" debugfs file together with |
53 | * file together with modifications to the memory scanning parameters | 53 | * modifications to the memory scanning parameters including the scan_thread |
54 | * including the scan_thread pointer | 54 | * pointer |
55 | * | 55 | * |
56 | * The kmemleak_object structures have a use_count incremented or decremented | 56 | * The kmemleak_object structures have a use_count incremented or decremented |
57 | * using the get_object()/put_object() functions. When the use_count becomes | 57 | * using the get_object()/put_object() functions. When the use_count becomes |
@@ -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> |
@@ -103,7 +105,6 @@ | |||
103 | #define MAX_TRACE 16 /* stack trace length */ | 105 | #define MAX_TRACE 16 /* stack trace length */ |
104 | #define REPORTS_NR 50 /* maximum number of reported leaks */ | 106 | #define REPORTS_NR 50 /* maximum number of reported leaks */ |
105 | #define MSECS_MIN_AGE 5000 /* minimum object age for reporting */ | 107 | #define MSECS_MIN_AGE 5000 /* minimum object age for reporting */ |
106 | #define MSECS_SCAN_YIELD 10 /* CPU yielding period */ | ||
107 | #define SECS_FIRST_SCAN 60 /* delay before the first scan */ | 108 | #define SECS_FIRST_SCAN 60 /* delay before the first scan */ |
108 | #define SECS_SCAN_WAIT 600 /* subsequent auto scanning delay */ | 109 | #define SECS_SCAN_WAIT 600 /* subsequent auto scanning delay */ |
109 | 110 | ||
@@ -184,19 +185,16 @@ static atomic_t kmemleak_error = ATOMIC_INIT(0); | |||
184 | static unsigned long min_addr = ULONG_MAX; | 185 | static unsigned long min_addr = ULONG_MAX; |
185 | static unsigned long max_addr; | 186 | static unsigned long max_addr; |
186 | 187 | ||
187 | /* used for yielding the CPU to other tasks during scanning */ | ||
188 | static unsigned long next_scan_yield; | ||
189 | static struct task_struct *scan_thread; | 188 | static struct task_struct *scan_thread; |
190 | static unsigned long jiffies_scan_yield; | 189 | /* used to avoid reporting of recently allocated objects */ |
191 | static unsigned long jiffies_min_age; | 190 | static unsigned long jiffies_min_age; |
191 | static unsigned long jiffies_last_scan; | ||
192 | /* delay between automatic memory scannings */ | 192 | /* delay between automatic memory scannings */ |
193 | static signed long jiffies_scan_wait; | 193 | static signed long jiffies_scan_wait; |
194 | /* enables or disables the task stacks scanning */ | 194 | /* enables or disables the task stacks scanning */ |
195 | static int kmemleak_stack_scan; | 195 | static int kmemleak_stack_scan = 1; |
196 | /* mutex protecting the memory scanning */ | 196 | /* protects the memory scanning, parameters and debug/kmemleak file access */ |
197 | static DEFINE_MUTEX(scan_mutex); | 197 | static DEFINE_MUTEX(scan_mutex); |
198 | /* mutex protecting the access to the /sys/kernel/debug/kmemleak file */ | ||
199 | static DEFINE_MUTEX(kmemleak_mutex); | ||
200 | 198 | ||
201 | /* number of leaks reported (for limitation purposes) */ | 199 | /* number of leaks reported (for limitation purposes) */ |
202 | static int reported_leaks; | 200 | static int reported_leaks; |
@@ -233,7 +231,7 @@ struct early_log { | |||
233 | }; | 231 | }; |
234 | 232 | ||
235 | /* early logging buffer and current position */ | 233 | /* early logging buffer and current position */ |
236 | static struct early_log early_log[200]; | 234 | static struct early_log early_log[CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE]; |
237 | static int crt_early_log; | 235 | static int crt_early_log; |
238 | 236 | ||
239 | static void kmemleak_disable(void); | 237 | static void kmemleak_disable(void); |
@@ -277,15 +275,6 @@ static int color_gray(const struct kmemleak_object *object) | |||
277 | } | 275 | } |
278 | 276 | ||
279 | /* | 277 | /* |
280 | * Objects are considered referenced if their color is gray and they have not | ||
281 | * been deleted. | ||
282 | */ | ||
283 | static int referenced_object(struct kmemleak_object *object) | ||
284 | { | ||
285 | return (object->flags & OBJECT_ALLOCATED) && color_gray(object); | ||
286 | } | ||
287 | |||
288 | /* | ||
289 | * Objects are considered unreferenced only if their color is white, they have | 278 | * Objects are considered unreferenced only if their color is white, they have |
290 | * not be deleted and have a minimum age to avoid false positives caused by | 279 | * not be deleted and have a minimum age to avoid false positives caused by |
291 | * pointers temporarily stored in CPU registers. | 280 | * pointers temporarily stored in CPU registers. |
@@ -293,42 +282,28 @@ static int referenced_object(struct kmemleak_object *object) | |||
293 | static int unreferenced_object(struct kmemleak_object *object) | 282 | static int unreferenced_object(struct kmemleak_object *object) |
294 | { | 283 | { |
295 | return (object->flags & OBJECT_ALLOCATED) && color_white(object) && | 284 | return (object->flags & OBJECT_ALLOCATED) && color_white(object) && |
296 | time_is_before_eq_jiffies(object->jiffies + jiffies_min_age); | 285 | time_before_eq(object->jiffies + jiffies_min_age, |
286 | jiffies_last_scan); | ||
297 | } | 287 | } |
298 | 288 | ||
299 | /* | 289 | /* |
300 | * Printing of the (un)referenced objects information, either to the seq file | 290 | * Printing of the unreferenced objects information to the seq file. The |
301 | * or to the kernel log. The print_referenced/print_unreferenced functions | 291 | * print_unreferenced function must be called with the object->lock held. |
302 | * must be called with the object->lock held. | ||
303 | */ | 292 | */ |
304 | #define print_helper(seq, x...) do { \ | ||
305 | struct seq_file *s = (seq); \ | ||
306 | if (s) \ | ||
307 | seq_printf(s, x); \ | ||
308 | else \ | ||
309 | pr_info(x); \ | ||
310 | } while (0) | ||
311 | |||
312 | static void print_referenced(struct kmemleak_object *object) | ||
313 | { | ||
314 | pr_info("kmemleak: referenced object 0x%08lx (size %zu)\n", | ||
315 | object->pointer, object->size); | ||
316 | } | ||
317 | |||
318 | static void print_unreferenced(struct seq_file *seq, | 293 | static void print_unreferenced(struct seq_file *seq, |
319 | struct kmemleak_object *object) | 294 | struct kmemleak_object *object) |
320 | { | 295 | { |
321 | int i; | 296 | int i; |
322 | 297 | ||
323 | print_helper(seq, "kmemleak: unreferenced object 0x%08lx (size %zu):\n", | 298 | seq_printf(seq, "unreferenced object 0x%08lx (size %zu):\n", |
324 | object->pointer, object->size); | 299 | object->pointer, object->size); |
325 | print_helper(seq, " comm \"%s\", pid %d, jiffies %lu\n", | 300 | seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu\n", |
326 | object->comm, object->pid, object->jiffies); | 301 | object->comm, object->pid, object->jiffies); |
327 | print_helper(seq, " backtrace:\n"); | 302 | seq_printf(seq, " backtrace:\n"); |
328 | 303 | ||
329 | for (i = 0; i < object->trace_len; i++) { | 304 | for (i = 0; i < object->trace_len; i++) { |
330 | void *ptr = (void *)object->trace[i]; | 305 | void *ptr = (void *)object->trace[i]; |
331 | print_helper(seq, " [<%p>] %pS\n", ptr, ptr); | 306 | seq_printf(seq, " [<%p>] %pS\n", ptr, ptr); |
332 | } | 307 | } |
333 | } | 308 | } |
334 | 309 | ||
@@ -344,7 +319,7 @@ static void dump_object_info(struct kmemleak_object *object) | |||
344 | trace.nr_entries = object->trace_len; | 319 | trace.nr_entries = object->trace_len; |
345 | trace.entries = object->trace; | 320 | trace.entries = object->trace; |
346 | 321 | ||
347 | pr_notice("kmemleak: Object 0x%08lx (size %zu):\n", | 322 | pr_notice("Object 0x%08lx (size %zu):\n", |
348 | object->tree_node.start, object->size); | 323 | object->tree_node.start, object->size); |
349 | pr_notice(" comm \"%s\", pid %d, jiffies %lu\n", | 324 | pr_notice(" comm \"%s\", pid %d, jiffies %lu\n", |
350 | object->comm, object->pid, object->jiffies); | 325 | object->comm, object->pid, object->jiffies); |
@@ -372,7 +347,7 @@ static struct kmemleak_object *lookup_object(unsigned long ptr, int alias) | |||
372 | object = prio_tree_entry(node, struct kmemleak_object, | 347 | object = prio_tree_entry(node, struct kmemleak_object, |
373 | tree_node); | 348 | tree_node); |
374 | if (!alias && object->pointer != ptr) { | 349 | if (!alias && object->pointer != ptr) { |
375 | kmemleak_warn("kmemleak: Found object by alias"); | 350 | kmemleak_warn("Found object by alias"); |
376 | object = NULL; | 351 | object = NULL; |
377 | } | 352 | } |
378 | } else | 353 | } else |
@@ -467,8 +442,7 @@ static void create_object(unsigned long ptr, size_t size, int min_count, | |||
467 | 442 | ||
468 | object = kmem_cache_alloc(object_cache, gfp & GFP_KMEMLEAK_MASK); | 443 | object = kmem_cache_alloc(object_cache, gfp & GFP_KMEMLEAK_MASK); |
469 | if (!object) { | 444 | if (!object) { |
470 | kmemleak_stop("kmemleak: Cannot allocate a kmemleak_object " | 445 | kmemleak_stop("Cannot allocate a kmemleak_object structure\n"); |
471 | "structure\n"); | ||
472 | return; | 446 | return; |
473 | } | 447 | } |
474 | 448 | ||
@@ -527,8 +501,8 @@ static void create_object(unsigned long ptr, size_t size, int min_count, | |||
527 | if (node != &object->tree_node) { | 501 | if (node != &object->tree_node) { |
528 | unsigned long flags; | 502 | unsigned long flags; |
529 | 503 | ||
530 | kmemleak_stop("kmemleak: Cannot insert 0x%lx into the object " | 504 | kmemleak_stop("Cannot insert 0x%lx into the object search tree " |
531 | "search tree (already existing)\n", ptr); | 505 | "(already existing)\n", ptr); |
532 | object = lookup_object(ptr, 1); | 506 | object = lookup_object(ptr, 1); |
533 | spin_lock_irqsave(&object->lock, flags); | 507 | spin_lock_irqsave(&object->lock, flags); |
534 | dump_object_info(object); | 508 | dump_object_info(object); |
@@ -553,8 +527,10 @@ static void delete_object(unsigned long ptr) | |||
553 | write_lock_irqsave(&kmemleak_lock, flags); | 527 | write_lock_irqsave(&kmemleak_lock, flags); |
554 | object = lookup_object(ptr, 0); | 528 | object = lookup_object(ptr, 0); |
555 | if (!object) { | 529 | if (!object) { |
556 | kmemleak_warn("kmemleak: Freeing unknown object at 0x%08lx\n", | 530 | #ifdef DEBUG |
531 | kmemleak_warn("Freeing unknown object at 0x%08lx\n", | ||
557 | ptr); | 532 | ptr); |
533 | #endif | ||
558 | write_unlock_irqrestore(&kmemleak_lock, flags); | 534 | write_unlock_irqrestore(&kmemleak_lock, flags); |
559 | return; | 535 | return; |
560 | } | 536 | } |
@@ -570,8 +546,6 @@ static void delete_object(unsigned long ptr) | |||
570 | * cannot be freed when it is being scanned. | 546 | * cannot be freed when it is being scanned. |
571 | */ | 547 | */ |
572 | spin_lock_irqsave(&object->lock, flags); | 548 | spin_lock_irqsave(&object->lock, flags); |
573 | if (object->flags & OBJECT_REPORTED) | ||
574 | print_referenced(object); | ||
575 | object->flags &= ~OBJECT_ALLOCATED; | 549 | object->flags &= ~OBJECT_ALLOCATED; |
576 | spin_unlock_irqrestore(&object->lock, flags); | 550 | spin_unlock_irqrestore(&object->lock, flags); |
577 | put_object(object); | 551 | put_object(object); |
@@ -588,8 +562,7 @@ static void make_gray_object(unsigned long ptr) | |||
588 | 562 | ||
589 | object = find_and_get_object(ptr, 0); | 563 | object = find_and_get_object(ptr, 0); |
590 | if (!object) { | 564 | if (!object) { |
591 | kmemleak_warn("kmemleak: Graying unknown object at 0x%08lx\n", | 565 | kmemleak_warn("Graying unknown object at 0x%08lx\n", ptr); |
592 | ptr); | ||
593 | return; | 566 | return; |
594 | } | 567 | } |
595 | 568 | ||
@@ -610,8 +583,7 @@ static void make_black_object(unsigned long ptr) | |||
610 | 583 | ||
611 | object = find_and_get_object(ptr, 0); | 584 | object = find_and_get_object(ptr, 0); |
612 | if (!object) { | 585 | if (!object) { |
613 | kmemleak_warn("kmemleak: Blacking unknown object at 0x%08lx\n", | 586 | kmemleak_warn("Blacking unknown object at 0x%08lx\n", ptr); |
614 | ptr); | ||
615 | return; | 587 | return; |
616 | } | 588 | } |
617 | 589 | ||
@@ -634,21 +606,20 @@ static void add_scan_area(unsigned long ptr, unsigned long offset, | |||
634 | 606 | ||
635 | object = find_and_get_object(ptr, 0); | 607 | object = find_and_get_object(ptr, 0); |
636 | if (!object) { | 608 | if (!object) { |
637 | kmemleak_warn("kmemleak: Adding scan area to unknown " | 609 | kmemleak_warn("Adding scan area to unknown object at 0x%08lx\n", |
638 | "object at 0x%08lx\n", ptr); | 610 | ptr); |
639 | return; | 611 | return; |
640 | } | 612 | } |
641 | 613 | ||
642 | area = kmem_cache_alloc(scan_area_cache, gfp & GFP_KMEMLEAK_MASK); | 614 | area = kmem_cache_alloc(scan_area_cache, gfp & GFP_KMEMLEAK_MASK); |
643 | if (!area) { | 615 | if (!area) { |
644 | kmemleak_warn("kmemleak: Cannot allocate a scan area\n"); | 616 | kmemleak_warn("Cannot allocate a scan area\n"); |
645 | goto out; | 617 | goto out; |
646 | } | 618 | } |
647 | 619 | ||
648 | spin_lock_irqsave(&object->lock, flags); | 620 | spin_lock_irqsave(&object->lock, flags); |
649 | if (offset + length > object->size) { | 621 | if (offset + length > object->size) { |
650 | kmemleak_warn("kmemleak: Scan area larger than object " | 622 | kmemleak_warn("Scan area larger than object 0x%08lx\n", ptr); |
651 | "0x%08lx\n", ptr); | ||
652 | dump_object_info(object); | 623 | dump_object_info(object); |
653 | kmem_cache_free(scan_area_cache, area); | 624 | kmem_cache_free(scan_area_cache, area); |
654 | goto out_unlock; | 625 | goto out_unlock; |
@@ -677,8 +648,7 @@ static void object_no_scan(unsigned long ptr) | |||
677 | 648 | ||
678 | object = find_and_get_object(ptr, 0); | 649 | object = find_and_get_object(ptr, 0); |
679 | if (!object) { | 650 | if (!object) { |
680 | kmemleak_warn("kmemleak: Not scanning unknown object at " | 651 | kmemleak_warn("Not scanning unknown object at 0x%08lx\n", ptr); |
681 | "0x%08lx\n", ptr); | ||
682 | return; | 652 | return; |
683 | } | 653 | } |
684 | 654 | ||
@@ -699,7 +669,8 @@ static void log_early(int op_type, const void *ptr, size_t size, | |||
699 | struct early_log *log; | 669 | struct early_log *log; |
700 | 670 | ||
701 | if (crt_early_log >= ARRAY_SIZE(early_log)) { | 671 | if (crt_early_log >= ARRAY_SIZE(early_log)) { |
702 | kmemleak_stop("kmemleak: Early log buffer exceeded\n"); | 672 | pr_warning("Early log buffer exceeded\n"); |
673 | kmemleak_disable(); | ||
703 | return; | 674 | return; |
704 | } | 675 | } |
705 | 676 | ||
@@ -811,21 +782,6 @@ void kmemleak_no_scan(const void *ptr) | |||
811 | EXPORT_SYMBOL(kmemleak_no_scan); | 782 | EXPORT_SYMBOL(kmemleak_no_scan); |
812 | 783 | ||
813 | /* | 784 | /* |
814 | * Yield the CPU so that other tasks get a chance to run. The yielding is | ||
815 | * rate-limited to avoid excessive number of calls to the schedule() function | ||
816 | * during memory scanning. | ||
817 | */ | ||
818 | static void scan_yield(void) | ||
819 | { | ||
820 | might_sleep(); | ||
821 | |||
822 | if (time_is_before_eq_jiffies(next_scan_yield)) { | ||
823 | schedule(); | ||
824 | next_scan_yield = jiffies + jiffies_scan_yield; | ||
825 | } | ||
826 | } | ||
827 | |||
828 | /* | ||
829 | * Memory scanning is a long process and it needs to be interruptable. This | 785 | * Memory scanning is a long process and it needs to be interruptable. This |
830 | * function checks whether such interrupt condition occured. | 786 | * function checks whether such interrupt condition occured. |
831 | */ | 787 | */ |
@@ -865,15 +821,6 @@ static void scan_block(void *_start, void *_end, | |||
865 | if (scan_should_stop()) | 821 | if (scan_should_stop()) |
866 | break; | 822 | break; |
867 | 823 | ||
868 | /* | ||
869 | * When scanning a memory block with a corresponding | ||
870 | * kmemleak_object, the CPU yielding is handled in the calling | ||
871 | * code since it holds the object->lock to avoid the block | ||
872 | * freeing. | ||
873 | */ | ||
874 | if (!scanned) | ||
875 | scan_yield(); | ||
876 | |||
877 | object = find_and_get_object(pointer, 1); | 824 | object = find_and_get_object(pointer, 1); |
878 | if (!object) | 825 | if (!object) |
879 | continue; | 826 | continue; |
@@ -955,6 +902,9 @@ static void kmemleak_scan(void) | |||
955 | struct kmemleak_object *object, *tmp; | 902 | struct kmemleak_object *object, *tmp; |
956 | struct task_struct *task; | 903 | struct task_struct *task; |
957 | int i; | 904 | int i; |
905 | int new_leaks = 0; | ||
906 | |||
907 | jiffies_last_scan = jiffies; | ||
958 | 908 | ||
959 | /* prepare the kmemleak_object's */ | 909 | /* prepare the kmemleak_object's */ |
960 | rcu_read_lock(); | 910 | rcu_read_lock(); |
@@ -966,7 +916,7 @@ static void kmemleak_scan(void) | |||
966 | * 1 reference to any object at this point. | 916 | * 1 reference to any object at this point. |
967 | */ | 917 | */ |
968 | if (atomic_read(&object->use_count) > 1) { | 918 | if (atomic_read(&object->use_count) > 1) { |
969 | pr_debug("kmemleak: object->use_count = %d\n", | 919 | pr_debug("object->use_count = %d\n", |
970 | atomic_read(&object->use_count)); | 920 | atomic_read(&object->use_count)); |
971 | dump_object_info(object); | 921 | dump_object_info(object); |
972 | } | 922 | } |
@@ -1036,7 +986,7 @@ static void kmemleak_scan(void) | |||
1036 | */ | 986 | */ |
1037 | object = list_entry(gray_list.next, typeof(*object), gray_list); | 987 | object = list_entry(gray_list.next, typeof(*object), gray_list); |
1038 | while (&object->gray_list != &gray_list) { | 988 | while (&object->gray_list != &gray_list) { |
1039 | scan_yield(); | 989 | cond_resched(); |
1040 | 990 | ||
1041 | /* may add new objects to the list */ | 991 | /* may add new objects to the list */ |
1042 | if (!scan_should_stop()) | 992 | if (!scan_should_stop()) |
@@ -1052,6 +1002,32 @@ static void kmemleak_scan(void) | |||
1052 | object = tmp; | 1002 | object = tmp; |
1053 | } | 1003 | } |
1054 | WARN_ON(!list_empty(&gray_list)); | 1004 | WARN_ON(!list_empty(&gray_list)); |
1005 | |||
1006 | /* | ||
1007 | * If scanning was stopped do not report any new unreferenced objects. | ||
1008 | */ | ||
1009 | if (scan_should_stop()) | ||
1010 | return; | ||
1011 | |||
1012 | /* | ||
1013 | * Scanning result reporting. | ||
1014 | */ | ||
1015 | rcu_read_lock(); | ||
1016 | list_for_each_entry_rcu(object, &object_list, object_list) { | ||
1017 | spin_lock_irqsave(&object->lock, flags); | ||
1018 | if (unreferenced_object(object) && | ||
1019 | !(object->flags & OBJECT_REPORTED)) { | ||
1020 | object->flags |= OBJECT_REPORTED; | ||
1021 | new_leaks++; | ||
1022 | } | ||
1023 | spin_unlock_irqrestore(&object->lock, flags); | ||
1024 | } | ||
1025 | rcu_read_unlock(); | ||
1026 | |||
1027 | if (new_leaks) | ||
1028 | pr_info("%d new suspected memory leaks (see " | ||
1029 | "/sys/kernel/debug/kmemleak)\n", new_leaks); | ||
1030 | |||
1055 | } | 1031 | } |
1056 | 1032 | ||
1057 | /* | 1033 | /* |
@@ -1062,7 +1038,7 @@ static int kmemleak_scan_thread(void *arg) | |||
1062 | { | 1038 | { |
1063 | static int first_run = 1; | 1039 | static int first_run = 1; |
1064 | 1040 | ||
1065 | pr_info("kmemleak: Automatic memory scanning thread started\n"); | 1041 | pr_info("Automatic memory scanning thread started\n"); |
1066 | 1042 | ||
1067 | /* | 1043 | /* |
1068 | * Wait before the first scan to allow the system to fully initialize. | 1044 | * Wait before the first scan to allow the system to fully initialize. |
@@ -1073,49 +1049,25 @@ static int kmemleak_scan_thread(void *arg) | |||
1073 | } | 1049 | } |
1074 | 1050 | ||
1075 | while (!kthread_should_stop()) { | 1051 | while (!kthread_should_stop()) { |
1076 | struct kmemleak_object *object; | ||
1077 | signed long timeout = jiffies_scan_wait; | 1052 | signed long timeout = jiffies_scan_wait; |
1078 | 1053 | ||
1079 | mutex_lock(&scan_mutex); | 1054 | mutex_lock(&scan_mutex); |
1080 | |||
1081 | kmemleak_scan(); | 1055 | kmemleak_scan(); |
1082 | reported_leaks = 0; | ||
1083 | |||
1084 | rcu_read_lock(); | ||
1085 | list_for_each_entry_rcu(object, &object_list, object_list) { | ||
1086 | unsigned long flags; | ||
1087 | |||
1088 | if (reported_leaks >= REPORTS_NR) | ||
1089 | break; | ||
1090 | spin_lock_irqsave(&object->lock, flags); | ||
1091 | if (!(object->flags & OBJECT_REPORTED) && | ||
1092 | unreferenced_object(object)) { | ||
1093 | print_unreferenced(NULL, object); | ||
1094 | object->flags |= OBJECT_REPORTED; | ||
1095 | reported_leaks++; | ||
1096 | } else if ((object->flags & OBJECT_REPORTED) && | ||
1097 | referenced_object(object)) { | ||
1098 | print_referenced(object); | ||
1099 | object->flags &= ~OBJECT_REPORTED; | ||
1100 | } | ||
1101 | spin_unlock_irqrestore(&object->lock, flags); | ||
1102 | } | ||
1103 | rcu_read_unlock(); | ||
1104 | |||
1105 | mutex_unlock(&scan_mutex); | 1056 | mutex_unlock(&scan_mutex); |
1057 | |||
1106 | /* wait before the next scan */ | 1058 | /* wait before the next scan */ |
1107 | while (timeout && !kthread_should_stop()) | 1059 | while (timeout && !kthread_should_stop()) |
1108 | timeout = schedule_timeout_interruptible(timeout); | 1060 | timeout = schedule_timeout_interruptible(timeout); |
1109 | } | 1061 | } |
1110 | 1062 | ||
1111 | pr_info("kmemleak: Automatic memory scanning thread ended\n"); | 1063 | pr_info("Automatic memory scanning thread ended\n"); |
1112 | 1064 | ||
1113 | return 0; | 1065 | return 0; |
1114 | } | 1066 | } |
1115 | 1067 | ||
1116 | /* | 1068 | /* |
1117 | * Start the automatic memory scanning thread. This function must be called | 1069 | * Start the automatic memory scanning thread. This function must be called |
1118 | * with the kmemleak_mutex held. | 1070 | * with the scan_mutex held. |
1119 | */ | 1071 | */ |
1120 | void start_scan_thread(void) | 1072 | void start_scan_thread(void) |
1121 | { | 1073 | { |
@@ -1123,14 +1075,14 @@ void start_scan_thread(void) | |||
1123 | return; | 1075 | return; |
1124 | scan_thread = kthread_run(kmemleak_scan_thread, NULL, "kmemleak"); | 1076 | scan_thread = kthread_run(kmemleak_scan_thread, NULL, "kmemleak"); |
1125 | if (IS_ERR(scan_thread)) { | 1077 | if (IS_ERR(scan_thread)) { |
1126 | pr_warning("kmemleak: Failed to create the scan thread\n"); | 1078 | pr_warning("Failed to create the scan thread\n"); |
1127 | scan_thread = NULL; | 1079 | scan_thread = NULL; |
1128 | } | 1080 | } |
1129 | } | 1081 | } |
1130 | 1082 | ||
1131 | /* | 1083 | /* |
1132 | * Stop the automatic memory scanning thread. This function must be called | 1084 | * Stop the automatic memory scanning thread. This function must be called |
1133 | * with the kmemleak_mutex held. | 1085 | * with the scan_mutex held. |
1134 | */ | 1086 | */ |
1135 | void stop_scan_thread(void) | 1087 | void stop_scan_thread(void) |
1136 | { | 1088 | { |
@@ -1150,10 +1102,8 @@ static void *kmemleak_seq_start(struct seq_file *seq, loff_t *pos) | |||
1150 | struct kmemleak_object *object; | 1102 | struct kmemleak_object *object; |
1151 | loff_t n = *pos; | 1103 | loff_t n = *pos; |
1152 | 1104 | ||
1153 | if (!n) { | 1105 | if (!n) |
1154 | kmemleak_scan(); | ||
1155 | reported_leaks = 0; | 1106 | reported_leaks = 0; |
1156 | } | ||
1157 | if (reported_leaks >= REPORTS_NR) | 1107 | if (reported_leaks >= REPORTS_NR) |
1158 | return NULL; | 1108 | return NULL; |
1159 | 1109 | ||
@@ -1214,11 +1164,10 @@ static int kmemleak_seq_show(struct seq_file *seq, void *v) | |||
1214 | unsigned long flags; | 1164 | unsigned long flags; |
1215 | 1165 | ||
1216 | spin_lock_irqsave(&object->lock, flags); | 1166 | spin_lock_irqsave(&object->lock, flags); |
1217 | if (!unreferenced_object(object)) | 1167 | if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object)) { |
1218 | goto out; | 1168 | print_unreferenced(seq, object); |
1219 | print_unreferenced(seq, object); | 1169 | reported_leaks++; |
1220 | reported_leaks++; | 1170 | } |
1221 | out: | ||
1222 | spin_unlock_irqrestore(&object->lock, flags); | 1171 | spin_unlock_irqrestore(&object->lock, flags); |
1223 | return 0; | 1172 | return 0; |
1224 | } | 1173 | } |
@@ -1237,13 +1186,10 @@ static int kmemleak_open(struct inode *inode, struct file *file) | |||
1237 | if (!atomic_read(&kmemleak_enabled)) | 1186 | if (!atomic_read(&kmemleak_enabled)) |
1238 | return -EBUSY; | 1187 | return -EBUSY; |
1239 | 1188 | ||
1240 | ret = mutex_lock_interruptible(&kmemleak_mutex); | 1189 | ret = mutex_lock_interruptible(&scan_mutex); |
1241 | if (ret < 0) | 1190 | if (ret < 0) |
1242 | goto out; | 1191 | goto out; |
1243 | if (file->f_mode & FMODE_READ) { | 1192 | if (file->f_mode & FMODE_READ) { |
1244 | ret = mutex_lock_interruptible(&scan_mutex); | ||
1245 | if (ret < 0) | ||
1246 | goto kmemleak_unlock; | ||
1247 | ret = seq_open(file, &kmemleak_seq_ops); | 1193 | ret = seq_open(file, &kmemleak_seq_ops); |
1248 | if (ret < 0) | 1194 | if (ret < 0) |
1249 | goto scan_unlock; | 1195 | goto scan_unlock; |
@@ -1252,8 +1198,6 @@ static int kmemleak_open(struct inode *inode, struct file *file) | |||
1252 | 1198 | ||
1253 | scan_unlock: | 1199 | scan_unlock: |
1254 | mutex_unlock(&scan_mutex); | 1200 | mutex_unlock(&scan_mutex); |
1255 | kmemleak_unlock: | ||
1256 | mutex_unlock(&kmemleak_mutex); | ||
1257 | out: | 1201 | out: |
1258 | return ret; | 1202 | return ret; |
1259 | } | 1203 | } |
@@ -1262,11 +1206,9 @@ static int kmemleak_release(struct inode *inode, struct file *file) | |||
1262 | { | 1206 | { |
1263 | int ret = 0; | 1207 | int ret = 0; |
1264 | 1208 | ||
1265 | if (file->f_mode & FMODE_READ) { | 1209 | if (file->f_mode & FMODE_READ) |
1266 | seq_release(inode, file); | 1210 | seq_release(inode, file); |
1267 | mutex_unlock(&scan_mutex); | 1211 | mutex_unlock(&scan_mutex); |
1268 | } | ||
1269 | mutex_unlock(&kmemleak_mutex); | ||
1270 | 1212 | ||
1271 | return ret; | 1213 | return ret; |
1272 | } | 1214 | } |
@@ -1281,6 +1223,7 @@ static int kmemleak_release(struct inode *inode, struct file *file) | |||
1281 | * scan=off - stop the automatic memory scanning thread | 1223 | * scan=off - stop the automatic memory scanning thread |
1282 | * scan=... - set the automatic memory scanning period in seconds (0 to | 1224 | * scan=... - set the automatic memory scanning period in seconds (0 to |
1283 | * disable it) | 1225 | * disable it) |
1226 | * scan - trigger a memory scan | ||
1284 | */ | 1227 | */ |
1285 | static ssize_t kmemleak_write(struct file *file, const char __user *user_buf, | 1228 | static ssize_t kmemleak_write(struct file *file, const char __user *user_buf, |
1286 | size_t size, loff_t *ppos) | 1229 | size_t size, loff_t *ppos) |
@@ -1318,7 +1261,9 @@ static ssize_t kmemleak_write(struct file *file, const char __user *user_buf, | |||
1318 | jiffies_scan_wait = msecs_to_jiffies(secs * 1000); | 1261 | jiffies_scan_wait = msecs_to_jiffies(secs * 1000); |
1319 | start_scan_thread(); | 1262 | start_scan_thread(); |
1320 | } | 1263 | } |
1321 | } else | 1264 | } else if (strncmp(buf, "scan", 4) == 0) |
1265 | kmemleak_scan(); | ||
1266 | else | ||
1322 | return -EINVAL; | 1267 | return -EINVAL; |
1323 | 1268 | ||
1324 | /* ignore the rest of the buffer, only one command at a time */ | 1269 | /* ignore the rest of the buffer, only one command at a time */ |
@@ -1343,11 +1288,9 @@ static int kmemleak_cleanup_thread(void *arg) | |||
1343 | { | 1288 | { |
1344 | struct kmemleak_object *object; | 1289 | struct kmemleak_object *object; |
1345 | 1290 | ||
1346 | mutex_lock(&kmemleak_mutex); | 1291 | mutex_lock(&scan_mutex); |
1347 | stop_scan_thread(); | 1292 | stop_scan_thread(); |
1348 | mutex_unlock(&kmemleak_mutex); | ||
1349 | 1293 | ||
1350 | mutex_lock(&scan_mutex); | ||
1351 | rcu_read_lock(); | 1294 | rcu_read_lock(); |
1352 | list_for_each_entry_rcu(object, &object_list, object_list) | 1295 | list_for_each_entry_rcu(object, &object_list, object_list) |
1353 | delete_object(object->pointer); | 1296 | delete_object(object->pointer); |
@@ -1367,7 +1310,7 @@ static void kmemleak_cleanup(void) | |||
1367 | cleanup_thread = kthread_run(kmemleak_cleanup_thread, NULL, | 1310 | cleanup_thread = kthread_run(kmemleak_cleanup_thread, NULL, |
1368 | "kmemleak-clean"); | 1311 | "kmemleak-clean"); |
1369 | if (IS_ERR(cleanup_thread)) | 1312 | if (IS_ERR(cleanup_thread)) |
1370 | pr_warning("kmemleak: Failed to create the clean-up thread\n"); | 1313 | pr_warning("Failed to create the clean-up thread\n"); |
1371 | } | 1314 | } |
1372 | 1315 | ||
1373 | /* | 1316 | /* |
@@ -1414,7 +1357,6 @@ void __init kmemleak_init(void) | |||
1414 | int i; | 1357 | int i; |
1415 | unsigned long flags; | 1358 | unsigned long flags; |
1416 | 1359 | ||
1417 | jiffies_scan_yield = msecs_to_jiffies(MSECS_SCAN_YIELD); | ||
1418 | jiffies_min_age = msecs_to_jiffies(MSECS_MIN_AGE); | 1360 | jiffies_min_age = msecs_to_jiffies(MSECS_MIN_AGE); |
1419 | jiffies_scan_wait = msecs_to_jiffies(SECS_SCAN_WAIT * 1000); | 1361 | jiffies_scan_wait = msecs_to_jiffies(SECS_SCAN_WAIT * 1000); |
1420 | 1362 | ||
@@ -1488,11 +1430,10 @@ static int __init kmemleak_late_init(void) | |||
1488 | dentry = debugfs_create_file("kmemleak", S_IRUGO, NULL, NULL, | 1430 | dentry = debugfs_create_file("kmemleak", S_IRUGO, NULL, NULL, |
1489 | &kmemleak_fops); | 1431 | &kmemleak_fops); |
1490 | if (!dentry) | 1432 | if (!dentry) |
1491 | pr_warning("kmemleak: Failed to create the debugfs kmemleak " | 1433 | pr_warning("Failed to create the debugfs kmemleak file\n"); |
1492 | "file\n"); | 1434 | mutex_lock(&scan_mutex); |
1493 | mutex_lock(&kmemleak_mutex); | ||
1494 | start_scan_thread(); | 1435 | start_scan_thread(); |
1495 | mutex_unlock(&kmemleak_mutex); | 1436 | mutex_unlock(&scan_mutex); |
1496 | 1437 | ||
1497 | pr_info("Kernel memory leak detector initialized\n"); | 1438 | pr_info("Kernel memory leak detector initialized\n"); |
1498 | 1439 | ||