From: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
To: Jan Kara <jack@suse.cz>
Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>,
Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>,
akpm@linux-foundation.org, jack@suse.com, pmladek@suse.com,
tj@kernel.org, linux-kernel@vger.kernel.org,
sergey.senozhatsky@gmail.com
Subject: Re: [RFC][PATCH v2 1/2] printk: Make printk() completely async
Date: Wed, 9 Mar 2016 15:09:50 +0900 [thread overview]
Message-ID: <20160309060950.GA666@swordfish> (raw)
In-Reply-To: <20160307121625.GG5201@quack.suse.cz>
Hello Jan,
On (03/07/16 13:16), Jan Kara wrote:
[..]
> > So if this will be a problem in practice, using a kthread will probably be
> > the easiest solution.
>
> Hum, and thinking more about it: Considering that WQ_MEM_RECLAIM workqueues
> create kthread anyway as a rescuer thread, it may be the simplest to just
> go back to using a single kthread for printing. What do you think?
I have this patch on top of the series now. In short, it closes one more
possibility of lockups -- console_lock()/console_unlock() calls. the patch
splits console_unlock() in two parts:
-- the fast one just wake up printing kthread
-- the slow one does call_console_drivers() loop
I think it sort of makes sense to tweak the patch below a bit and fold it
into 0001, and move _some_ of the vprintk_emit() checks to console_unlock().
very schematically, after folding, vprintk_emit() will be
if (in_sched) {
if (!printk_sync && printk_thread)
wake_up()
else
irq_work_queue()
}
if (!in_sched)
if (console_trylock())
console_unlock()
and console_unlock() will be
if (!in_panic && !printk_sync && printk_thread) {
up_console_sem()
wake_up()
} else {
console_unlock_for_printk()
}
console_unlock_for_printk() does the call_console_drivers() loop.
console_flush_on_panic() and printing_func() call console_unlock_for_printk()
directly.
What do you think? Or would you prefer to first introduce async
printk() rework, and move to console_unlock() in vprintk_emit()
one release cycle later?
IOW, in 3 steps:
-- first make printk() async
-- then console_unlock() async, and use console_unlock_for_printk() in
vprintk_emit()
-- then switch to console_unlock() in vprintk_emit().
below is the patch which introduces console_unlock_for_printk().
not the squashed console_unlock_for_printk() and 0001.
-ss
======
>From bc3932c68c5afb9bf43af98335c705c75067a93a Mon Sep 17 00:00:00 2001
From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Subject: [PATCH 3/4] printk: introduce console_unlock_for_printk()
Even though we already have asynchronous printk()->vprintk_emit(),
there are still good chances to get lockups, because we don't have
asynchronous console_unlock(). So any process doing console_lock()
and console_unlock() will end up looping in console_unlock(), pushing
the messages to console drivers (possibly with IRQs or preemption
disabled), regardless the fact that we have a dedicated kthread for
that particular job.
Apart from that, console_lock()/console_unlock() can be executed by
user processes as a part of system calls:
a) SyS_open()
...
chrdev_open()
tty_open()
console_device()
console_lock()
console_unlock()
for (;;) {
call_console_drivers()
}
b) SyS_read()
...
sysfs_read_file()
dev_attr_show()
show_cons_active()
console_lock()
console_unlock()
for (;;) {
call_console_drivers()
}
c) doing `cat /proc/consoles`
SyS_read()
vfs_read()
proc_reg_read()
seq_read()
c_stop()
console_unlock()
for (;;) {
call_console_drivers()
}
etc.
This can add unnecessary latencies to the user space processes.
This patch splits console_unlock() in two parts:
-- the fast path up() console semaphore and wake up printing kthread
(if there is one, of course), otherwise
-- the slow path: does what console_unlock() did previously, emit
the messages and then up() console semaphore
The actual printing loop is, thus, moved to a new function,
console_unlock_for_printk(). There are 3 places that
unconditionally call it:
a) direct printing from vprintk_emit()
b) console_flush_on_panic()
c) printing kthread callback
Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
kernel/printk/printk.c | 51 +++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 44 insertions(+), 7 deletions(-)
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index de45d86..ddaf62e 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -303,6 +303,8 @@ static struct task_struct *printk_thread;
/* Wait for printing wakeups from async vprintk_emit() */
static DECLARE_WAIT_QUEUE_HEAD(printing_wait);
+static void console_unlock_for_printk(void);
+
static int printing_func(void *data)
{
while (1) {
@@ -314,7 +316,7 @@ static int printing_func(void *data)
remove_wait_queue(&printing_wait, &wait);
console_lock();
- console_unlock();
+ console_unlock_for_printk();
}
return 0;
@@ -1900,7 +1902,7 @@ asmlinkage int vprintk_emit(int facility, int level,
* /dev/kmsg and syslog() users.
*/
if (console_trylock())
- console_unlock();
+ console_unlock_for_printk();
lockdep_on();
}
@@ -2339,20 +2341,20 @@ out:
#define PRINT_MSGS_BEFORE_OOPS 100
/**
- * console_unlock - unlock the console system
+ * console_unlock_for_printk - unlock the console system
*
* Releases the console_lock which the caller holds on the console system
* and the console driver list.
*
* While the console_lock was held, console output may have been buffered
- * by printk(). If this is the case, console_unlock(); emits
+ * by printk(). If this is the case, console_unlock_for_printk() emits
* the output prior to releasing the lock.
*
* If there is output waiting, we wake /dev/kmsg and syslog() users.
*
- * console_unlock(); may be called from any context.
+ * console_unlock_for_printk() may be called from any context.
*/
-void console_unlock(void)
+static void console_unlock_for_printk(void)
{
static char ext_text[CONSOLE_EXT_LOG_MAX];
static char text[LOG_LINE_MAX + PREFIX_MAX];
@@ -2511,6 +2513,41 @@ skip:
if (wake_klogd)
wake_up_klogd();
}
+
+
+/**
+ * console_unlock - unlock the console system
+ *
+ * Releases the console_lock which the caller holds on the console system.
+ *
+ * The fast path is to wake up the printing kthread (if the system can
+ * perform asynchronous printing) and return; the slow path is to emit
+ * the messages directly invoking console_unlock_for_printk().
+ *
+ * console_unlock() may be called from any context.
+ */
+void console_unlock(void)
+{
+ bool in_panic = console_loglevel == CONSOLE_LOGLEVEL_MOTORMOUTH;
+
+ if (in_panic) {
+ /*
+ * If the system is in panic console_flush_on_panic() issued
+ * from panic_cpu will flush the messages.
+ */
+ console_locked = 0;
+ up_console_sem();
+ return;
+ }
+
+ if (!printk_sync && printk_thread) {
+ console_locked = 0;
+ up_console_sem();
+ wake_up(&printing_wait);
+ } else {
+ console_unlock_for_printk();
+ }
+}
EXPORT_SYMBOL(console_unlock);
/**
@@ -2567,7 +2604,7 @@ void console_flush_on_panic(void)
*/
console_trylock();
console_may_schedule = 0;
- console_unlock();
+ console_unlock_for_printk();
}
/*
--
2.8.0.rc0.1.gd285ab0
next prev parent reply other threads:[~2016-03-09 6:08 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-05 10:55 [RFC][PATCH v2 0/2] printk: Make printk() completely async Sergey Senozhatsky
2016-03-05 10:55 ` [RFC][PATCH v2 1/2] " Sergey Senozhatsky
2016-03-06 6:32 ` Sergey Senozhatsky
2016-03-06 7:18 ` Tetsuo Handa
2016-03-06 9:35 ` Sergey Senozhatsky
2016-03-06 11:06 ` Tetsuo Handa
2016-03-06 13:27 ` Sergey Senozhatsky
2016-03-06 14:54 ` Tetsuo Handa
2016-03-07 8:22 ` Jan Kara
2016-03-07 10:12 ` Sergey Senozhatsky
2016-03-07 10:52 ` Jan Kara
2016-03-07 12:16 ` Jan Kara
2016-03-07 12:37 ` Tetsuo Handa
2016-03-07 15:10 ` Sergey Senozhatsky
2016-03-07 15:49 ` Tejun Heo
2016-03-08 10:21 ` Sergey Senozhatsky
2016-03-11 17:22 ` Tejun Heo
2016-03-12 5:01 ` Sergey Senozhatsky
2016-03-09 6:09 ` Sergey Senozhatsky [this message]
2016-03-10 9:27 ` Jan Kara
2016-03-10 15:48 ` Sergey Senozhatsky
2016-03-10 9:53 ` Petr Mladek
2016-03-10 16:26 ` Sergey Senozhatsky
2016-03-07 14:40 ` Sergey Senozhatsky
2016-03-07 11:10 ` Tetsuo Handa
2016-03-07 14:36 ` Sergey Senozhatsky
2016-03-07 15:42 ` Tejun Heo
2016-03-05 10:55 ` [RFC][PATCH v2 2/2] printk: Skip messages on oops 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=20160309060950.GA666@swordfish \
--to=sergey.senozhatsky.work@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=jack@suse.com \
--cc=jack@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=penguin-kernel@I-love.SAKURA.ne.jp \
--cc=pmladek@suse.com \
--cc=sergey.senozhatsky@gmail.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).