diff options
author | Kay Sievers <kay@vrfy.org> | 2012-05-10 03:57:37 +0200 |
---|---|---|
committer | Kay Sievers <kay@vrfy.org> | 2012-05-10 04:25:16 +0200 |
commit | 0997e9ee6f26084c4b78e52e2d90f68fb4f498d9 (patch) | |
tree | ff7f9430a740c3a84da355530fd306dd19db9632 | |
parent | ba24d184b1d228fcfd16a041a66a5b65f7b05154 (diff) | |
download | patches-0997e9ee6f26084c4b78e52e2d90f68fb4f498d9.tar.gz |
fixes
-rw-r--r-- | cont.patch | 69 | ||||
-rw-r--r-- | printk-time.patch | 122 | ||||
-rw-r--r-- | series | 3 |
3 files changed, 193 insertions, 1 deletions
diff --git a/cont.patch b/cont.patch new file mode 100644 index 0000000..3fc2406 --- /dev/null +++ b/cont.patch @@ -0,0 +1,69 @@ +From: Kay Sievers <kay@vrfy.org> +Subject: printk() - do not merge continuation lines of different threads + +This prevents the merging of printk() continuation lines of different +threads, in the case they race against each other. + +It should properly isolate "atomic" single-line printk() users from +continuation users, to make sure the single-line users will never be +merged with the racy continuation ones. + +Signed-off-by: Kay Sievers <kay@vrfy.org> +--- + + kernel/printk.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +--- a/kernel/printk.c ++++ b/kernel/printk.c +@@ -1230,12 +1230,13 @@ asmlinkage int vprintk_emit(int facility + static size_t buflen; + static int buflevel; + static char textbuf[LOG_LINE_MAX]; ++ static struct task_struct *cont; + char *text = textbuf; + size_t textlen; + unsigned long flags; + int this_cpu; + bool newline = false; +- bool cont = false; ++ bool prefix = false; + int printed_len = 0; + + boot_delay_msec(); +@@ -1295,20 +1296,16 @@ asmlinkage int vprintk_emit(int facility + case '0' ... '7': + if (level == -1) + level = text[1] - '0'; +- text += 3; +- textlen -= 3; +- break; +- case 'c': /* KERN_CONT */ +- cont = true; + case 'd': /* KERN_DEFAULT */ ++ prefix = true; ++ case 'c': /* KERN_CONT */ + text += 3; + textlen -= 3; +- break; + } + } + +- if (buflen && (!cont || dict)) { +- /* no continuation; flush existing buffer */ ++ if (buflen && (prefix || dict || cont != current)) { ++ /* flush existing buffer */ + log_store(facility, buflevel, NULL, 0, buf, buflen); + printed_len += buflen; + buflen = 0; +@@ -1342,6 +1339,10 @@ asmlinkage int vprintk_emit(int facility + dict, dictlen, text, textlen); + printed_len += textlen; + } ++ cont = NULL; ++ } else { ++ /* remember thread which filled the buffer */ ++ cont = current; + } + + /* diff --git a/printk-time.patch b/printk-time.patch new file mode 100644 index 0000000..d90ece5 --- /dev/null +++ b/printk-time.patch @@ -0,0 +1,122 @@ +From: Kay Sievers <kay@vrfy.org> +Subject: printk() - restore timestamp printing at console output + +The output of the timestamps got lost with the conversion of the +kmsg buffer to records; restore the old behavior. + +Document, that CONFIG_PRINTK_TIME now only controls the output of +the timestamps in the syslog() system call and on the console, and +not the recording of the timestamps. + +Signed-off-by: Kay Sievers <kay@vrfy.org> +--- + + kernel/printk.c | 43 ++++++++++++++++++++++++++----------------- + lib/Kconfig.debug | 16 ++++++++++------ + 2 files changed, 36 insertions(+), 23 deletions(-) + +--- a/kernel/printk.c ++++ b/kernel/printk.c +@@ -786,6 +786,22 @@ static bool printk_time; + #endif + module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); + ++static size_t prepend_timestamp(unsigned long long t, char *buf) ++{ ++ unsigned long rem_ns; ++ ++ if (!printk_time) ++ return 0; ++ ++ if (!buf) ++ return 15; ++ ++ rem_ns = do_div(t, 1000000000); ++ ++ return sprintf(buf, "[%5lu.%06lu] ", ++ (unsigned long) t, rem_ns / 1000); ++} ++ + static int syslog_print_line(u32 idx, char *text, size_t size) + { + struct log *msg; +@@ -800,9 +816,7 @@ static int syslog_print_line(u32 idx, ch + len++; + if (msg->level > 99) + len++; +- +- if (printk_time) +- len += 15; ++ len += prepend_timestamp(0, NULL); + + len += msg->text_len; + len++; +@@ -810,15 +824,7 @@ static int syslog_print_line(u32 idx, ch + } + + len = sprintf(text, "<%u>", msg->level); +- +- if (printk_time) { +- unsigned long long t = msg->ts_nsec; +- unsigned long rem_ns = do_div(t, 1000000000); +- +- len += sprintf(text + len, "[%5lu.%06lu] ", +- (unsigned long) t, rem_ns / 1000); +- } +- ++ len += prepend_timestamp(msg->ts_nsec, text + len); + if (len + msg->text_len > size) + return -EINVAL; + memcpy(text + len, log_text(msg), msg->text_len); +@@ -1741,7 +1747,7 @@ again: + for (;;) { + struct log *msg; + static char text[LOG_LINE_MAX]; +- size_t len; ++ size_t len, l; + int level; + + raw_spin_lock_irqsave(&logbuf_lock, flags); +@@ -1761,10 +1767,13 @@ again: + + msg = log_from_idx(console_idx); + level = msg->level & 7; +- len = msg->text_len; +- if (len+1 >= sizeof(text)) +- len = sizeof(text)-1; +- memcpy(text, log_text(msg), len); ++ ++ len = prepend_timestamp(msg->ts_nsec, text); ++ l = msg->text_len; ++ if (len + l + 1 >= sizeof(text)) ++ l = sizeof(text) - len - 1; ++ memcpy(text + len, log_text(msg), l); ++ len += l; + text[len++] = '\n'; + + console_idx = log_next(console_idx); +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -3,12 +3,16 @@ config PRINTK_TIME + bool "Show timing information on printks" + depends on PRINTK + help +- Selecting this option causes timing information to be +- included in printk output. This allows you to measure +- the interval between kernel operations, including bootup +- operations. This is useful for identifying long delays +- in kernel startup. Or add printk.time=1 at boot-time. +- See Documentation/kernel-parameters.txt ++ Selecting this option causes time stamps of the printk() ++ messages to be added to the output of the syslog() system ++ call and at the console. ++ ++ The timestamp is always recorded internally, and exported ++ to /dev/kmsg. This flag just specifies if the timetamp should ++ be included, not that the timestamp is recorded. ++ ++ The behaviour is also controlled by the kernel command line ++ parameter printk.time=1. See Documentation/kernel-parameters.txt + + config DEFAULT_MESSAGE_LOGLEVEL + int "Default message log level (1-7)" @@ -5,7 +5,8 @@ printk-devkmsg.patch printk-dev_printk.patch kmsg-fix64bit-division.patch kern-cont-parport.patch -kern-conti-acpi.patch kern-cont-mm.patch kmsg-docs.patch kmsg-off.patch +cont.patch +printk-time.patch |