diff options
author | Sasha Levin <sashal@kernel.org> | 2018-12-13 09:24:35 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-12-17 09:28:54 +0100 |
commit | 62582f67ff7617313b27b897ed02b569b712dcac (patch) | |
tree | 15a90baaa5bedf28ca68afccafb381987d956930 /kernel/printk | |
parent | 56926f913bf8284f0d33d79cdf0421f0caec8a1f (diff) |
Revert "printk: Never set console_may_schedule in console_trylock()"
This reverts commit c9b8d580b3fb0ab65d37c372aef19a318fda3199.
This is just a technical revert to make the printk fix apply cleanly,
this patch will be re-picked in about 3 commits.
Diffstat (limited to 'kernel/printk')
-rw-r--r-- | kernel/printk/printk.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index a9cf2e15f6a3..7161312593dd 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1763,19 +1763,12 @@ asmlinkage int vprintk_emit(int facility, int level, /* If called from the scheduler, we can not call up(). */ if (!in_sched) { /* - * Disable preemption to avoid being preempted while holding - * console_sem which would prevent anyone from printing to - * console - */ - preempt_disable(); - /* * Try to acquire and then immediately release the console * semaphore. The release will print out buffers and wake up * /dev/kmsg and syslog() users. */ if (console_trylock()) console_unlock(); - preempt_enable(); } return printed_len; @@ -2090,7 +2083,20 @@ int console_trylock(void) return 0; } console_locked = 1; - console_may_schedule = 0; + /* + * When PREEMPT_COUNT disabled we can't reliably detect if it's + * safe to schedule (e.g. calling printk while holding a spin_lock), + * because preempt_disable()/preempt_enable() are just barriers there + * and preempt_count() is always 0. + * + * RCU read sections have a separate preemption counter when + * PREEMPT_RCU enabled thus we must take extra care and check + * rcu_preempt_depth(), otherwise RCU read sections modify + * preempt_count(). + */ + console_may_schedule = !oops_in_progress && + preemptible() && + !rcu_preempt_depth(); return 1; } EXPORT_SYMBOL(console_trylock); |