History

locking/lockdep: Improve 'invalid wait context' splat

The 'invalid wait context' splat doesn't print all the information required to reconstruct / validate the error, specifically the irq-context state is missing.

Peter Zijlstra committed 6 years ago

Commit 9a019db1 parent a13f58a1 file · +31 −20Browse files

Unified · Split

kernel/locking/lockdep.c+31−20
@@ -3952,10 +3952,36 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, · 3951 unmodified lines
3952 return ret;3952 return ret;
3953}3953}
3954 3954
3955static inline short task_wait_context(struct task_struct *curr)
3956{
3957 /*
3958 * Set appropriate wait type for the context; for IRQs we have to take
3959 * into account force_irqthread as that is implied by PREEMPT_RT.
3960 */
3961 if (curr->hardirq_context) {
3962 /*
3963 * Check if force_irqthreads will run us threaded.
3964 */
3965 if (curr->hardirq_threaded || curr->irq_config)
3966 return LD_WAIT_CONFIG;
3967
3968 return LD_WAIT_SPIN;
3969 } else if (curr->softirq_context) {
3970 /*
3971 * Softirqs are always threaded.
3972 */
3973 return LD_WAIT_CONFIG;
3974 }
3975
3976 return LD_WAIT_MAX;
3977}
3978
3955static int3979static int
3956print_lock_invalid_wait_context(struct task_struct *curr,3980print_lock_invalid_wait_context(struct task_struct *curr,
3957 struct held_lock *hlock)3981 struct held_lock *hlock)
3958{3982{
3983 short curr_inner;
3984
3959 if (!debug_locks_off())3985 if (!debug_locks_off())
3960 return 0;3986 return 0;
3961 if (debug_locks_silent)3987 if (debug_locks_silent)
@@ -3971,6 +3997,10 @@ print_lock_invalid_wait_context(struct task_struct *curr, · 9 unmodified lines
3971 print_lock(hlock);3997 print_lock(hlock);
3972 3998
3973 pr_warn("other info that might help us debug this:\n");3999 pr_warn("other info that might help us debug this:\n");
4000
4001 curr_inner = task_wait_context(curr);
4002 pr_warn("context-{%d:%d}\n", curr_inner, curr_inner);
4003
3974 lockdep_print_held_locks(curr);4004 lockdep_print_held_locks(curr);
3975 4005
3976 pr_warn("stack backtrace:\n");4006 pr_warn("stack backtrace:\n");
@@ -4017,26 +4047,7 @@ static int check_wait_context(struct task_struct *curr, struct held_lock *next) · 40 unmodified lines
4017 }4047 }
4018 depth++;4048 depth++;
4019 4049
4020 /*4050 curr_inner = task_wait_context(curr);
4021 * Set appropriate wait type for the context; for IRQs we have to take
4022 * into account force_irqthread as that is implied by PREEMPT_RT.
4023 */
4024 if (curr->hardirq_context) {
4025 /*
4026 * Check if force_irqthreads will run us threaded.
4027 */
4028 if (curr->hardirq_threaded || curr->irq_config)
4029 curr_inner = LD_WAIT_CONFIG;
4030 else
4031 curr_inner = LD_WAIT_SPIN;
4032 } else if (curr->softirq_context) {
4033 /*
4034 * Softirqs are always threaded.
4035 */
4036 curr_inner = LD_WAIT_CONFIG;
4037 } else {
4038 curr_inner = LD_WAIT_MAX;
4039 }
4040 4051
4041 for (; depth < curr->lockdep_depth; depth++) {4052 for (; depth < curr->lockdep_depth; depth++) {
4042 struct held_lock *prev = curr->held_locks + depth;4053 struct held_lock *prev = curr->held_locks + depth;