aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2009-07-07 05:32:58 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2009-07-08 09:25:13 -0400
commit2587362eaf5c9df4e08de11e6340e3c4a88ed4c8 (patch)
tree90fc902a3c131146981164b859ed009d20157333 /mm
parentb87324d082d9d898e3c06b2a07a2b94b2430b8ba (diff)
kmemleak: Scan objects allocated during a scanning episode
Many of the false positives in kmemleak happen on busy systems where objects are allocated during a kmemleak scanning episode. These objects aren't scanned by default until the next memory scan. When such object is added, for example, at the head of a list, it is possible that all the other objects in the list become unreferenced until the next scan. This patch adds checking for newly allocated objects at the end of the scan and repeats the scanning on these objects. If Linux allocates new objects at a higher rate than their scanning, it stops after a predefined number of passes. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'mm')
-rw-r--r--mm/kmemleak.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 7cfb7d014a20..466d39007264 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -106,6 +106,7 @@
106#define MSECS_MIN_AGE 5000 /* minimum object age for reporting */ 106#define MSECS_MIN_AGE 5000 /* minimum object age for reporting */
107#define SECS_FIRST_SCAN 60 /* delay before the first scan */ 107#define SECS_FIRST_SCAN 60 /* delay before the first scan */
108#define SECS_SCAN_WAIT 600 /* subsequent auto scanning delay */ 108#define SECS_SCAN_WAIT 600 /* subsequent auto scanning delay */
109#define GRAY_LIST_PASSES 25 /* maximum number of gray list scans */
109 110
110#define BYTES_PER_POINTER sizeof(void *) 111#define BYTES_PER_POINTER sizeof(void *)
111 112
@@ -157,6 +158,8 @@ struct kmemleak_object {
157#define OBJECT_REPORTED (1 << 1) 158#define OBJECT_REPORTED (1 << 1)
158/* flag set to not scan the object */ 159/* flag set to not scan the object */
159#define OBJECT_NO_SCAN (1 << 2) 160#define OBJECT_NO_SCAN (1 << 2)
161/* flag set on newly allocated objects */
162#define OBJECT_NEW (1 << 3)
160 163
161/* the list of all allocated objects */ 164/* the list of all allocated objects */
162static LIST_HEAD(object_list); 165static LIST_HEAD(object_list);
@@ -270,6 +273,11 @@ static int color_gray(const struct kmemleak_object *object)
270 return object->min_count != -1 && object->count >= object->min_count; 273 return object->min_count != -1 && object->count >= object->min_count;
271} 274}
272 275
276static int color_black(const struct kmemleak_object *object)
277{
278 return object->min_count == -1;
279}
280
273/* 281/*
274 * 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
275 * 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
@@ -447,7 +455,7 @@ static void create_object(unsigned long ptr, size_t size, int min_count,
447 INIT_HLIST_HEAD(&object->area_list); 455 INIT_HLIST_HEAD(&object->area_list);
448 spin_lock_init(&object->lock); 456 spin_lock_init(&object->lock);
449 atomic_set(&object->use_count, 1); 457 atomic_set(&object->use_count, 1);
450 object->flags = OBJECT_ALLOCATED; 458 object->flags = OBJECT_ALLOCATED | OBJECT_NEW;
451 object->pointer = ptr; 459 object->pointer = ptr;
452 object->size = size; 460 object->size = size;
453 object->min_count = min_count; 461 object->min_count = min_count;
@@ -901,6 +909,7 @@ static void kmemleak_scan(void)
901 struct task_struct *task; 909 struct task_struct *task;
902 int i; 910 int i;
903 int new_leaks = 0; 911 int new_leaks = 0;
912 int gray_list_pass = 0;
904 913
905 jiffies_last_scan = jiffies; 914 jiffies_last_scan = jiffies;
906 915
@@ -921,6 +930,7 @@ static void kmemleak_scan(void)
921#endif 930#endif
922 /* reset the reference count (whiten the object) */ 931 /* reset the reference count (whiten the object) */
923 object->count = 0; 932 object->count = 0;
933 object->flags &= ~OBJECT_NEW;
924 if (color_gray(object) && get_object(object)) 934 if (color_gray(object) && get_object(object))
925 list_add_tail(&object->gray_list, &gray_list); 935 list_add_tail(&object->gray_list, &gray_list);
926 936
@@ -983,6 +993,7 @@ static void kmemleak_scan(void)
983 * kmemleak objects cannot be freed from outside the loop because their 993 * kmemleak objects cannot be freed from outside the loop because their
984 * use_count was increased. 994 * use_count was increased.
985 */ 995 */
996repeat:
986 object = list_entry(gray_list.next, typeof(*object), gray_list); 997 object = list_entry(gray_list.next, typeof(*object), gray_list);
987 while (&object->gray_list != &gray_list) { 998 while (&object->gray_list != &gray_list) {
988 cond_resched(); 999 cond_resched();
@@ -1000,12 +1011,38 @@ static void kmemleak_scan(void)
1000 1011
1001 object = tmp; 1012 object = tmp;
1002 } 1013 }
1014
1015 if (scan_should_stop() || ++gray_list_pass >= GRAY_LIST_PASSES)
1016 goto scan_end;
1017
1018 /*
1019 * Check for new objects allocated during this scanning and add them
1020 * to the gray list.
1021 */
1022 rcu_read_lock();
1023 list_for_each_entry_rcu(object, &object_list, object_list) {
1024 spin_lock_irqsave(&object->lock, flags);
1025 if ((object->flags & OBJECT_NEW) && !color_black(object) &&
1026 get_object(object)) {
1027 object->flags &= ~OBJECT_NEW;
1028 list_add_tail(&object->gray_list, &gray_list);
1029 }
1030 spin_unlock_irqrestore(&object->lock, flags);
1031 }
1032 rcu_read_unlock();
1033
1034 if (!list_empty(&gray_list))
1035 goto repeat;
1036
1037scan_end:
1003 WARN_ON(!list_empty(&gray_list)); 1038 WARN_ON(!list_empty(&gray_list));
1004 1039
1005 /* 1040 /*
1006 * If scanning was stopped do not report any new unreferenced objects. 1041 * If scanning was stopped or new objects were being allocated at a
1042 * higher rate than gray list scanning, do not report any new
1043 * unreferenced objects.
1007 */ 1044 */
1008 if (scan_should_stop()) 1045 if (scan_should_stop() || gray_list_pass >= GRAY_LIST_PASSES)
1009 return; 1046 return;
1010 1047
1011 /* 1048 /*