]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
printk: make sure to print log on console.
authorManinder Singh <maninder1.s@samsung.com>
Fri, 1 Jun 2018 08:56:42 +0000 (14:26 +0530)
committerPetr Mladek <pmladek@suse.com>
Wed, 27 Jun 2018 14:14:28 +0000 (16:14 +0200)
This patch make sure printing of log on console if loglevel
at time of storing log is less than current console loglevel.

@why
In SMP printk can work asynchronously, logs can be missed on console
because it checks current log level at time of console_unlock,
not at time of storing logs.

func()
{
....
....
        console_verbose();  // user wants to have all the logs on console.
        pr_alert();
dump_backtrace(); //prints with default loglevel.
        ...
        console_silent(); // stop all logs from printing on console.
}

Now if console_lock was owned by another process, the messages might
be handled after the consoles were silenced.

Reused flag LOG_NOCONS as its usage is gone long back by the commit
5c2992ee7fd8a29d0412 ("printk: remove console flushing special cases
for partial buffered lines").

Note that there are still some corner cases where this patch is not enough.
For example, when the messages are flushed later from printk_safe buffers
or when there are races between console_verbose() and console_silent()
callers.

Link: http://lkml.kernel.org/r/20180601090029epcas5p3cc93d4bfbebb3199f0a2684058da7e26~z-a_jkmrI2993329933epcas5p3q@epcas5p3.samsung.com
Cc: linux-kernel@vger.kernel.org
Cc: a.sahrawat@samsung.com
Cc: pankaj.m@samsung.com
Cc: v.narang@samsung.com
Cc: <maninder1.s@samsung.com>
Signed-off-by: Vaneet Narang <v.narang@samsung.com>
Signed-off-by: Maninder Singh <maninder1.s@samsung.com>
Reviewed-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Signed-off-by: Petr Mladek <pmladek@suse.com>
kernel/printk/printk.c

index 247808333ba430f75c0ac7382bc08d6f219685cf..3999c295d6f71de2ce5c219cd3aeeb6aafc34137 100644 (file)
@@ -349,7 +349,7 @@ static int console_msg_format = MSG_FORMAT_DEFAULT;
  */
 
 enum log_flags {
-       LOG_NOCONS      = 1,    /* already flushed, do not print to console */
+       LOG_NOCONS      = 1,    /* suppress print, do not print to console */
        LOG_NEWLINE     = 2,    /* text ended with a newline */
        LOG_PREFIX      = 4,    /* text started with a prefix */
        LOG_CONT        = 8,    /* text is a fragment of a continuation line */
@@ -1886,6 +1886,9 @@ asmlinkage int vprintk_emit(int facility, int level,
        if (dict)
                lflags |= LOG_PREFIX|LOG_NEWLINE;
 
+       if (suppress_message_printing(level))
+               lflags |= LOG_NOCONS;
+
        printed_len = log_output(facility, level, lflags, dict, dictlen, text, text_len);
 
        logbuf_unlock_irqrestore(flags);
@@ -2349,11 +2352,10 @@ void console_unlock(void)
                        break;
 
                msg = log_from_idx(console_idx);
-               if (suppress_message_printing(msg->level)) {
+               if (msg->flags & LOG_NOCONS) {
                        /*
-                        * Skip record we have buffered and already printed
-                        * directly to the console when we received it, and
-                        * record that has level above the console loglevel.
+                        * Skip record if !ignore_loglevel, and
+                        * record has level above the console loglevel.
                         */
                        console_idx = log_next(console_idx);
                        console_seq++;