aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/locking
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2018-04-06 06:41:19 -0400
committerIngo Molnar <mingo@kernel.org>2018-05-14 03:15:02 -0400
commit8cc05c71ba5f793690bb72aeb404dce65b5d4b52 (patch)
tree1a120bcc0d7129e9737e6979ab1aa9dd3546ee32 /kernel/locking
parent0f736a52e4be86476eec1d5adbcbd9c2809ac4b4 (diff)
locking/lockdep: Move sanity check to inside lockdep_print_held_locks()
Calling lockdep_print_held_locks() on a running thread is considered unsafe. Since all callers should follow that rule and the sanity check is not heavy, this patch moves the sanity check to inside lockdep_print_held_locks(). As a side effect of this patch, the number of locks held by running threads will be printed as well. This change will be preferable when we want to know which threads might be relevant to a problem but are unable to print any clues because that thread is running. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Matthew Wilcox <willy@infradead.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/1523011279-8206-2-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/locking')
-rw-r--r--kernel/locking/lockdep.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 94f4d21ff66d..edcac5de7ebc 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -561,20 +561,24 @@ static void print_lock(struct held_lock *hlock)
561 printk(KERN_CONT ", at: %pS\n", (void *)hlock->acquire_ip); 561 printk(KERN_CONT ", at: %pS\n", (void *)hlock->acquire_ip);
562} 562}
563 563
564static void lockdep_print_held_locks(struct task_struct *curr) 564static void lockdep_print_held_locks(struct task_struct *p)
565{ 565{
566 int i, depth = curr->lockdep_depth; 566 int i, depth = READ_ONCE(p->lockdep_depth);
567 567
568 if (!depth) { 568 if (!depth)
569 printk("no locks held by %s/%d.\n", curr->comm, task_pid_nr(curr)); 569 printk("no locks held by %s/%d.\n", p->comm, task_pid_nr(p));
570 else
571 printk("%d lock%s held by %s/%d:\n", depth,
572 depth > 1 ? "s" : "", p->comm, task_pid_nr(p));
573 /*
574 * It's not reliable to print a task's held locks if it's not sleeping
575 * and it's not the current task.
576 */
577 if (p->state == TASK_RUNNING && p != current)
570 return; 578 return;
571 }
572 printk("%d lock%s held by %s/%d:\n",
573 depth, depth > 1 ? "s" : "", curr->comm, task_pid_nr(curr));
574
575 for (i = 0; i < depth; i++) { 579 for (i = 0; i < depth; i++) {
576 printk(" #%d: ", i); 580 printk(" #%d: ", i);
577 print_lock(curr->held_locks + i); 581 print_lock(p->held_locks + i);
578 } 582 }
579} 583}
580 584
@@ -4460,13 +4464,6 @@ void debug_show_all_locks(void)
4460 4464
4461 rcu_read_lock(); 4465 rcu_read_lock();
4462 for_each_process_thread(g, p) { 4466 for_each_process_thread(g, p) {
4463 /*
4464 * It's not reliable to print a task's held locks
4465 * if it's not sleeping (or if it's not the current
4466 * task):
4467 */
4468 if (p->state == TASK_RUNNING && p != current)
4469 continue;
4470 if (!p->lockdep_depth) 4467 if (!p->lockdep_depth)
4471 continue; 4468 continue;
4472 lockdep_print_held_locks(p); 4469 lockdep_print_held_locks(p);