All of lore.kernel.org
 help / color / mirror / Atom feed
From: Joe Perches <joe@perches.com>
To: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>,
	Pavel Machek <pavel@ucw.cz>,
	Linus Torvalds <torvalds@linux-foundation.org>
Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
	Petr Mladek <pmladek@suse.com>,
	Steven Rostedt <rostedt@goodmis.org>, Jan Kara <jack@suse.cz>,
	Andrew Morton <akpm@linux-foundation.org>,
	Jiri Slaby <jslaby@suse.com>, Andreas Mohr <andi@lisas.de>,
	Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>,
	linux-kernel@vger.kernel.org
Subject: Re: printk: what is going on with additional newlines?
Date: Tue, 29 Aug 2017 09:37:10 -0700	[thread overview]
Message-ID: <1504024630.2040.25.camel@perches.com> (raw)
In-Reply-To: <20170829134048.GA437@jagdpanzerIV.localdomain>

On Tue, 2017-08-29 at 22:40 +0900, Sergey Senozhatsky wrote:
> Hi,
> 
> so I had a second look, and I think the patch I posted yesterday is
> pretty wrong. How about something like below?

> ---
> 
> From d65d1b74d3acc51e5d998c5d2cf10d20c28dc2f9 Mon Sep 17 00:00:00 2001
> From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> Date: Tue, 29 Aug 2017 22:30:07 +0900
> Subject: [PATCH] printk: restore non-log_prefix messages handling
> 
> Pavel reported that
> 	printk("foo"); printk("bar");
> 
> now does not produce a single continuation "foobar" line, but
> instead produces two lines
> 		foo
> 		bar
> 
> The first printk() goes to cont buffer, just as before. The difference
> is how we handle the second one. We used to just add it to the cont
> buffer:
> 
> 	if (!(lflags & LOG_NEWLINE)) {
> 		if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
> 			cont_flush();
> 
> 		cont_add(...)
> 	}
> 
> but now we flush the existing cont buffer and store the second
> printk() message separately:
> 
> 	if (cont.len) {
> 		if (cont.owner == current && (lflags & LOG_CONT))
> 			return cont_add();
> 
> 		/* otherwise flush */
> 		cont_flush();
> 	}
> 
> because printk("bar") does not have LOG_CONT.
> 
> The patch restores the old behaviour.
> 
> To verify the change I did the following printk() test again the v4.5
> and patched linux-next:

It's possibly dubious to go back to v4.5 behavior.
Linus changed the
printk continuation behavior in v4.9
Unfortunately he did this without
posting anything to lkml
for comment and he broke a bunch of continuation
printks.


