aboutsummaryrefslogtreecommitdiff
path: root/kernel/printk.c
diff options
context:
space:
mode:
authorJan Engelmohr <jan.engelmohr@mailbox.tu-dresden.de>2016-09-04 16:45:09 +0200
committerMoyster <oysterized@gmail.com>2016-09-10 00:45:11 +0200
commit0a1e8e11acd3cc36b1d65023ce1cb1a06a887b11 (patch)
treebd92a01ee850567d86074cca3fb6c928c960fe39 /kernel/printk.c
parentade0200dcde3ad70876875392b6bc156155b9b75 (diff)
3.10.102-> 3.10.103
Diffstat (limited to 'kernel/printk.c')
-rw-r--r--kernel/printk.c35
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
*/