All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Ogness <john.ogness@linutronix.de>
To: Petr Mladek <pmladek@suse.com>
Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>,
	Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	linux-kernel@vger.kernel.org, Kees Cook <keescook@chromium.org>,
	Pavel Tatashin <pasha.tatashin@soleen.com>,
	Michael Ellerman <mpe@ellerman.id.au>
Subject: [PATCH next v4 05/15] printk: refactor kmsg_dump_get_buffer()
Date: Wed,  3 Mar 2021 11:15:18 +0100	[thread overview]
Message-ID: <20210303101528.29901-6-john.ogness@linutronix.de> (raw)
In-Reply-To: <20210303101528.29901-1-john.ogness@linutronix.de>

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>
---
 include/linux/kmsg_dump.h |  2 +-
 kernel/printk/printk.c    | 62 +++++++++++++++++++++------------------
 2 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h
index ae38035f1dca..070c994ff19f 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..ed678d84dc51 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3410,7 +3410,7 @@ EXPORT_SYMBOL_GPL(kmsg_dump_get_line);
  * @syslog: include the "<4>" prefixes
  * @buf: buffer to copy the line to
  * @size: maximum size of the buffer
- * @len: length of line placed into buffer
+ * @len_out: length of line placed into buffer
  *
  * Start at the end of the kmsg buffer and fill the provided buffer
  * with as many of the *youngest* kmsg records that fit into it.
@@ -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);
+		len += record_print_text(&r, syslog, time);
 
-		/* adjust record to store to remaining buffer space */
-		prb_rec_init_rd(&r, &info, buf + l, size - l);
-
-		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.20.1


  parent reply	other threads:[~2021-03-03 13:59 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-03 10:15 [PATCH next v4 00/15] printk: remove logbuf_lock John Ogness
2021-03-03 10:15 ` John Ogness
2021-03-03 10:15 ` John Ogness
2021-03-03 10:15 ` [PATCH next v4 01/15] um: synchronize kmsg_dumper John Ogness
2021-03-03 10:15   ` John Ogness
2021-03-03 10:15 ` [PATCH next v4 02/15] mtd: mtdoops: " John Ogness
2021-03-03 10:15   ` John Ogness
2021-03-11  9:50   ` Miquel Raynal
2021-03-11  9:50     ` Miquel Raynal
2021-03-03 10:15 ` [PATCH next v4 03/15] printk: limit second loop of syslog_print_all John Ogness
2021-03-03 10:15 ` [PATCH next v4 04/15] printk: kmsg_dump: remove unused fields John Ogness
2021-03-03 10:15 ` John Ogness [this message]
2021-03-03 10:15 ` [PATCH next v4 06/15] printk: consolidate kmsg_dump_get_buffer/syslog_print_all code John Ogness
2021-03-03 10:15 ` [PATCH next v4 07/15] printk: introduce CONSOLE_LOG_MAX John Ogness
2021-03-03 13:35   ` Petr Mladek
2021-03-03 10:15 ` [PATCH next v4 08/15] printk: use seqcount_latch for clear_seq John Ogness
2021-03-03 10:15 ` [PATCH next v4 09/15] printk: use atomic64_t for devkmsg_user.seq John Ogness
2021-03-03 10:15 ` [PATCH next v4 10/15] printk: add syslog_lock John Ogness
2021-03-03 10:15 ` [PATCH next v4 11/15] printk: kmsg_dumper: remove @active field John Ogness
2021-03-03 10:15   ` John Ogness
2021-03-03 10:15 ` [PATCH next v4 12/15] printk: introduce a kmsg_dump iterator John Ogness
2021-03-03 10:15   ` John Ogness
2021-03-03 10:15   ` John Ogness
2021-03-03 13:48   ` Petr Mladek
2021-03-03 13:48     ` Petr Mladek
2021-03-03 13:48     ` Petr Mladek
2021-03-03 10:15 ` [PATCH next v4 13/15] printk: remove logbuf_lock John Ogness
2021-03-03 10:15 ` [PATCH next v4 14/15] printk: kmsg_dump: remove _nolock() variants John Ogness
2021-03-03 10:15   ` John Ogness
2021-03-03 10:15 ` [PATCH next v4 15/15] printk: console: remove unnecessary safe buffer usage John Ogness
2021-03-03 13:18 ` lkml delivery: was: Re: [PATCH next v4 00/15] printk: remove logbuf_lock Petr Mladek
2021-03-03 13:18   ` Petr Mladek
2021-03-03 13:18   ` Petr Mladek
2021-03-03 14:34   ` Steven Rostedt
2021-03-03 14:34     ` Steven Rostedt
2021-03-03 14:34     ` Steven Rostedt
2021-03-03 15:34 ` Petr Mladek
2021-03-03 15:34   ` Petr Mladek
2021-03-03 15:34   ` Petr Mladek
2021-03-08 15:09   ` Petr Mladek
2021-03-08 15:09     ` Petr Mladek
2021-03-08 15:09     ` Petr Mladek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210303101528.29901-6-john.ogness@linutronix.de \
    --to=john.ogness@linutronix.de \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mpe@ellerman.id.au \
    --cc=pasha.tatashin@soleen.com \
    --cc=pmladek@suse.com \
    --cc=rostedt@goodmis.org \
    --cc=sergey.senozhatsky.work@gmail.com \
    --cc=sergey.senozhatsky@gmail.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.