From: Jan Kiszka <jan.kiszka@siemens.com>
To: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: RT <linux-rt-users@vger.kernel.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Steven Rostedt <rostedt@goodmis.org>,
Mike Galbraith <umgwanakikbuti@gmail.com>
Subject: [PATCH v2 RT 3.18] irq_work: Provide a soft-irq based queue
Date: Thu, 23 Apr 2015 09:35:59 +0200 [thread overview]
Message-ID: <5538A0DF.50401@siemens.com> (raw)
Instead of turning all irq_work requests into lazy ones on -rt, just
move their execution from hard into soft-irq context.
This resolves deadlocks of ftrace which will queue work from arbitrary
contexts, including those that have locks held that are needed for
raising a soft-irq.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
Changes in v2:
- fix execution of raised list (discovered by Mike Galbraith)
- added comment of irq_work_run (derived from Mike's suggestion)
kernel/irq_work.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/kernel/irq_work.c b/kernel/irq_work.c
index 9dda38a..171dfac 100644
--- a/kernel/irq_work.c
+++ b/kernel/irq_work.c
@@ -85,12 +85,9 @@ bool irq_work_queue_on(struct irq_work *work, int cpu)
raise_irqwork = llist_add(&work->llnode,
&per_cpu(hirq_work_list, cpu));
else
- raise_irqwork = llist_add(&work->llnode,
- &per_cpu(lazy_list, cpu));
-#else
+#endif
raise_irqwork = llist_add(&work->llnode,
&per_cpu(raised_list, cpu));
-#endif
if (raise_irqwork)
arch_send_call_function_single_ipi(cpu);
@@ -114,21 +111,20 @@ bool irq_work_queue(struct irq_work *work)
if (work->flags & IRQ_WORK_HARD_IRQ) {
if (llist_add(&work->llnode, this_cpu_ptr(&hirq_work_list)))
arch_irq_work_raise();
- } else {
+ } else
+#endif
+ if (work->flags & IRQ_WORK_LAZY) {
if (llist_add(&work->llnode, this_cpu_ptr(&lazy_list)) &&
tick_nohz_tick_stopped())
+#ifdef CONFIG_PREEMPT_RT_FULL
raise_softirq(TIMER_SOFTIRQ);
- }
#else
- if (work->flags & IRQ_WORK_LAZY) {
- if (llist_add(&work->llnode, this_cpu_ptr(&lazy_list)) &&
- tick_nohz_tick_stopped())
arch_irq_work_raise();
+#endif
} else {
if (llist_add(&work->llnode, this_cpu_ptr(&raised_list)))
arch_irq_work_raise();
}
-#endif
preempt_enable();
@@ -202,6 +198,13 @@ void irq_work_run(void)
{
#ifdef CONFIG_PREEMPT_RT_FULL
irq_work_run_list(this_cpu_ptr(&hirq_work_list));
+ /*
+ * NOTE: we raise softirq via IPI for safety (caller may hold locks
+ * that raise_softirq needs) and execute in irq_work_tick() to move
+ * the overhead from hard to soft irq context.
+ */
+ if (!llist_empty(this_cpu_ptr(&raised_list)))
+ raise_softirq(TIMER_SOFTIRQ);
#else
irq_work_run_list(this_cpu_ptr(&raised_list));
irq_work_run_list(this_cpu_ptr(&lazy_list));
@@ -211,15 +214,12 @@ EXPORT_SYMBOL_GPL(irq_work_run);
void irq_work_tick(void)
{
-#ifdef CONFIG_PREEMPT_RT_FULL
- irq_work_run_list(this_cpu_ptr(&lazy_list));
-#else
- struct llist_head *raised = &__get_cpu_var(raised_list);
+ struct llist_head *raised = this_cpu_ptr(&raised_list);
- if (!llist_empty(raised) && !arch_irq_work_has_interrupt())
+ if (!llist_empty(raised) && (!arch_irq_work_has_interrupt() ||
+ IS_ENABLED(CONFIG_PREEMPT_RT_FULL)))
irq_work_run_list(raised);
- irq_work_run_list(&__get_cpu_var(lazy_list));
-#endif
+ irq_work_run_list(this_cpu_ptr(&lazy_list));
}
/*
--
2.1.4
next reply other threads:[~2015-04-23 7:36 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-23 7:35 Jan Kiszka [this message]
2015-05-14 19:58 ` [PATCH v2 RT 3.18] irq_work: Provide a soft-irq based queue Sebastian Andrzej Siewior
2015-05-15 7:43 ` Jan Kiszka
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=5538A0DF.50401@siemens.com \
--to=jan.kiszka@siemens.com \
--cc=bigeasy@linutronix.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-users@vger.kernel.org \
--cc=rostedt@goodmis.org \
--cc=umgwanakikbuti@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.