aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2018-04-06 06:41:18 -0400
committerIngo Molnar <mingo@kernel.org>2018-05-14 03:15:02 -0400
commit0f736a52e4be86476eec1d5adbcbd9c2809ac4b4 (patch)
treed1a995699c621493e9e7e45c0bf64d404b3c26aa /kernel
parent12e2c41148a9e68bc3b261954961db9d28decf47 (diff)
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: 4449a51a7c281602 ("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 <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/1523011279-8206-1-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/locking/lockdep.c43
1 files changed, 8 insertions, 35 deletions
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 023386338269..94f4d21ff66d 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -4451,8 +4451,6 @@ EXPORT_SYMBOL_GPL(debug_check_no_locks_held);
4451void debug_show_all_locks(void) 4451void debug_show_all_locks(void)
4452{ 4452{
4453 struct task_struct *g, *p; 4453 struct task_struct *g, *p;
4454 int count = 10;
4455 int unlock = 1;
4456 4454
4457 if (unlikely(!debug_locks)) { 4455 if (unlikely(!debug_locks)) {
4458 pr_warn("INFO: lockdep is turned off.\n"); 4456 pr_warn("INFO: lockdep is turned off.\n");
@@ -4460,30 +4458,8 @@ void debug_show_all_locks(void)
4460 } 4458 }
4461 pr_warn("\nShowing all locks held in the system:\n"); 4459 pr_warn("\nShowing all locks held in the system:\n");
4462 4460
4463 /* 4461 rcu_read_lock();
4464 * Here we try to get the tasklist_lock as hard as possible, 4462 for_each_process_thread(g, p) {
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 */
4469retry:
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) {
4487 /* 4463 /*
4488 * It's not reliable to print a task's held locks 4464 * It's not reliable to print a task's held locks
4489 * if it's not sleeping (or if it's not the current 4465 * if it's not sleeping (or if it's not the current
@@ -4491,19 +4467,16 @@ retry:
4491 */ 4467 */
4492 if (p->state == TASK_RUNNING && p != current) 4468 if (p->state == TASK_RUNNING && p != current)
4493 continue; 4469 continue;
4494 if (p->lockdep_depth) 4470 if (!p->lockdep_depth)
4495 lockdep_print_held_locks(p); 4471 continue;
4496 if (!unlock) 4472 lockdep_print_held_locks(p);
4497 if (read_trylock(&tasklist_lock))
4498 unlock = 1;
4499 touch_nmi_watchdog(); 4473 touch_nmi_watchdog();
4500 } while_each_thread(g, p); 4474 touch_all_softlockup_watchdogs();
4475 }
4476 rcu_read_unlock();
4501 4477
4502 pr_warn("\n"); 4478 pr_warn("\n");
4503 pr_warn("=============================================\n\n"); 4479 pr_warn("=============================================\n\n");
4504
4505 if (unlock)
4506 read_unlock(&tasklist_lock);
4507} 4480}
4508EXPORT_SYMBOL_GPL(debug_show_all_locks); 4481EXPORT_SYMBOL_GPL(debug_show_all_locks);
4509#endif 4482#endif