http://lkml.indiana.edu/hypermail/linux/kernel/0907.2/00557.html This patch changes the for_each_process() loop with the do_each_thread()/while_each_thread() pair. It also replaces the read_lock(&tasklist_lock) with rcu_read_lock() and task_lock(p). Signed-off-by: Catalin Marinas <catalin.mari...@xxxxxxx> --- My questions: 1. Is it correct that for_each_process() used currently by kmemleak may not loop through all the possible kernel thread stacks? 2. Is it safe to use rcu_read_lock() and task_lock() when scanning the corresponding kernel stack (thread_info structure)? The loop doesn't do any modification to the task list. The reason for this is to allow kernel preemption when scanning the stacks. Alternatively, I can hook kmemleak callbacks into the alloc_thread_info/free_thread_info structures but many of these are architecture-specific. Thanks, Catalin mm/kmemleak.c | 17 ++++++++++------- 1 files changed, 10 insertions(+), 7 deletions(-) diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 983f3f6..a933128 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -1064,7 +1064,6 @@ static void kmemleak_scan(void) { unsigned long flags; struct kmemleak_object *object, *tmp; - struct task_struct *task; int i; int new_leaks = 0; int gray_list_pass = 0; @@ -1135,12 +1134,16 @@ static void kmemleak_scan(void) * not enabled by default. */ if (kmemleak_stack_scan) { - read_lock(&tasklist_lock); - for_each_process(task) - scan_block(task_stack_page(task), - task_stack_page(task) + THREAD_SIZE, - NULL, 0); - read_unlock(&tasklist_lock); + struct task_struct *p, *g; + + rcu_read_lock(); + do_each_thread(g, p) { + task_lock(p); + scan_block(task_stack_page(p), task_stack_page(p) + + THREAD_SIZE, NULL, 0); + task_unlock(p); + } while_each_thread(g, p); + rcu_read_unlock(); } /* |