aboutsummaryrefslogtreecommitdiffstats
path: root/features/rt/printk-refactor-kmsg_dump_get_buffer.patch
diff options
context:
space:
mode:
Diffstat (limited to 'features/rt/printk-refactor-kmsg_dump_get_buffer.patch')
-rw-r--r--features/rt/printk-refactor-kmsg_dump_get_buffer.patch144
1 files changed, 144 insertions, 0 deletions
diff --git a/features/rt/printk-refactor-kmsg_dump_get_buffer.patch b/features/rt/printk-refactor-kmsg_dump_get_buffer.patch
new file mode 100644
index 00000000..3ac51cf4
--- /dev/null
+++ b/features/rt/printk-refactor-kmsg_dump_get_buffer.patch
@@ -0,0 +1,144 @@
+From d90ed552b2dc6bf64d8c0858f712deb58825fb95 Mon Sep 17 00:00:00 2001
+From: John Ogness <john.ogness@linutronix.de>
+Date: Mon, 30 Nov 2020 01:41:56 +0106
+Subject: [PATCH 009/191] printk: refactor kmsg_dump_get_buffer()
+
+kmsg_dump_get_buffer() requires nearly the same logic as
+syslog_print_all(), but uses different variable names and
+does not make use of the ringbuffer loop macros. Modify
+kmsg_dump_get_buffer() so that the implementation is as similar
+to syslog_print_all() as possible.
+
+A follow-up commit will move this common logic into a
+separate helper function.
+
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ include/linux/kmsg_dump.h | 2 +-
+ kernel/printk/printk.c | 60 +++++++++++++++++++++------------------
+ 2 files changed, 33 insertions(+), 29 deletions(-)
+
+diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h
+index 235c50982c2d..4095a34db0fa 100644
+--- a/include/linux/kmsg_dump.h
++++ b/include/linux/kmsg_dump.h
+@@ -62,7 +62,7 @@ bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog,
+ char *line, size_t size, size_t *len);
+
+ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
+- char *buf, size_t size, size_t *len);
++ char *buf, size_t size, size_t *len_out);
+
+ void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper);
+
+diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
+index 77ae2704e979..3f17ff13fd51 100644
+--- a/kernel/printk/printk.c
++++ b/kernel/printk/printk.c
+@@ -3424,7 +3424,7 @@ EXPORT_SYMBOL_GPL(kmsg_dump_get_line);
+ * read.
+ */
+ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
+- char *buf, size_t size, size_t *len)
++ char *buf, size_t size, size_t *len_out)
+ {
+ struct printk_info info;
+ unsigned int line_count;
+@@ -3432,12 +3432,10 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
+ unsigned long flags;
+ u64 seq;
+ u64 next_seq;
+- size_t l = 0;
++ size_t len = 0;
+ bool ret = false;
+ bool time = printk_time;
+
+- prb_rec_init_rd(&r, &info, buf, size);
+-
+ if (!dumper->active || !buf || !size)
+ goto out;
+
+@@ -3455,48 +3453,54 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
+ goto out;
+ }
+
+- /* calculate length of entire buffer */
+- seq = dumper->cur_seq;
+- while (prb_read_valid_info(prb, seq, &info, &line_count)) {
+- if (r.info->seq >= dumper->next_seq)
++ /*
++ * Find first record that fits, including all following records,
++ * into the user-provided buffer for this dump.
++ */
++
++ prb_for_each_info(dumper->cur_seq, prb, seq, &info, &line_count) {
++ if (info.seq >= dumper->next_seq)
+ break;
+- l += get_record_print_text_size(&info, line_count, syslog, time);
+- seq = r.info->seq + 1;
++ len += get_record_print_text_size(&info, line_count, syslog, time);
+ }
+
+- /* move first record forward until length fits into the buffer */
+- seq = dumper->cur_seq;
+- while (l >= size && prb_read_valid_info(prb, seq,
+- &info, &line_count)) {
+- if (r.info->seq >= dumper->next_seq)
++ /*
++ * Move first record forward until length fits into the buffer. Ignore
++ * newest messages that were not counted in the above cycle. Messages
++ * might appear and get lost in the meantime. This is the best effort
++ * that prevents an infinite loop.
++ */
++ prb_for_each_info(dumper->cur_seq, prb, seq, &info, &line_count) {
++ if (len < size || info.seq >= dumper->next_seq)
+ break;
+- l -= get_record_print_text_size(&info, line_count, syslog, time);
+- seq = r.info->seq + 1;
++ len -= get_record_print_text_size(&info, line_count, syslog, time);
+ }
+
+- /* last message in next interation */
++ /*
++ * Next kmsg_dump_get_buffer() invocation will dump block of
++ * older records stored right before this one.
++ */
+ next_seq = seq;
+
+- /* actually read text into the buffer now */
+- l = 0;
+- while (prb_read_valid(prb, seq, &r)) {
++ prb_rec_init_rd(&r, &info, buf, size);
++
++ len = 0;
++ prb_for_each_record(seq, prb, seq, &r) {
+ if (r.info->seq >= dumper->next_seq)
+ break;
+
+- l += record_print_text(&r, syslog, time);
+-
+- /* adjust record to store to remaining buffer space */
+- prb_rec_init_rd(&r, &info, buf + l, size - l);
++ len += record_print_text(&r, syslog, time);
+
+- seq = r.info->seq + 1;
++ /* Adjust record to store to remaining buffer space. */
++ prb_rec_init_rd(&r, &info, buf + len, size - len);
+ }
+
+ dumper->next_seq = next_seq;
+ ret = true;
+ logbuf_unlock_irqrestore(flags);
+ out:
+- if (len)
+- *len = l;
++ if (len_out)
++ *len_out = len;
+ return ret;
+ }
+ EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer);
+--
+2.19.1
+