|
@@ -1244,7 +1244,7 @@ void console_unlock(void)
|
|
|
{
|
|
|
unsigned long flags;
|
|
|
unsigned _con_start, _log_end;
|
|
|
- unsigned wake_klogd = 0;
|
|
|
+ unsigned wake_klogd = 0, retry = 0;
|
|
|
|
|
|
if (console_suspended) {
|
|
|
up(&console_sem);
|
|
@@ -1253,6 +1253,7 @@ void console_unlock(void)
|
|
|
|
|
|
console_may_schedule = 0;
|
|
|
|
|
|
+again:
|
|
|
for ( ; ; ) {
|
|
|
spin_lock_irqsave(&logbuf_lock, flags);
|
|
|
wake_klogd |= log_start - log_end;
|
|
@@ -1273,8 +1274,23 @@ void console_unlock(void)
|
|
|
if (unlikely(exclusive_console))
|
|
|
exclusive_console = NULL;
|
|
|
|
|
|
- spin_unlock_irqrestore(&logbuf_lock, flags);
|
|
|
+ spin_unlock(&logbuf_lock);
|
|
|
+
|
|
|
up(&console_sem);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Someone could have filled up the buffer again, so re-check if there's
|
|
|
+ * something to flush. In case we cannot trylock the console_sem again,
|
|
|
+ * there's a new owner and the console_unlock() from them will do the
|
|
|
+ * flush, no worries.
|
|
|
+ */
|
|
|
+ spin_lock(&logbuf_lock);
|
|
|
+ if (con_start != log_end)
|
|
|
+ retry = 1;
|
|
|
+ spin_unlock_irqrestore(&logbuf_lock, flags);
|
|
|
+ if (retry && console_trylock())
|
|
|
+ goto again;
|
|
|
+
|
|
|
if (wake_klogd)
|
|
|
wake_up_klogd();
|
|
|
}
|