From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
To: Petr Mladek <pmladek@suse.com>, Steven Rostedt <rostedt@goodmis.org>
Cc: Jan Kara <jack@suse.cz>,
Andrew Morton <akpm@linux-foundation.org>,
Peter Zijlstra <peterz@infradead.org>,
"Rafael J . Wysocki" <rjw@rjwysocki.net>,
Eric Biederman <ebiederm@xmission.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Jiri Slaby <jslaby@suse.com>, Pavel Machek <pavel@ucw.cz>,
Andreas Mohr <andi@lisas.de>,
Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>,
linux-kernel@vger.kernel.org,
Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
Subject: [RFC][PATCHv5 13/13] printk: move offloading logic to per-cpu
Date: Tue, 15 Aug 2017 11:56:25 +0900 [thread overview]
Message-ID: <20170815025625.1977-14-sergey.senozhatsky@gmail.com> (raw)
In-Reply-To: <20170815025625.1977-1-sergey.senozhatsky@gmail.com>
We have a global offloading state and make the offloading
decision based on printing task pointer and timestamp. If
we keep seeing the same task performing printing for too
long (`atomic_print_limit') we request offloading. Similarly
when we see that printing is now performed by another task,
we reset the timestamp counter.
This, however, will not work in the following case:
===============================================================================
CPU0 CPU1
//taskA //taskB
preempt_disable() preempt_disable()
printk()
console_trylock()
console_unlock()
printing_task = taskA
up()
printk()
console_trylock()
console_unlock()
printing_task = taskB
^^^ reset offloading control
up()
printk()
console_trylock()
console_unlock()
printing_task = taskA
^^^ reset offloading control
up()
printk()
console_trylock()
console_unlock()
printing_task = taskB
^^^ reset offloading control
up()
/*
* X seconds later
*/
printk()
console_trylock()
console_unlock()
printing_task = taskA
^^^ reset offloading control
up()
printk()
console_trylock()
console_unlock()
printing_task = taskB
^^^ reset offloading control
up()
lockup! lockup!
===============================================================================
So this printk ping-pong confuses our offloading control logic.
Move it to per-CPU area and have a separate offloading control
on every CPU.
Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
kernel/printk/printk.c | 36 ++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index ba82152ce5d9..f9799616e9fc 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -558,13 +558,14 @@ static inline void adj_atomic_print_limit(void)
#endif
}
-static inline unsigned long emergency_timeout(unsigned long ts)
+static inline unsigned long emergency_timeout(unsigned long now,
+ unsigned long ts)
{
#ifdef CONFIG_LOCKUP_DETECTOR
if (watchdog_thresh)
- return ts + 2 * watchdog_thresh;
+ return time_after_eq(now, ts + 2 * watchdog_thresh);
#endif
- return ts + 10 * atomic_print_limit;
+ return time_after_eq(now, ts + 10 * atomic_print_limit);
}
/*
@@ -574,13 +575,13 @@ static inline unsigned long emergency_timeout(unsigned long ts)
* amount of time a process can print from console_unlock().
*
* This function must be called from 'printk_safe' context under
- * console_sem lock.
+ * console_sem lock with preemption disabled.
*/
static inline bool console_offload_printing(void)
{
- static struct task_struct *printing_task;
- static unsigned long printing_start_ts;
- static unsigned long saved_csw;
+ static DEFINE_PER_CPU(struct task_struct, *printing_task);
+ static DEFINE_PER_CPU(unsigned long, printing_start_ts);
+ static DEFINE_PER_CPU(unsigned long, saved_csw);
unsigned long now = local_clock() >> 30LL; /* seconds */
if (printk_kthread_should_stop())
@@ -600,16 +601,17 @@ static inline bool console_offload_printing(void)
goto offload;
/* A new task - reset the counters. */
- if (printing_task != current) {
- printing_start_ts = local_clock() >> 30LL;
- saved_csw = current->nvcsw + current->nivcsw;
- printing_task = current;
+ if (this_cpu_read(printing_task) != current) {
+ this_cpu_write(printing_start_ts, local_clock() >> 30LL);
+ this_cpu_write(saved_csw, current->nvcsw + current->nivcsw);
+ this_cpu_write(printing_task, current);
return false;
}
adj_atomic_print_limit();
- if (!time_after_eq(now, printing_start_ts + atomic_print_limit))
+ if (!time_after_eq(now, this_cpu_read(printing_start_ts) +
+ atomic_print_limit))
return false;
if (current == printk_kthread) {
@@ -626,7 +628,7 @@ static inline bool console_offload_printing(void)
* back to console_unlock(), it will have another full
* `atomic_print_limit' time slice.
*/
- printing_start_ts = local_clock() >> 30LL;
+ this_cpu_write(printing_start_ts, local_clock() >> 30LL);
return true;
}
@@ -634,10 +636,12 @@ static inline bool console_offload_printing(void)
* A trivial emergency enforcement - give up on printk_kthread if
* we can't wake it up.
*/
- if (time_after_eq(now, emergency_timeout(printing_start_ts)) &&
- saved_csw == (current->nvcsw + current->nivcsw)) {
+ if (this_cpu_read(saved_csw) == (current->nvcsw + current->nivcsw)
+ && emergency_timeout(now, this_cpu_read(printing_start_ts))) {
+
printk_enforce_emergency = true;
- pr_crit("Declaring printk emergency mode.\n");
+ pr_crit("CPU%d declared a printk emergency mode.\n",
+ smp_processor_id());
return true;
}
--
2.14.1
next prev parent reply other threads:[~2017-08-15 3:01 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 ` Sergey Senozhatsky [this message]
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
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=20170815025625.1977-14-sergey.senozhatsky@gmail.com \
--to=sergey.senozhatsky@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=andi@lisas.de \
--cc=ebiederm@xmission.com \
--cc=gregkh@linuxfoundation.org \
--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=peterz@infradead.org \
--cc=pmladek@suse.com \
--cc=rjw@rjwysocki.net \
--cc=rostedt@goodmis.org \
--cc=sergey.senozhatsky.work@gmail.com \
/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.