diff options
| author | Jan Engelmohr <jan.engelmohr@mailbox.tu-dresden.de> | 2016-09-04 16:45:09 +0200 |
|---|---|---|
| committer | Moyster <oysterized@gmail.com> | 2016-09-10 00:45:11 +0200 |
| commit | 0a1e8e11acd3cc36b1d65023ce1cb1a06a887b11 (patch) | |
| tree | bd92a01ee850567d86074cca3fb6c928c960fe39 /kernel/printk.c | |
| parent | ade0200dcde3ad70876875392b6bc156155b9b75 (diff) | |
3.10.102-> 3.10.103
Diffstat (limited to 'kernel/printk.c')
| -rw-r--r-- | kernel/printk.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index b30c61814..95cfcfd30 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -2161,7 +2161,7 @@ void console_unlock(void) static u64 seen_seq; unsigned long flags; bool wake_klogd = false; - bool retry; + bool do_cond_resched, retry; #ifdef LOG_TOO_MUCH_WARNING unsigned long total_log_size = 0; unsigned long long t1 = 0, t2 = 0; @@ -2174,6 +2174,18 @@ void console_unlock(void) return; } + /* + * Console drivers are called under logbuf_lock, so + * @console_may_schedule should be cleared before; however, we may + * end up dumping a lot of lines, for example, if called from + * console registration path, and should invoke cond_resched() + * between lines if allowable. Not doing so can cause a very long + * scheduling stall on a slow console leading to RCU stall and + * softlockup warnings which exacerbate the issue with more + * messages practically incapacitating the system. + */ + do_cond_resched = console_may_schedule; + console_may_schedule = 0; /* flush buffered message fragment immediately to console */ @@ -2269,6 +2281,8 @@ skip: call_console_drivers(level, text, len); #endif local_irq_restore(flags); + if (do_cond_resched) + cond_resched(); } console_locked = 0; mutex_release(&console_lock_dep_map, 1, _RET_IP_); @@ -2337,6 +2351,25 @@ void console_unblank(void) console_unlock(); } +/** + * console_flush_on_panic - flush console content on panic + * + * Immediately output all pending messages no matter what. + */ +void console_flush_on_panic(void) +{ + /* + * If someone else is holding the console lock, trylock will fail + * and may_schedule may be set. Ignore and proceed to unlock so + * that messages are flushed out. As this can be called from any + * context and we don't want to get preempted while flushing, + * ensure may_schedule is cleared. + */ + console_trylock(); + console_may_schedule = 0; + console_unlock(); +} + /* * Return the console tty driver structure and its associated index */ |
