Skip to content

Commit 0f736a5

Browse files
Tetsuo HandaIngo Molnar
authored andcommitted
locking/lockdep: Use for_each_process_thread() for debug_show_all_locks()
debug_show_all_locks() tries to grab the tasklist_lock for two seconds, but calling while_each_thread() without tasklist_lock held is not safe. See the following commit for more information: 4449a51 ("vm_is_stack: use for_each_thread() rather then buggy while_each_thread()") Change debug_show_all_locks() from "do_each_thread()/while_each_thread() with possibility of missing tasklist_lock" to "for_each_process_thread() with RCU", and add a call to touch_all_softlockup_watchdogs() like show_state_filter() does. Signed-off-by: Tetsuo Handa <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Link: http://lkml.kernel.org/r/1523011279-8206-1-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp Signed-off-by: Ingo Molnar <[email protected]>
1 parent 12e2c41 commit 0f736a5

File tree

1 file changed

+8
-35
lines changed

1 file changed

+8
-35
lines changed

kernel/locking/lockdep.c

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4451,59 +4451,32 @@ EXPORT_SYMBOL_GPL(debug_check_no_locks_held);
44514451
void debug_show_all_locks(void)
44524452
{
44534453
struct task_struct *g, *p;
4454-
int count = 10;
4455-
int unlock = 1;
44564454

44574455
if (unlikely(!debug_locks)) {
44584456
pr_warn("INFO: lockdep is turned off.\n");
44594457
return;
44604458
}
44614459
pr_warn("\nShowing all locks held in the system:\n");
44624460

4463-
/*
4464-
* Here we try to get the tasklist_lock as hard as possible,
4465-
* if not successful after 2 seconds we ignore it (but keep
4466-
* trying). This is to enable a debug printout even if a
4467-
* tasklist_lock-holding task deadlocks or crashes.
4468-
*/
4469-
retry:
4470-
if (!read_trylock(&tasklist_lock)) {
4471-
if (count == 10)
4472-
pr_warn("hm, tasklist_lock locked, retrying... ");
4473-
if (count) {
4474-
count--;
4475-
pr_cont(" #%d", 10-count);
4476-
mdelay(200);
4477-
goto retry;
4478-
}
4479-
pr_cont(" ignoring it.\n");
4480-
unlock = 0;
4481-
} else {
4482-
if (count != 10)
4483-
pr_cont(" locked it.\n");
4484-
}
4485-
4486-
do_each_thread(g, p) {
4461+
rcu_read_lock();
4462+
for_each_process_thread(g, p) {
44874463
/*
44884464
* It's not reliable to print a task's held locks
44894465
* if it's not sleeping (or if it's not the current
44904466
* task):
44914467
*/
44924468
if (p->state == TASK_RUNNING && p != current)
44934469
continue;
4494-
if (p->lockdep_depth)
4495-
lockdep_print_held_locks(p);
4496-
if (!unlock)
4497-
if (read_trylock(&tasklist_lock))
4498-
unlock = 1;
4470+
if (!p->lockdep_depth)
4471+
continue;
4472+
lockdep_print_held_locks(p);
44994473
touch_nmi_watchdog();
4500-
} while_each_thread(g, p);
4474+
touch_all_softlockup_watchdogs();
4475+
}
4476+
rcu_read_unlock();
45014477

45024478
pr_warn("\n");
45034479
pr_warn("=============================================\n\n");
4504-
4505-
if (unlock)
4506-
read_unlock(&tasklist_lock);
45074480
}
45084481
EXPORT_SYMBOL_GPL(debug_show_all_locks);
45094482
#endif

0 commit comments

Comments
 (0)