>  pr_err("foo"); pr_cont("bar"); pr_cont("bar\n");
>  printk("foo"); printk("foo"); printk("bar\n");
> 
>  printk("baz"); printk("baz"); printk("baz"); pr_info("INFO foo");
>  printk("baz"); printk("baz"); printk("baz"); pr_err("ERR foo");
> 
>  printk(KERN_CONT"foo"); printk(KERN_CONT"foo"); printk(KERN_CONT"bar\n");
>  printk(KERN_CONT"foo"); printk(KERN_CONT"foo"); printk(KERN_ERR"bar\n");
> 
>  printk(KERN_CONT"foo"); printk(KERN_ERR"foo err"); printk(KERN_ERR "ERR foo\n");
> 
>  printk("baz"); printk("baz"); printk("baz"); pr_info("INFO foo\n");
>  printk("baz"); printk("baz"); printk("baz"); pr_err("ERR foo\n");
> 
>  printk(KERN_INFO "foo"); printk(KERN_CONT "bar\n"); printk(KERN_CONT "bar\n");
> 
> I, however, got a slightly different output (I'll explain the difference):
> 
> 	v4.5                    linux-next
> 
> 	foobarbar               foobarbar
> 	foofoobar               foofoobar
> 	bazbazbaz               bazbazbaz
> 	INFO foo                INFO foobazbazbaz
> 	bazbazbaz
> 	ERR foo                 ERR foofoofoobar
> 	foofoobar
> 	foofoo                  foofoo
> 	bar                     bar
> 	foo                     foo
> 	foo err                 foo err
> 	ERR foo                 ERR foo
> 	bazbazbaz               bazbazbaz
> 	INFO foo                INFO foo
> 	bazbazbaz               bazbazbaz
> 	ERR foo                 ERR foo
> 	foobar                  foobar
> 	bar                     bar
> 
> As we can see the difference is in:
>    pr_info("INFO foo"); printk(KERN_CONT"foo"); printk(KERN_CONT"foo")...
> and
>    pr_err("ERR foo"); printk(KERN_CONT"foo"); printk(KERN_CONT"foo");...
> handling.
> 
> The output is expected to be two continuation lines; but this is not
> the case for old kernels.
> 
> What the old kernel does here is:
> 
> - it sees that cont buffer already has data: all those !LOG_PREFIX messages
> 
> - it also sees that the current messages is LOG_PREFIX and that part of
>   the cont buffer was already printed to the serial console:
> 
> 	// Flush the conflicting buffer. An earlier newline was missing
> 	// or another task also prints continuation lines
> 
> 	if (!(lflags & LOG_NEWLINE)) {
> 		if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
> 			cont_flush(LOG_NEWLINE);
> 
> 		if (cont_add(text))
> 			printed_len += text_len;
> 		else
> 			printed_len += log_store(text);
> 	}
> 
>   the problem here is that, flush does not actually flush the buffer and
>   does not reset the conf buffer state, but sets cont.flushed to true
>   instead:
> 
> 	if (cont.cons) {
> 		log_store(cont.text);
> 		cont.flags = flags;
> 		cont.flushed = true;
> 	}
> 
> - then the kernel attempts to cont_add() the messages. but cont_add() does
>   not append the messages to the cont buffer, because of this check
> 
> 	if (cont.len && cont.flushed)
> 		return false;
> 
>   both cont.len and cont.flushed are true. because the kernel waits for
>   console_unlock() to call console_cont_flush()->cont_print_text(),
>   which should print the cont.text to the serial console and reset the
>   cont buffer state.
> 
> - but cont_print_text() must be called under logbuf_lock lock, which
>   we still hold in vprintk_emit(). so the kernel has no chance to flush
>   the cont buffer and thus cont_add() fails there and forces the kernel
>   to log_store() the message, allocating a separate logbuf entry for
>   it.
> 
> That's why we see the difference in v4.5 vs linux-next logs. This is
> visible only when !LOG_NEWLINE path has to cont_flush() partially
> printed cont buffer from under the logbuf_lock.
> 
> I think the old behavior had a bug - we need to concatenate
> 
> 	KERN_ERR foo; KERN_CONT bar; KERN_CON bar\n;
> 
> regardless the previous cont buffer state.
> 
> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> Reported-by: Pavel Machek <pavel@ucw.cz>
> ---
>  kernel/printk/printk.c | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index ac1fd606d6c5..be868b7d9ceb 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -1914,12 +1914,17 @@ static size_t log_output(int facility, int level, enum log_flags lflags, const c
>  	 * write from the same process, try to add it to the buffer.
>  	 */
>  	if (cont.len) {
> -		if (cont.owner == current && (lflags & LOG_CONT)) {
> +		/*
> +		 * Flush the conflicting buffer. An earlier newline was missing,
> +		 * or another task also prints continuation lines.
> +		 */
> +		if (lflags & LOG_PREFIX || cont.owner != current)
> +			cont_flush();
> +
> +		if (!(lflags & LOG_PREFIX) || lflags & LOG_CONT) {
>  			if (cont_add(facility, level, lflags, text, text_len))
>  				return text_len;
>  		}
> -		/* Otherwise, make sure it's flushed */
> -		cont_flush();
>  	}
>  
>  	/* Skip empty continuation lines that couldn't be added - they just flush */

  reply	other threads:[~2017-08-29 16:37 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-15  2:56 [RFC][PATCHv5 00/13] printk: introduce printing kernel thread Sergey Senozhatsky
2017-08-15  2:56 ` [RFC][PATCHv5 01/13] printk: move printk_pending out of per-cpu Sergey Senozhatsky
2017-08-15  2:56 ` [RFC][PATCHv5 02/13] printk: introduce printing kernel thread Sergey Senozhatsky
2017-08-15  2:56 ` [RFC][PATCHv5 03/13] printk: add sync printk_emergency API Sergey Senozhatsky
2017-08-15  2:56 ` [RFC][PATCHv5 04/13] printk: add enforce_emergency parameter Sergey Senozhatsky
2017-08-15  2:56 ` [RFC][PATCHv5 05/13] printk: enable printk offloading Sergey Senozhatsky
2017-08-15  2:56 ` [RFC][PATCHv5 06/13] printk: register PM notifier Sergey Senozhatsky
2017-08-15 11:51   ` Rafael J. Wysocki
2017-08-16  7:31     ` Sergey Senozhatsky
2017-08-16 12:58       ` Rafael J. Wysocki
2017-08-17  5:55         ` Sergey Senozhatsky
2017-08-17 15:43           ` Rafael J. Wysocki
2017-08-17 23:19             ` Sergey Senozhatsky
2017-08-15  2:56 ` [RFC][PATCHv5 07/13] printk: register syscore notifier Sergey Senozhatsky
2017-08-15 11:56   ` Rafael J. Wysocki
2017-08-16  6:55     ` Sergey Senozhatsky
2017-08-16 12:59       ` Rafael J. Wysocki
2017-08-15  2:56 ` [RFC][PATCHv5 08/13] printk: set watchdog_thresh as maximum value for atomic_print_limit Sergey Senozhatsky
2017-08-15  2:56 ` [RFC][PATCHv5 09/13] printk: add auto-emergency enforcement mechanism Sergey Senozhatsky
2017-08-15  2:56 ` [RFC][PATCHv5 10/13] printk: force printk_kthread to offload printing Sergey Senozhatsky
2017-08-15  2:56 ` [RFC][PATCHv5 11/13] printk: always offload printing from user-space processes Sergey Senozhatsky
2017-08-15  2:56 ` [RFC][PATCHv5 12/13] printk: do not cond_resched() when we can offload Sergey Senozhatsky
2017-08-15  2:56 ` [RFC][PATCHv5 13/13] printk: move offloading logic to per-cpu Sergey Senozhatsky
2017-08-23  8:33 ` [RFC][PATCHv5 00/13] printk: introduce printing kernel thread Sergey Senozhatsky
2017-08-28  9:05 ` printk: what is going on with additional newlines? Pavel Machek
2017-08-28 10:28   ` Sergey Senozhatsky
2017-08-28 12:21     ` Sergey Senozhatsky
2017-08-28 12:38       ` Sergey Senozhatsky
2017-08-28 12:46       ` Pavel Machek
2017-08-29 13:40         ` Sergey Senozhatsky
2017-08-29 16:37           ` Joe Perches [this message]
2017-08-29 17:00           ` Linus Torvalds
2017-08-29 17:12             ` Linus Torvalds
2017-08-29 20:41               ` Tetsuo Handa
2017-08-29 20:51                 ` Linus Torvalds
2017-09-02  6:12                   ` Tetsuo Handa
2017-09-02 17:06                     ` Linus Torvalds
2017-08-29 23:50               ` Steven Rostedt
2017-08-29 23:59                 ` Linus Torvalds
2017-08-30  1:03                 ` Sergey Senozhatsky
2017-08-30  1:10                   ` Steven Rostedt
2017-08-30  1:51                     ` Sergey Senozhatsky
2017-08-30  1:52                     ` Joe Perches
2017-08-30  2:25                       ` Sergey Senozhatsky
2017-08-30  2:31                         ` Joe Perches
2017-08-30  2:47                           ` Sergey Senozhatsky
2017-08-30  2:58                             ` Joe Perches
2017-08-30  5:37                               ` Sergey Senozhatsky
2017-09-08 10:18                                 ` Pavel Machek
2017-09-05  9:44                             ` Petr Mladek
2017-09-05  9:59                               ` Sergey Senozhatsky
2017-09-05 12:21                                 ` Petr Mladek
2017-09-05 12:35                                   ` Tetsuo Handa
2017-09-05 14:18                                     ` Sergey Senozhatsky
2017-09-05 13:42                                   ` Sergey Senozhatsky
2017-09-06  7:55                                     ` Petr Mladek
2017-09-17  6:26                                       ` Sergey Senozhatsky
2017-09-17  9:27                                         ` Sergey Senozhatsky
2017-09-17 15:35                                         ` Linus Torvalds
2017-09-18  0:46                                           ` Sergey Senozhatsky
2017-09-18  2:22                                             ` Joe Perches
2017-09-18  2:41                                               ` Sergey Senozhatsky
2017-09-18  2:45                                                 ` Joe Perches
2017-09-18  2:55                                                   ` Sergey Senozhatsky
2017-09-18  3:07                                                     ` Joe Perches
2017-09-18  4:42                                                       ` Sergey Senozhatsky
2017-09-01 13:19                     ` Sergey Senozhatsky
2017-09-01 17:32                       ` Joe Perches
2017-09-01 20:21                         ` Linus Torvalds
2017-09-04  5:22                           ` Sergey Senozhatsky
2017-09-04  5:41                             ` Joe Perches
2017-09-05 14:54                             ` Steven Rostedt
2017-09-06  2:14                               ` Sergey Senozhatsky
2017-09-06  2:36                               ` Linus Torvalds
2017-09-04  4:30                         ` Sergey Senozhatsky
2017-09-04  5:24                           ` Sergey Senozhatsky
2017-08-29 17:33             ` Sergey Senozhatsky
2017-08-29 17:52               ` Linus Torvalds
2017-08-29 18:09                 ` Joe Perches
2017-08-30  1:07                   ` Sergey Senozhatsky
2017-08-30  0:58                 ` Sergey Senozhatsky
2017-08-29 16:48   ` Linus Torvalds
2017-08-29 17:10     ` Joe Perches
2017-08-29 17:20       ` Linus Torvalds
2017-08-29 17:33         ` Joe Perches
2017-08-29 17:36           ` Linus Torvalds
2017-08-29 17:48             ` Joe Perches
2017-08-29 20:24     ` Pavel Machek
2017-09-01  1:40       ` Sergey Senozhatsky
2017-09-01  2:04         ` Joe Perches
2017-09-01  6:59           ` Pavel Machek
2017-09-01  7:23             ` Joe Perches
2017-09-01  7:29         ` Pavel Machek
2017-09-01 11:13           ` Steven Rostedt

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=1504024630.2040.25.camel@perches.com \
    --to=joe@perches.com \
    --cc=akpm@linux-foundation.org \
    --cc=andi@lisas.de \
    --cc=jack@suse.cz \
    --cc=jslaby@suse.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pavel@ucw.cz \
    --cc=penguin-kernel@I-love.SAKURA.ne.jp \
    --cc=pmladek@suse.com \
    --cc=rostedt@goodmis.org \
    --cc=sergey.senozhatsky.work@gmail.com \
    --cc=sergey.senozhatsky@gmail.com \
    --cc=torvalds@linux-foundation.org \
    /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.