Skip to content

Commit 5fd29d6

Browse files
committed
printk: clean up handling of log-levels and newlines
It used to be that we would only look at the log-level in a printk() after explicit newlines, which can cause annoying problems when the previous printk() did not end with a '\n'. In that case, the log-level marker would be just printed out in the middle of the line, and be seen as just noise rather than change the logging level. This changes things to always look at the log-level in the first bytes of the printout. If a log level marker is found, it is always used as the log-level. Additionally, if no newline existed, one is added (unless the log-level is the explicit KERN_CONT marker, to explicitly show that it's a continuation of a previous line). Acked-by: Arjan van de Ven <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 03347e2 commit 5fd29d6

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

include/linux/kernel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ extern const char linux_proc_banner[];
102102
* line that had no enclosing \n). Only to be used by core/arch code
103103
* during early bootup (a continued line is not SMP-safe otherwise).
104104
*/
105-
#define KERN_CONT ""
105+
#define KERN_CONT "<c>"
106106

107107
extern int console_printk[];
108108

kernel/printk.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -687,20 +687,33 @@ asmlinkage int vprintk(const char *fmt, va_list args)
687687
sizeof(printk_buf) - printed_len, fmt, args);
688688

689689

690+
p = printk_buf;
691+
692+
/* Do we have a loglevel in the string? */
693+
if (p[0] == '<') {
694+
unsigned char c = p[1];
695+
if (c && p[2] == '>') {
696+
switch (c) {
697+
case '0' ... '7': /* loglevel */
698+
current_log_level = c - '0';
699+
if (!new_text_line) {
700+
emit_log_char('\n');
701+
new_text_line = 1;
702+
}
703+
/* Fallthrough - skip the loglevel */
704+
case 'c': /* KERN_CONT */
705+
p += 3;
706+
break;
707+
}
708+
}
709+
}
710+
690711
/*
691712
* Copy the output into log_buf. If the caller didn't provide
692713
* appropriate log level tags, we insert them here
693714
*/
694-
for (p = printk_buf; *p; p++) {
715+
for ( ; *p; p++) {
695716
if (new_text_line) {
696-
/* If a token, set current_log_level and skip over */
697-
if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' &&
698-
p[2] == '>') {
699-
current_log_level = p[1] - '0';
700-
p += 3;
701-
printed_len -= 3;
702-
}
703-
704717
/* Always output the token */
705718
emit_log_char('<');
706719
emit_log_char(current_log_level + '0');

0 commit comments

Comments
 (0)