printk: split out core logging code into helper function
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 9 Oct 2016 05:02:09 +0000 (22:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 9 Oct 2016 19:23:39 +0000 (12:23 -0700)
The code that actually decides how to log the message (whether to put it
directly into the record log, whether to append it to an existing
buffered log, or whether to start a new buffered log) is fairly
non-obvious code in the middle of the vprintk_emit() function.

Splitting that code up into a helper function makes it easier to
understand, but perhaps more importantly also allows for the code to
just return early out of the helper function once it has made the
decision about where the new log content goes.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
kernel/printk/printk.c

index 7b44980..090e201 100644 (file)
@@ -1730,6 +1730,44 @@ static size_t cont_print_text(char *text, size_t size)
        return textlen;
 }
 
+static size_t log_output(int facility, int level, enum log_flags lflags, const char *dict, size_t dictlen, char *text, size_t text_len)
+{
+       if (!(lflags & LOG_NEWLINE)) {
+               /*
+                * Flush the conflicting buffer. An earlier newline was missing,
+                * or another task also prints continuation lines.
+                */
+               if (cont.len && (!(lflags & LOG_CONT) || cont.owner != current))
+                       cont_flush(LOG_NEWLINE);
+
+               /* buffer line if possible, otherwise store it right away */
+               if (cont_add(facility, level, text, text_len))
+                       return text_len;
+
+               return log_store(facility, level, lflags | LOG_CONT, 0, dict, dictlen, text, text_len);
+       }
+
+       /*
+        * If an earlier newline was missing and it was the same task,
+        * either merge it with the current buffer and flush, or if
+        * there was a race with interrupts (prefix == true) then just
+        * flush it out and store this line separately.
+        * If the preceding printk was from a different task and missed
+        * a newline, flush and append the newline.
+        */
+       if (cont.len) {
+               bool stored = false;
+
+               if (cont.owner == current && (lflags & LOG_CONT))
+                       stored = cont_add(facility, level, text, text_len);
+               cont_flush(LOG_NEWLINE);
+               if (stored)
+                       return text_len;
+       }
+
+       return log_store(facility, level, lflags, 0, dict, dictlen, text, text_len);
+}
+
 asmlinkage int vprintk_emit(int facility, int level,
                            const char *dict, size_t dictlen,
                            const char *fmt, va_list args)
@@ -1842,45 +1880,7 @@ asmlinkage int vprintk_emit(int facility, int level,
        if (dict)
                lflags |= LOG_PREFIX|LOG_NEWLINE;
 
-       if (!(lflags & LOG_NEWLINE)) {
-               /*
-                * Flush the conflicting buffer. An earlier newline was missing,
-                * or another task also prints continuation lines.
-                */
-               if (cont.len && (!(lflags & LOG_CONT) || cont.owner != current))
-                       cont_flush(LOG_NEWLINE);
-
-               /* buffer line if possible, otherwise store it right away */
-               if (cont_add(facility, level, text, text_len))
-                       printed_len += text_len;
-               else
-                       printed_len += log_store(facility, level,
-                                                lflags | LOG_CONT, 0,
-                                                dict, dictlen, text, text_len);
-       } else {
-               bool stored = false;
-
-               /*
-                * If an earlier newline was missing and it was the same task,
-                * either merge it with the current buffer and flush, or if
-                * there was a race with interrupts (prefix == true) then just
-                * flush it out and store this line separately.
-                * If the preceding printk was from a different task and missed
-                * a newline, flush and append the newline.
-                */
-               if (cont.len) {
-                       if (cont.owner == current && (lflags & LOG_CONT))
-                               stored = cont_add(facility, level, text,
-                                                 text_len);
-                       cont_flush(LOG_NEWLINE);
-               }
-
-               if (stored)
-                       printed_len += text_len;
-               else
-                       printed_len += log_store(facility, level, lflags, 0,
-                                                dict, dictlen, text, text_len);
-       }
+       printed_len += log_output(facility, level, lflags, dict, dictlen, text, text_len);
 
        logbuf_cpu = UINT_MAX;
        raw_spin_unlock(&logbuf_lock);