All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
To: sergey.senozhatsky.work@gmail.com
Cc: tj@kernel.org, akpm@linux-foundation.org, calvinowens@fb.com,
	davej@codemonkey.org.uk, jack@suse.com, kyle@kernel.org,
	stable@vger.kernel.org, mm-commits@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: + printk-do-cond_resched-between-lines-while-outputting-to-consoles.patch added to -mm tree
Date: Thu, 3 Dec 2015 11:39:33 +0900	[thread overview]
Message-ID: <20151203023932.GB510@swordfish> (raw)
In-Reply-To: <20151203011129.GA510@swordfish>

On (12/03/15 10:11), Sergey Senozhatsky wrote:
> On (12/02/15 15:57), akpm@linux-foundation.org wrote:
> [..]
> > @console_may_schedule tracks whether console_sem was acquired through lock
> > or trylock.  If the former, we're inside a sleepable context and
> > console_conditional_schedule() performs cond_resched().  This allows
> > console drivers which use console_lock for synchronization to yield while
> > performing time-consuming operations such as scrolling.
> > 
> > However, the actual console outputting is performed while holding irq-safe
> > logbuf_lock, so console_unlock() clears @console_may_schedule before
> > starting outputting lines.  Also, only a few drivers call
> > console_conditional_schedule() to begin with.  This means that when a lot
> > of lines need to be output by console_unlock(), for example on a console
> > registration, the task doing console_unlock() may not yield for a long
> > time on a non-preemptible kernel.
> > 
> > If this happens with a slow console devices, for example a serial console,
> > the outputting task may occupy the cpu for a very long time.  Long enough
> > to trigger softlockup and/or RCU stall warnings, which in turn pile more
> > messages, sometimes enough to trigger the next cycle of warnings
> > incapacitating the system.
> > 
> > Fix it by making console_unlock() insert cond_resched() between lines if
> > @console_may_schedule.
> 
> CPU2 still can cause lots of troubles. consider
> 
> CPU0		CPU1			CPU2
> printk		
> ...		printk_deferred		
> printk					wake_up_klogd
> 						wake_up_klogd_work_func
> 							console_trylock
> 								console_unlock
> 
> printk_deferred() may be issued by scheduler, for example.

IOW, may be we can start limiting the number of bytes printed in console_unlock()
from irq contexts. Which is quite ugly, yes. We basically don't know how much time
we spend in call_console_drivers(); some of the consoles can do 'internal' spin_lock
loops in ->write() handlers, etc. So something like this (below) probably will not
really help, but still it's not always OK to do `while (1)' loop in console_unlock()
for irqs.

	-ss

(not even compile tested)

---

 kernel/printk/printk.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 9da39e7..221a230 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2235,6 +2235,7 @@ void console_unlock(void)
 	unsigned long flags;
 	bool wake_klogd = false;
 	bool do_cond_resched, retry;
+	int printed, irq_count = irq_count();
 
 	if (console_suspended) {
 		up_console_sem();
@@ -2257,6 +2258,7 @@ void console_unlock(void)
 	/* flush buffered message fragment immediately to console */
 	console_cont_flush(text, sizeof(text));
 again:
+	printed = 0;
 	for (;;) {
 		struct printk_log *msg;
 		size_t ext_len = 0;
@@ -2326,6 +2328,8 @@ skip:
 
 		if (do_cond_resched)
 			cond_resched();
+		if (irq_count && printed > LOG_LINE_MAX)
+			break;
 	}
 	console_locked = 0;
 
@@ -2344,7 +2348,7 @@ skip:
 	 * flush, no worries.
 	 */
 	raw_spin_lock(&logbuf_lock);
-	retry = console_seq != log_next_seq;
+	retry = (console_seq != log_next_seq) && !!irq_count;
 	raw_spin_unlock_irqrestore(&logbuf_lock, flags);
 
 	if (retry && console_trylock())


  reply	other threads:[~2015-12-03  2:43 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-02 23:57 + printk-do-cond_resched-between-lines-while-outputting-to-consoles.patch added to -mm tree akpm
2015-12-03  1:11 ` Sergey Senozhatsky
2015-12-03  2:39   ` Sergey Senozhatsky [this message]
2015-12-03  9:57     ` Jan Kara
2015-12-04  0:29       ` Sergey Senozhatsky

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=20151203023932.GB510@swordfish \
    --to=sergey.senozhatsky.work@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=calvinowens@fb.com \
    --cc=davej@codemonkey.org.uk \
    --cc=jack@suse.com \
    --cc=kyle@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mm-commits@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tj@kernel.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.