aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Senozhatsky <sergey.senozhatsky@gmail.com>2018-10-01 22:38:35 -0400
committerPetr Mladek <pmladek@suse.com>2018-10-12 04:03:39 -0400
commit3ac37a93fa9217e576bebfd4ba3e80edaaeb2289 (patch)
tree5ac022d5c88ad6842a498ed57d9de4cacd01a01b
parent9627808d2d409279cea3fb334212d04a83ff6371 (diff)
printk: lock/unlock console only for new logbuf entries
Prior to commit 5c2992ee7fd8a29 ("printk: remove console flushing special cases for partial buffered lines") we would do console_cont_flush() for each pr_cont() to print cont fragments, so console_unlock() would actually print data: pr_cont(); console_lock(); console_unlock() console_cont_flush(); // print cont fragment ... pr_cont(); console_lock(); console_unlock() console_cont_flush(); // print cont fragment We don't do console_cont_flush() anymore, so when we do pr_cont() console_unlock() does nothing (unless we flushed the cont buffer): pr_cont(); console_lock(); console_unlock(); // noop ... pr_cont(); console_lock(); console_unlock(); // noop ... pr_cont(); cont_flush(); console_lock(); console_unlock(); // print data We also wakeup klogd purposelessly for pr_cont() output - un-flushed cont buffer is not stored in log_buf; there is nothing to pull. Thus we can console_lock()/console_unlock()/wake_up_klogd() only when we know that we log_store()-ed a message and there is something to print to the consoles/syslog. Link: http://lkml.kernel.org/r/20181002023836.4487-3-sergey.senozhatsky@gmail.com To: Steven Rostedt <rostedt@goodmis.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Dmitriy Vyukov <dvyukov@google.com> Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> Cc: Tejun Heo <tj@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: LKML <linux-kernel@vger.kernel.org> Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Signed-off-by: Petr Mladek <pmladek@suse.com>
-rw-r--r--kernel/printk/printk.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index f717656c0fac..e9a7e50ed60a 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1890,8 +1890,9 @@ asmlinkage int vprintk_emit(int facility, int level,
1890 const char *fmt, va_list args) 1890 const char *fmt, va_list args)
1891{ 1891{
1892 int printed_len; 1892 int printed_len;
1893 bool in_sched = false; 1893 bool in_sched = false, pending_output;
1894 unsigned long flags; 1894 unsigned long flags;
1895 u64 curr_log_seq;
1895 1896
1896 if (level == LOGLEVEL_SCHED) { 1897 if (level == LOGLEVEL_SCHED) {
1897 level = LOGLEVEL_DEFAULT; 1898 level = LOGLEVEL_DEFAULT;
@@ -1903,11 +1904,13 @@ asmlinkage int vprintk_emit(int facility, int level,
1903 1904
1904 /* This stops the holder of console_sem just where we want him */ 1905 /* This stops the holder of console_sem just where we want him */
1905 logbuf_lock_irqsave(flags); 1906 logbuf_lock_irqsave(flags);
1907 curr_log_seq = log_next_seq;
1906 printed_len = vprintk_store(facility, level, dict, dictlen, fmt, args); 1908 printed_len = vprintk_store(facility, level, dict, dictlen, fmt, args);
1909 pending_output = (curr_log_seq != log_next_seq);
1907 logbuf_unlock_irqrestore(flags); 1910 logbuf_unlock_irqrestore(flags);
1908 1911
1909 /* If called from the scheduler, we can not call up(). */ 1912 /* If called from the scheduler, we can not call up(). */
1910 if (!in_sched) { 1913 if (!in_sched && pending_output) {
1911 /* 1914 /*
1912 * Disable preemption to avoid being preempted while holding 1915 * Disable preemption to avoid being preempted while holding
1913 * console_sem which would prevent anyone from printing to 1916 * console_sem which would prevent anyone from printing to
@@ -1924,7 +1927,8 @@ asmlinkage int vprintk_emit(int facility, int level,
1924 preempt_enable(); 1927 preempt_enable();
1925 } 1928 }
1926 1929
1927 wake_up_klogd(); 1930 if (pending_output)
1931 wake_up_klogd();
1928 return printed_len; 1932 return printed_len;
1929} 1933}
1930EXPORT_SYMBOL(vprintk_emit); 1934EXPORT_SYMBOL(vprintk_emit);