summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2012-05-10 03:57:37 +0200
committerKay Sievers <kay@vrfy.org>2012-05-10 04:25:16 +0200
commit0997e9ee6f26084c4b78e52e2d90f68fb4f498d9 (patch)
treeff7f9430a740c3a84da355530fd306dd19db9632
parentba24d184b1d228fcfd16a041a66a5b65f7b05154 (diff)
downloadpatches-0997e9ee6f26084c4b78e52e2d90f68fb4f498d9.tar.gz
fixes
-rw-r--r--cont.patch69
-rw-r--r--printk-time.patch122
-rw-r--r--series3
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)"
diff --git a/series b/series
index fb6d188..ca6cad3 100644
--- a/series
+++ b/series
@@ -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