diff options
-rw-r--r-- | 00-kmsg-fix-overlong-cont.patch | 139 | ||||
-rw-r--r-- | 01-kmsg-config-no-printk.patch | 46 | ||||
-rw-r--r-- | 02-kmsg-export-flags.patch | 132 | ||||
-rw-r--r-- | 03-kmsg-cont-order.patch | 213 | ||||
-rw-r--r-- | pr_cat.patch | 117 | ||||
-rw-r--r-- | series | 5 |
6 files changed, 0 insertions, 652 deletions
diff --git a/00-kmsg-fix-overlong-cont.patch b/00-kmsg-fix-overlong-cont.patch deleted file mode 100644 index 8e77f40..0000000 --- a/00-kmsg-fix-overlong-cont.patch +++ /dev/null @@ -1,139 +0,0 @@ -From: Kay Sievers <kay@vrfy.org> -Subject: kmsg - properly print over-long continuation lines - -Reserve PREFIX_MAX bytes in the LOG_LINE_MAX line when buffering a -continuation line, to be able to properly prefix the LOG_LINE_MAX -line with the syslog prefix and timestamp when printing it. - -Reported-By: Dave Jones <davej@redhat.com> -Signed-off-by: Kay Sievers <kay@vrfy.org> ---- - - kernel/printk.c | 33 +++++++++++++++++++-------------- - 1 file changed, 19 insertions(+), 14 deletions(-) - ---- a/kernel/printk.c -+++ b/kernel/printk.c -@@ -235,7 +235,8 @@ static u32 log_next_idx; - static u64 clear_seq; - static u32 clear_idx; - --#define LOG_LINE_MAX 1024 -+#define PREFIX_MAX 32 -+#define LOG_LINE_MAX 1024 - PREFIX_MAX - - /* record buffer */ - #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) -@@ -876,7 +877,7 @@ static size_t msg_print_text(const struc - - if (buf) { - if (print_prefix(msg, syslog, NULL) + -- text_len + 1>= size - len) -+ text_len + 1 >= size - len) - break; - - if (prefix) -@@ -907,7 +908,7 @@ static int syslog_print(char __user *buf - struct log *msg; - int len = 0; - -- text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); -+ text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); - if (!text) - return -ENOMEM; - -@@ -930,7 +931,8 @@ static int syslog_print(char __user *buf - - skip = syslog_partial; - msg = log_from_idx(syslog_idx); -- n = msg_print_text(msg, syslog_prev, true, text, LOG_LINE_MAX); -+ n = msg_print_text(msg, syslog_prev, true, text, -+ LOG_LINE_MAX + PREFIX_MAX); - if (n - syslog_partial <= size) { - /* message fits into buffer, move forward */ - syslog_idx = log_next(syslog_idx); -@@ -969,7 +971,7 @@ static int syslog_print_all(char __user - char *text; - int len = 0; - -- text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); -+ text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); - if (!text) - return -ENOMEM; - -@@ -1022,7 +1024,8 @@ static int syslog_print_all(char __user - struct log *msg = log_from_idx(idx); - int textlen; - -- textlen = msg_print_text(msg, prev, true, text, LOG_LINE_MAX); -+ textlen = msg_print_text(msg, prev, true, text, -+ LOG_LINE_MAX + PREFIX_MAX); - if (textlen < 0) { - len = textlen; - break; -@@ -1367,15 +1370,15 @@ static struct cont { - bool flushed:1; /* buffer sealed and committed */ - } cont; - --static void cont_flush(void) -+static void cont_flush(enum log_flags flags) - { - if (cont.flushed) - return; - if (cont.len == 0) - return; - -- log_store(cont.facility, cont.level, LOG_NOCONS, cont.ts_nsec, -- NULL, 0, cont.buf, cont.len); -+ log_store(cont.facility, cont.level, LOG_NOCONS | flags, -+ cont.ts_nsec, NULL, 0, cont.buf, cont.len); - - cont.flushed = true; - } -@@ -1386,7 +1389,8 @@ static bool cont_add(int facility, int l - return false; - - if (cont.len + len > sizeof(cont.buf)) { -- cont_flush(); -+ /* the line gets too long, split it up in separate records */ -+ cont_flush(LOG_CONT); - return false; - } - -@@ -1522,7 +1526,7 @@ asmlinkage int vprintk_emit(int facility - * or another task also prints continuation lines. - */ - if (cont.len && (lflags & LOG_PREFIX || cont.owner != current)) -- cont_flush(); -+ cont_flush(0); - - /* buffer line if possible, otherwise store it right away */ - if (!cont_add(facility, level, text, text_len)) -@@ -1540,7 +1544,7 @@ asmlinkage int vprintk_emit(int facility - if (cont.len && cont.owner == current) { - if (!(lflags & LOG_PREFIX)) - stored = cont_add(facility, level, text, text_len); -- cont_flush(); -+ cont_flush(0); - } - - if (!stored) -@@ -1633,7 +1637,8 @@ EXPORT_SYMBOL(printk); - - #else - --#define LOG_LINE_MAX 0 -+#define LOG_LINE_MAX 0 -+#define PREFIX_MAX 0 - static struct cont { - size_t len; - size_t cons; -@@ -1938,7 +1943,7 @@ static enum log_flags console_prev; - */ - void console_unlock(void) - { -- static char text[LOG_LINE_MAX]; -+ static char text[LOG_LINE_MAX + PREFIX_MAX]; - static u64 seen_seq; - unsigned long flags; - bool wake_klogd = false; diff --git a/01-kmsg-config-no-printk.patch b/01-kmsg-config-no-printk.patch deleted file mode 100644 index 54b49a9..0000000 --- a/01-kmsg-config-no-printk.patch +++ /dev/null @@ -1,46 +0,0 @@ -From: Kay Sievers <kay@vrfy.org> -Subject: kmsg - avoid warning for CONFIG_PRINTK=n compilations - -Signed-off-by: Kay Sievers <kay@vrfy.org> ---- - - kernel/printk.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - ---- a/kernel/printk.c -+++ b/kernel/printk.c -@@ -216,6 +216,7 @@ struct log { - */ - static DEFINE_RAW_SPINLOCK(logbuf_lock); - -+#ifdef CONFIG_PRINTK - /* the next printk record to read by syslog(READ) or /proc/kmsg */ - static u64 syslog_seq; - static u32 syslog_idx; -@@ -228,7 +229,6 @@ static u32 log_first_idx; - - /* index and sequence number of the next record to store in the buffer */ - static u64 log_next_seq; --#ifdef CONFIG_PRINTK - static u32 log_next_idx; - - /* the next printk record to read after the last 'clear' command */ -@@ -1635,10 +1635,17 @@ asmlinkage int printk(const char *fmt, . - } - EXPORT_SYMBOL(printk); - --#else -+#else /* CONFIG_PRINTK */ - - #define LOG_LINE_MAX 0 - #define PREFIX_MAX 0 -+#define LOG_LINE_MAX 0 -+static u64 syslog_seq; -+static u32 syslog_idx; -+static enum log_flags syslog_prev; -+static u64 log_first_seq; -+static u32 log_first_idx; -+static u64 log_next_seq; - static struct cont { - size_t len; - size_t cons; diff --git a/02-kmsg-export-flags.patch b/02-kmsg-export-flags.patch deleted file mode 100644 index 8091c5f..0000000 --- a/02-kmsg-export-flags.patch +++ /dev/null @@ -1,132 +0,0 @@ -From: Kay Sievers <kay@vrfy.org> -Subject: kmsg - export "continuation record" flag to /dev/kmsg - -In some cases we are forced to store individual records for a continuation -line print. - -Export a flag to allow the external re-construction of the line. The flag -allows us to apply a similar logic externally which is used internally when -the console, /proc/kmsg or the syslog() output is printed. - - $ cat /dev/kmsg - 4,165,0,-;Free swap = 0kB - 4,166,0,-;Total swap = 0kB - 6,167,0,c;[ - 4,168,0,+;0 - 4,169,0,+;1 - 4,170,0,+;2 - 4,171,0,+;3 - 4,172,0,+;] - 6,173,0,-;[0 1 2 3 ] - 6,174,0,-;Console: colour VGA+ 80x25 - 6,175,0,-;console [tty0] enabled - -Signed-off-by: Kay Sievers <kay@vrfy.org> ---- - - Documentation/ABI/testing/dev-kmsg | 29 ++++++++++++++++++++--------- - kernel/printk.c | 23 +++++++++++++++++++++-- - 2 files changed, 41 insertions(+), 11 deletions(-) - ---- a/Documentation/ABI/testing/dev-kmsg -+++ b/Documentation/ABI/testing/dev-kmsg -@@ -58,16 +58,18 @@ Description: The /dev/kmsg character dev - - The output format consists of a prefix carrying the syslog - prefix including priority and facility, the 64 bit message -- sequence number and the monotonic timestamp in microseconds. -- The values are separated by a ','. Future extensions might -- add more comma separated values before the terminating ';'. -- Unknown values should be gracefully ignored. -+ sequence number and the monotonic timestamp in microseconds, -+ and a flag field. All fields are separated by a ','. -+ -+ Future extensions might add more comma separated values before -+ the terminating ';'. Unknown fields and values should be -+ gracefully ignored. - - The human readable text string starts directly after the ';' - and is terminated by a '\n'. Untrusted values derived from - hardware or other facilities are printed, therefore -- all non-printable characters in the log message are escaped -- by "\x00" C-style hex encoding. -+ all non-printable characters and '\' itself in the log message -+ are escaped by "\x00" C-style hex encoding. - - A line starting with ' ', is a continuation line, adding - key/value pairs to the log message, which provide the machine -@@ -75,11 +77,11 @@ Description: The /dev/kmsg character dev - userspace. - - Example: -- 7,160,424069;pci_root PNP0A03:00: host bridge window [io 0x0000-0x0cf7] (ignored) -+ 7,160,424069,-;pci_root PNP0A03:00: host bridge window [io 0x0000-0x0cf7] (ignored) - SUBSYSTEM=acpi - DEVICE=+acpi:PNP0A03:00 -- 6,339,5140900;NET: Registered protocol family 10 -- 30,340,5690716;udevd[80]: starting version 181 -+ 6,339,5140900,-;NET: Registered protocol family 10 -+ 30,340,5690716,-;udevd[80]: starting version 181 - - The DEVICE= key uniquely identifies devices the following way: - b12:8 - block dev_t -@@ -87,4 +89,13 @@ Description: The /dev/kmsg character dev - n8 - netdev ifindex - +sound:card0 - subsystem:devname - -+ The flags field carries '-' by default. A 'c' indicates a -+ fragment of a line. All following fragments are flagged with -+ '+'. Note, that these hints about continuation lines are not -+ neccessarily correct, and the stream could be interleaved with -+ unrelated messages, but merging the lines in the output -+ usually produces better human readable results. A similar -+ logic is used internally when messages are printed to the -+ console, /proc/kmsg or the syslog() syscall. -+ - Users: dmesg(1), userspace kernel log consumers ---- a/kernel/printk.c -+++ b/kernel/printk.c -@@ -361,6 +361,7 @@ static void log_store(int facility, int - struct devkmsg_user { - u64 seq; - u32 idx; -+ enum log_flags prev; - struct mutex lock; - char buf[8192]; - }; -@@ -426,6 +427,7 @@ static ssize_t devkmsg_read(struct file - struct log *msg; - u64 ts_usec; - size_t i; -+ char cont = '-'; - size_t len; - ssize_t ret; - -@@ -463,8 +465,25 @@ static ssize_t devkmsg_read(struct file - msg = log_from_idx(user->idx); - ts_usec = msg->ts_nsec; - do_div(ts_usec, 1000); -- len = sprintf(user->buf, "%u,%llu,%llu;", -- (msg->facility << 3) | msg->level, user->seq, ts_usec); -+ -+ /* -+ * If we couldn't merge continuation line fragments during the print, -+ * export the stored flags to allow an optional external merge of the -+ * records. Merging the records isn't always neccessarily correct, like -+ * when we hit a race during printing. In most cases though, it produces -+ * better readable output. 'c' in the record flags mark the first -+ * fragment of a line, '+' the following. -+ */ -+ if (msg->flags & LOG_CONT && !(user->prev & LOG_CONT)) -+ cont = 'c'; -+ else if ((msg->flags & LOG_CONT) || -+ ((user->prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))) -+ cont = '+'; -+ -+ len = sprintf(user->buf, "%u,%llu,%llu,%c;", -+ (msg->facility << 3) | msg->level, -+ user->seq, ts_usec, cont); -+ user->prev = msg->flags; - - /* escape non-printable characters */ - for (i = 0; i < msg->text_len; i++) { diff --git a/03-kmsg-cont-order.patch b/03-kmsg-cont-order.patch deleted file mode 100644 index b53c6fb..0000000 --- a/03-kmsg-cont-order.patch +++ /dev/null @@ -1,213 +0,0 @@ -From: Kay Sievers <kay@vrfy.org> -Subject: kmsg - do not flush partial lines when the console is busy - -Fragments of continuation lines are flushed to the console immediately. In -case the console is locked, the fragment must be queued up in the cont -buffer. - -If the the console is busy and the continuation line is complete, but no part -of it was written to the console up to this point, we can just store the -entire line as a regular record and free the buffer earlier. - -If the console is busy and earlier messages are already queued up, we -should not flush the fragments of continuation lines, but store them after -the queued up messages, to ensure the proper ordering. - -This keeps the console output better readable in case printk()s race against -each other, or we receive over-long continuation lines we need to flush. - -Signed-off-by: Kay Sievers <kay@vrfy.org> ---- - - kernel/printk.c | 93 ++++++++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 68 insertions(+), 25 deletions(-) - ---- a/kernel/printk.c -+++ b/kernel/printk.c -@@ -231,6 +231,11 @@ static u32 log_first_idx; - static u64 log_next_seq; - static u32 log_next_idx; - -+/* the next printk record to write to the console */ -+static u64 console_seq; -+static u32 console_idx; -+static enum log_flags console_prev; -+ - /* the next printk record to read after the last 'clear' command */ - static u64 clear_seq; - static u32 clear_idx; -@@ -1386,6 +1391,7 @@ static struct cont { - u64 ts_nsec; /* time of first print */ - u8 level; /* log level of first message */ - u8 facility; /* log level of first message */ -+ enum log_flags flags; /* prefix, newline flags */ - bool flushed:1; /* buffer sealed and committed */ - } cont; - -@@ -1396,10 +1402,25 @@ static void cont_flush(enum log_flags fl - if (cont.len == 0) - return; - -- log_store(cont.facility, cont.level, LOG_NOCONS | flags, -- cont.ts_nsec, NULL, 0, cont.buf, cont.len); -- -- cont.flushed = true; -+ if (cont.cons) { -+ /* -+ * If a fragment of this line was directly flushed to the -+ * console; wait for the console to pick up the rest of the -+ * line. LOG_NOCONS suppresses a duplicated output. -+ */ -+ log_store(cont.facility, cont.level, flags | LOG_NOCONS, -+ cont.ts_nsec, NULL, 0, cont.buf, cont.len); -+ cont.flags = flags; -+ cont.flushed = true; -+ } else { -+ /* -+ * If no fragment of this line ever reached the console, -+ * just submit it to the store and free the buffer. -+ */ -+ log_store(cont.facility, cont.level, flags, 0, -+ NULL, 0, cont.buf, cont.len); -+ cont.len = 0; -+ } - } - - static bool cont_add(int facility, int level, const char *text, size_t len) -@@ -1418,12 +1439,17 @@ static bool cont_add(int facility, int l - cont.level = level; - cont.owner = current; - cont.ts_nsec = local_clock(); -+ cont.flags = 0; - cont.cons = 0; - cont.flushed = false; - } - - memcpy(cont.buf + cont.len, text, len); - cont.len += len; -+ -+ if (cont.len > (sizeof(cont.buf) * 80) / 100) -+ cont_flush(LOG_CONT); -+ - return true; - } - -@@ -1432,7 +1458,7 @@ static size_t cont_print_text(char *text - size_t textlen = 0; - size_t len; - -- if (cont.cons == 0) { -+ if (cont.cons == 0 && (console_prev & LOG_NEWLINE)) { - textlen += print_time(cont.ts_nsec, text); - size -= textlen; - } -@@ -1447,7 +1473,8 @@ static size_t cont_print_text(char *text - } - - if (cont.flushed) { -- text[textlen++] = '\n'; -+ if (cont.flags & LOG_NEWLINE) -+ text[textlen++] = '\n'; - /* got everything, release buffer */ - cont.len = 0; - } -@@ -1545,7 +1572,7 @@ asmlinkage int vprintk_emit(int facility - * or another task also prints continuation lines. - */ - if (cont.len && (lflags & LOG_PREFIX || cont.owner != current)) -- cont_flush(0); -+ cont_flush(LOG_NEWLINE); - - /* buffer line if possible, otherwise store it right away */ - if (!cont_add(facility, level, text, text_len)) -@@ -1563,7 +1590,7 @@ asmlinkage int vprintk_emit(int facility - if (cont.len && cont.owner == current) { - if (!(lflags & LOG_PREFIX)) - stored = cont_add(facility, level, text, text_len); -- cont_flush(0); -+ cont_flush(LOG_NEWLINE); - } - - if (!stored) -@@ -1661,10 +1688,13 @@ EXPORT_SYMBOL(printk); - #define LOG_LINE_MAX 0 - static u64 syslog_seq; - static u32 syslog_idx; -+static u64 console_seq; -+static u32 console_idx; - static enum log_flags syslog_prev; - static u64 log_first_seq; - static u32 log_first_idx; - static u64 log_next_seq; -+static enum log_flags console_prev; - static struct cont { - size_t len; - size_t cons; -@@ -1948,10 +1978,34 @@ void wake_up_klogd(void) - this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); - } - --/* the next printk record to write to the console */ --static u64 console_seq; --static u32 console_idx; --static enum log_flags console_prev; -+static void console_cont_flush(char *text, size_t size) -+{ -+ unsigned long flags; -+ size_t len; -+ -+ raw_spin_lock_irqsave(&logbuf_lock, flags); -+ -+ if (!cont.len) -+ goto out; -+ -+ /* -+ * We still queue earlier records, likely because the console was -+ * busy. The earlier ones need to be printed before this one, we -+ * did not flush any fragment so far, so just let it queue up. -+ */ -+ if (console_seq < log_next_seq && !cont.cons) -+ goto out; -+ -+ len = cont_print_text(text, size); -+ raw_spin_unlock(&logbuf_lock); -+ stop_critical_timings(); -+ call_console_drivers(cont.level, text, len); -+ start_critical_timings(); -+ local_irq_restore(flags); -+ return; -+out: -+ raw_spin_unlock_irqrestore(&logbuf_lock, flags); -+} - - /** - * console_unlock - unlock the console system -@@ -1983,19 +2037,7 @@ void console_unlock(void) - console_may_schedule = 0; - - /* flush buffered message fragment immediately to console */ -- raw_spin_lock_irqsave(&logbuf_lock, flags); -- if (cont.len && (cont.cons < cont.len || cont.flushed)) { -- size_t len; -- -- len = cont_print_text(text, sizeof(text)); -- raw_spin_unlock(&logbuf_lock); -- stop_critical_timings(); -- call_console_drivers(cont.level, text, len); -- start_critical_timings(); -- local_irq_restore(flags); -- } else -- raw_spin_unlock_irqrestore(&logbuf_lock, flags); -- -+ console_cont_flush(text, sizeof(text)); - again: - for (;;) { - struct log *msg; -@@ -2032,6 +2074,7 @@ skip: - * will properly dump everything later. - */ - msg->flags &= ~LOG_NOCONS; -+ console_prev = msg->flags; - goto skip; - } - diff --git a/pr_cat.patch b/pr_cat.patch deleted file mode 100644 index aea0193..0000000 --- a/pr_cat.patch +++ /dev/null @@ -1,117 +0,0 @@ -diff --git a/kernel/printk.c b/kernel/printk.c -index 177fa49..0f4df08 100644 ---- a/kernel/printk.c -+++ b/kernel/printk.c -@@ -48,6 +48,40 @@ - #define CREATE_TRACE_POINTS - #include <trace/events/printk.h> - -+#define CATSTR_INIT(name) \ -+ name##_len = 0 -+ -+#define CATSTR_DEFINE(name, max) \ -+ char name[max]; \ -+ size_t name##_len = 0; \ -+ size_t name##_max = max -+ -+#define pr_cat(name, fmt, ...) \ -+ _pr_cat(name, &name##_len, name##_max, fmt, ##__VA_ARGS__) -+ -+bool _pr_cat(char *s, size_t *len, size_t size, const char *fmt, ...) -+{ -+ va_list args; -+ size_t r; -+ -+ if (*len == size) -+ return false; -+ -+ va_start(args, fmt); -+ r = vsnprintf(s + *len, size - *len, fmt, args); -+ va_end(args); -+ -+ if (r + 1 >= size - *len) { -+ s[*len] = '\0'; -+ *len = size; -+ return false; -+ } -+ -+ *len += r; -+ s[*len] = '\0'; -+ return true; -+} -+ - /* - * Architectures can override it: - */ -@@ -587,6 +621,11 @@ static int devkmsg_open(struct inode *inode, struct file *file) - struct devkmsg_user *user; - int err; - -+ console_lock(); -+ print_modules(); -+ print_modules(); -+ console_unlock(); -+ - /* write-only does not need any file context */ - if ((file->f_flags & O_ACCMODE) == O_WRONLY) - return 0; -@@ -671,6 +710,59 @@ void __init setup_log_buf(int early) - unsigned long flags; - char *new_log_buf; - int free; -+ int i; -+ -+ CATSTR_DEFINE(line, 64); -+ CATSTR_DEFINE(line2, 16); -+ CATSTR_DEFINE(line3, 12); -+ -+ pr_cat(line, "1:"); -+ pr_cat(line, "-%i ", 12); -+ pr_cat(line, "-%i ", 34); -+ pr_cat(line, "-%i ", 56); -+ pr_cat(line, "-%i ", 78); -+ pr_info("%s-%i\n", line, 90); -+ -+ pr_cat(line2, "2:"); -+ pr_cat(line2, "-%i ", 12); -+ pr_cat(line2, "-%i ", 34); -+ pr_cat(line2, "-%i ", 56); -+ pr_cat(line2, "-%i ", 78); -+ pr_info("%s-%i\n", line2, 90); -+ -+ pr_cat(line3, "3:"); -+ pr_cat(line3, "-%i ", 12); -+ pr_cat(line3, "-%i ", 34); -+ pr_cat(line3, "-%i ", 56); -+ pr_cat(line3, "-%i ", 78); -+ pr_info("%s-%i\n", line3, 90); -+ -+ CATSTR_INIT(line3); -+ pr_cat(line3, "4:"); -+ pr_cat(line3, "+%i ", 12); -+ pr_cat(line3, "+%i ", 34); -+ pr_cat(line3, "+%i ", 56); -+ pr_cat(line3, "+%i ", 78); -+ pr_info("%s-%i\n", line3, 90); -+ -+ CATSTR_INIT(line3); -+ pr_cat(line3, "5:"); -+ pr_cat(line3, "~%i ", 12); -+ pr_cat(line3, "~%i ", 34); -+ pr_cat(line3, "~%i ", 56); -+ pr_cat(line3, "~%i ", 78); -+ pr_info("%s-%i\n", line3, 90); -+ -+ CATSTR_INIT(line); -+ pr_cat(line, "foo:"); -+ for (i = 0; i < 50; i++) { -+ if (!pr_cat(line, " #%i", i)) { -+ pr_info("%s #%i\n", line, i); -+ CATSTR_INIT(line); -+ pr_cat(line, "foo+:"); -+ } -+ } -+ pr_info("%s\n", line); - - if (!new_log_buf_len) - return; @@ -1,7 +1,2 @@ #test-modules.patch #test-console-blocked.patch -#pr_cat.patch -00-kmsg-fix-overlong-cont.patch -01-kmsg-config-no-printk.patch -02-kmsg-export-flags.patch -03-kmsg-cont-order.patch |