aboutsummaryrefslogtreecommitdiffstats
path: root/mm/kmemleak.c
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2009-06-26 12:38:26 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2009-06-26 12:38:26 -0400
commitbab4a34afc301fdb81b6ea0e3098d96fc356e03a (patch)
treed9722d26dc944dbad1afd6dd182aa3a21907b96d /mm/kmemleak.c
parente0a2a1601bec01243bcad44414d06f59dae2eedb (diff)
kmemleak: Simplify the reports logged by the scanning thread
Because of false positives, the memory scanning thread may print too much information. This patch changes the scanning thread to only print the number of newly suspected leaks. Further information can be read from the /sys/kernel/debug/kmemleak file. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'mm/kmemleak.c')
-rw-r--r--mm/kmemleak.c61
1 files changed, 16 insertions, 45 deletions
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index a38418a95d33..4130a4889fa9 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -279,15 +279,6 @@ static int color_gray(const struct kmemleak_object *object)
279} 279}
280 280
281/* 281/*
282 * Objects are considered referenced if their color is gray and they have not
283 * been deleted.
284 */
285static int referenced_object(struct kmemleak_object *object)
286{
287 return (object->flags & OBJECT_ALLOCATED) && color_gray(object);
288}
289
290/*
291 * Objects are considered unreferenced only if their color is white, they have 282 * Objects are considered unreferenced only if their color is white, they have
292 * not be deleted and have a minimum age to avoid false positives caused by 283 * not be deleted and have a minimum age to avoid false positives caused by
293 * pointers temporarily stored in CPU registers. 284 * pointers temporarily stored in CPU registers.
@@ -299,38 +290,23 @@ static int unreferenced_object(struct kmemleak_object *object)
299} 290}
300 291
301/* 292/*
302 * Printing of the (un)referenced objects information, either to the seq file 293 * Printing of the unreferenced objects information to the seq file. The
303 * or to the kernel log. The print_referenced/print_unreferenced functions 294 * print_unreferenced function must be called with the object->lock held.
304 * must be called with the object->lock held.
305 */ 295 */
306#define print_helper(seq, x...) do { \
307 struct seq_file *s = (seq); \
308 if (s) \
309 seq_printf(s, x); \
310 else \
311 pr_info(x); \
312} while (0)
313
314static void print_referenced(struct kmemleak_object *object)
315{
316 pr_info("referenced object 0x%08lx (size %zu)\n",
317 object->pointer, object->size);
318}
319
320static void print_unreferenced(struct seq_file *seq, 296static void print_unreferenced(struct seq_file *seq,
321 struct kmemleak_object *object) 297 struct kmemleak_object *object)
322{ 298{
323 int i; 299 int i;
324 300
325 print_helper(seq, "unreferenced object 0x%08lx (size %zu):\n", 301 seq_printf(seq, "unreferenced object 0x%08lx (size %zu):\n",
326 object->pointer, object->size); 302 object->pointer, object->size);
327 print_helper(seq, " comm \"%s\", pid %d, jiffies %lu\n", 303 seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu\n",
328 object->comm, object->pid, object->jiffies); 304 object->comm, object->pid, object->jiffies);
329 print_helper(seq, " backtrace:\n"); 305 seq_printf(seq, " backtrace:\n");
330 306
331 for (i = 0; i < object->trace_len; i++) { 307 for (i = 0; i < object->trace_len; i++) {
332 void *ptr = (void *)object->trace[i]; 308 void *ptr = (void *)object->trace[i];
333 print_helper(seq, " [<%p>] %pS\n", ptr, ptr); 309 seq_printf(seq, " [<%p>] %pS\n", ptr, ptr);
334 } 310 }
335} 311}
336 312
@@ -571,8 +547,6 @@ static void delete_object(unsigned long ptr)
571 * cannot be freed when it is being scanned. 547 * cannot be freed when it is being scanned.
572 */ 548 */
573 spin_lock_irqsave(&object->lock, flags); 549 spin_lock_irqsave(&object->lock, flags);
574 if (object->flags & OBJECT_REPORTED)
575 print_referenced(object);
576 object->flags &= ~OBJECT_ALLOCATED; 550 object->flags &= ~OBJECT_ALLOCATED;
577 spin_unlock_irqrestore(&object->lock, flags); 551 spin_unlock_irqrestore(&object->lock, flags);
578 put_object(object); 552 put_object(object);
@@ -1073,33 +1047,30 @@ static int kmemleak_scan_thread(void *arg)
1073 while (!kthread_should_stop()) { 1047 while (!kthread_should_stop()) {
1074 struct kmemleak_object *object; 1048 struct kmemleak_object *object;
1075 signed long timeout = jiffies_scan_wait; 1049 signed long timeout = jiffies_scan_wait;
1050 int new_leaks = 0;
1076 1051
1077 mutex_lock(&scan_mutex); 1052 mutex_lock(&scan_mutex);
1078 1053
1079 kmemleak_scan(); 1054 kmemleak_scan();
1080 reported_leaks = 0;
1081 1055
1082 rcu_read_lock(); 1056 rcu_read_lock();
1083 list_for_each_entry_rcu(object, &object_list, object_list) { 1057 list_for_each_entry_rcu(object, &object_list, object_list) {
1084 unsigned long flags; 1058 unsigned long flags;
1085 1059
1086 if (reported_leaks >= REPORTS_NR)
1087 break;
1088 spin_lock_irqsave(&object->lock, flags); 1060 spin_lock_irqsave(&object->lock, flags);
1089 if (!(object->flags & OBJECT_REPORTED) && 1061 if (unreferenced_object(object) &&
1090 unreferenced_object(object)) { 1062 !(object->flags & OBJECT_REPORTED)) {
1091 print_unreferenced(NULL, object);
1092 object->flags |= OBJECT_REPORTED; 1063 object->flags |= OBJECT_REPORTED;
1093 reported_leaks++; 1064 new_leaks++;
1094 } else if ((object->flags & OBJECT_REPORTED) &&
1095 referenced_object(object)) {
1096 print_referenced(object);
1097 object->flags &= ~OBJECT_REPORTED;
1098 } 1065 }
1099 spin_unlock_irqrestore(&object->lock, flags); 1066 spin_unlock_irqrestore(&object->lock, flags);
1100 } 1067 }
1101 rcu_read_unlock(); 1068 rcu_read_unlock();
1102 1069
1070 if (new_leaks)
1071 pr_info("%d new suspected memory leaks (see "
1072 "/sys/kernel/debug/kmemleak)\n", new_leaks);
1073
1103 mutex_unlock(&scan_mutex); 1074 mutex_unlock(&scan_mutex);
1104 /* wait before the next scan */ 1075 /* wait before the next scan */
1105 while (timeout && !kthread_should_stop()) 1076 while (timeout && !kthread_should_stop())