From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: linux-rt-users@vger.kernel.org
Cc: mingo@elte.hu, tglx@linutronix.de, dvhltc@us.ibm.com,
tytso@us.ibm.com, a.p.zijlstra@chello.nl,
dmitry.torokhov@gmail.com, akpm@linux-foundation.org,
nickpiggin@yahoo.com.au
Subject: [PATCH RFC -rt] updated synchronize_all_irqs implementation
Date: Sun, 23 Sep 2007 10:34:32 -0700 [thread overview]
Message-ID: <20070923173432.GA10542@linux.vnet.ibm.com> (raw)
In-Reply-To: <20070921054656.GA11708@linux.vnet.ibm.com>
Hello!
This updated patch adds a sychronize_all_irqs(), which waits for
all outstanding interrupt handlers, both threaded and IRQF_NODELAY,
to complete. This functionality is provided in non-rt kernels by
synchronize_sched(), but this approach fails in face of the threaded
interrupt handlers present in -rt. The trick sychronize_all_irqs() uses
is to recognize that it has no way of waiting for pending interrupts that
have not yet made it to the CPU, and that the existing synchronize_irq()
will in fact fail to wait for delivered interrupts that have not yet
managed to set the IRQ_INPROGRESS status flag.
This patch takes this thought one step farther, and guarantees only to
wait for interrupts that have already started executing in their handler.
This patch pushes the rcu_read_lock() and rcu_read_unlock() doen into
handle_IRQ_event() to as to avoid problems with the do-while loop in
thread_adge_irq().
Passes light testing (five rounds of kernbench) on an x86_64 box.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
include/linux/hardirq.h | 4 +++-
kernel/irq/handle.c | 2 ++
kernel/irq/manage.c | 25 +++++++++++++++++++++++++
3 files changed, 30 insertions(+), 1 deletion(-)
diff -urpNa -X dontdiff linux-2.6.23-rc4-rt1/include/linux/hardirq.h linux-2.6.23-rc4-rt1-sairq/include/linux/hardirq.h
--- linux-2.6.23-rc4-rt1/include/linux/hardirq.h 2007-09-20 17:34:52.000000000 -0700
+++ linux-2.6.23-rc4-rt1-sairq/include/linux/hardirq.h 2007-09-20 18:35:53.000000000 -0700
@@ -105,8 +105,10 @@
#ifdef CONFIG_SMP
extern void synchronize_irq(unsigned int irq);
+extern void synchronize_all_irqs(void);
#else
-# define synchronize_irq(irq) barrier()
+# define synchronize_irq(irq) barrier()
+# define synchronize_all_irqs(irq) barrier()
#endif
struct task_struct;
diff -urpNa -X dontdiff linux-2.6.23-rc4-rt1/kernel/irq/handle.c linux-2.6.23-rc4-rt1-sairq/kernel/irq/handle.c
--- linux-2.6.23-rc4-rt1/kernel/irq/handle.c 2007-09-20 17:34:51.000000000 -0700
+++ linux-2.6.23-rc4-rt1-sairq/kernel/irq/handle.c 2007-09-22 23:34:13.000000000 -0700
@@ -150,7 +150,9 @@ irqreturn_t handle_IRQ_event(unsigned in
do {
unsigned int preempt_count = preempt_count();
+ rcu_read_lock();
ret = action->handler(irq, action->dev_id);
+ rcu_read_unlock();
if (preempt_count() != preempt_count) {
stop_trace();
print_symbol("BUG: unbalanced irq-handler preempt count in %s!\n", (unsigned long) action->handler);
diff -urpNa -X dontdiff linux-2.6.23-rc4-rt1/kernel/irq/manage.c linux-2.6.23-rc4-rt1-sairq/kernel/irq/manage.c
--- linux-2.6.23-rc4-rt1/kernel/irq/manage.c 2007-09-20 17:34:51.000000000 -0700
+++ linux-2.6.23-rc4-rt1-sairq/kernel/irq/manage.c 2007-09-22 23:34:15.000000000 -0700
@@ -45,6 +45,30 @@ void synchronize_irq(unsigned int irq)
EXPORT_SYMBOL(synchronize_irq);
/**
+ * synchronize_all_irqs - wait for all pending IRQ handlers (on other CPUs)
+ *
+ * This function waits for any pending IRQ handlers for this interrupt
+ * to complete before returning. If you use this function while
+ * holding a resource the IRQ handler may need you will deadlock.
+ * If you use this function from an IRQ handler, you will immediately
+ * self-deadlock.
+ *
+ * Note that this function waits for -handlers-, not for pending
+ * interrupts, and most especially not for pending interrupts that
+ * have not yet been delivered to the CPU. So if an interrupt
+ * handler was just about to start executing when this function was
+ * called, and if there are no other interrupt handlers executing,
+ * this function is within its rights to return immediately.
+ */
+void synchronize_all_irqs(void)
+{
+ if (hardirq_preemption)
+ synchronize_rcu(); /* wait for threaded irq handlers. */
+ synchronize_sched(); /* wait for hardware irq handlers. */
+}
+EXPORT_SYMBOL_GPL(synchronize_all_irqs);
+
+/**
* irq_can_set_affinity - Check if the affinity of a given irq can be set
* @irq: Interrupt to check
*
@@ -886,3 +910,4 @@ void __init early_init_hardirqs(void)
for (i = 0; i < NR_IRQS; i++)
init_waitqueue_head(&irq_desc[i].wait_for_handler);
}
+
next prev parent reply other threads:[~2007-09-23 17:34 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-21 5:46 [PATCH RFC -rt] synchronize_all_irqs implementation Paul E. McKenney
2007-09-23 17:34 ` Paul E. McKenney [this message]
2007-09-25 17:22 ` [PATCH RFC -rt] updated " Steven Rostedt
2007-09-25 19:34 ` Paul E. McKenney
2007-09-25 20:02 ` Steven Rostedt
2007-09-25 23:24 ` Peter Zijlstra
2007-09-26 1:11 ` Paul E. McKenney
2007-09-26 8:28 ` Peter Zijlstra
2007-09-26 13:03 ` Paul E. McKenney
2007-09-26 13:16 ` Dmitry Torokhov
2007-09-26 15:56 ` Paul E. McKenney
2007-09-26 17:19 ` Dmitry Torokhov
2007-09-26 17:43 ` Paul E. McKenney
2007-09-26 17:47 ` Steven Rostedt
2007-09-26 17:44 ` Steven Rostedt
2007-09-26 19:55 ` Paul E. McKenney
2007-09-26 20:54 ` Peter Zijlstra
2007-09-26 21:07 ` Steven Rostedt
2007-09-26 21:42 ` Paul E. McKenney
2007-09-27 14:24 ` Dmitry Torokhov
2007-09-27 14:28 ` Steven Rostedt
2007-09-27 14:32 ` Dmitry Torokhov
2007-09-26 21:22 ` Paul E. McKenney
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=20070923173432.GA10542@linux.vnet.ibm.com \
--to=paulmck@linux.vnet.ibm.com \
--cc=a.p.zijlstra@chello.nl \
--cc=akpm@linux-foundation.org \
--cc=dmitry.torokhov@gmail.com \
--cc=dvhltc@us.ibm.com \
--cc=linux-rt-users@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=nickpiggin@yahoo.com.au \
--cc=tglx@linutronix.de \
--cc=tytso@us.ibm.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.