diff options
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r-- | kernel/sched/core.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index a7c6069ddf9d..0a27cb8f72a9 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -9493,6 +9493,18 @@ void __might_sleep(const char *file, int line) } EXPORT_SYMBOL(__might_sleep); +static void print_preempt_disable_ip(int preempt_offset, unsigned long ip) +{ + if (!IS_ENABLED(CONFIG_DEBUG_PREEMPT)) + return; + + if (preempt_count() == preempt_offset) + return; + + pr_err("Preemption disabled at:"); + print_ip_sym(KERN_ERR, ip); +} + void __might_resched(const char *file, int line, int preempt_offset) { /* Ratelimiting timestamp: */ @@ -9521,6 +9533,13 @@ void __might_resched(const char *file, int line, int preempt_offset) pr_err("in_atomic(): %d, irqs_disabled(): %d, non_block: %d, pid: %d, name: %s\n", in_atomic(), irqs_disabled(), current->non_block_count, current->pid, current->comm); + pr_err("preempt_count: %x, expected: %x\n", preempt_count(), + preempt_offset); + + if (IS_ENABLED(CONFIG_PREEMPT_RCU)) { + pr_err("RCU nest depth: %d, expected: 0\n", + rcu_preempt_depth()); + } if (task_stack_end_corrupted(current)) pr_emerg("Thread overran stack, or stack corrupted\n"); @@ -9528,11 +9547,9 @@ void __might_resched(const char *file, int line, int preempt_offset) debug_show_held_locks(current); if (irqs_disabled()) print_irqtrace_events(current); - if (IS_ENABLED(CONFIG_DEBUG_PREEMPT) - && !preempt_count_equals(preempt_offset)) { - pr_err("Preemption disabled at:"); - print_ip_sym(KERN_ERR, preempt_disable_ip); - } + + print_preempt_disable_ip(preempt_offset, preempt_disable_ip); + dump_stack(); add_taint(TAINT_WARN, LOCKDEP_STILL_OK); } |