* [PATCH/RFC] init_hardirqs shouldn't call start_irq_thread
@ 2008-10-02 3:01 Paul Gortmaker
0 siblings, 0 replies; only message in thread
From: Paul Gortmaker @ 2008-10-02 3:01 UTC (permalink / raw)
To: linux-rt-users
This might be interesting to anyone who has seen sporadic boot failures
with the RT patches (of any version). I was trying to solve such a
problem earlier this week and eventually came up with this.
I found that in the 2.6.27-rcN patchset, that we could end up with
the timer IRQ threaded, even though it was explicitly IRQF_NODELAY.
[As an interesting side note, with an SMP configuration, the boot
would suprisingly be OK with the timer IRQ as threaded...]
Looking at the 2.6.26.5 patchset, I see nothing different there which
would indicate the problem is 2.6.27 specific. I've not been able to
re-create the problem on 2.6.26.5; however I did test that the same
fix below applies to the 2.6.26.5-rt9 and doesn't obviously break
anything.
Paul.
----------
commit e33ed4611eb24fc267ef8326572d488588f37959
Author: Paul Gortmaker <paul.gortmaker@windriver.com>
Date: Wed Oct 1 19:30:52 2008 -0700
There are two ways that start_irq_thread() can be called; either
as a part of setup_irq() for flags !IRQF_NODELAY, or as a blanket
walk over NR_IRQS for status !IRQ_NODELAY from init_hardirqs().
The printk timestamps will confirm that either may get there 1st.
The problem is that if the latter gets there 1st, the IRQF_NODELAY
may not have propagated from flags to an IRQ_NODELAY in status, and
you end up with an IRQ-0 thread for the timer IRQ, even though it
should be IRQF_NODELAY and have no IRQ-0 thread. The threaded IRQ-0
eventually blows up when tick_periodic() does the following:
update_process_times(user_mode(get_irq_regs()));
and this results in a trace that looks like the attached. I've
simply stubbed out the seemingly needless init_hardirqs() to be
just a barrier so it checks on proper ordering and now the boot time
failures are gone.
[ 0.062407] BUG: unable to handle kernel NULL pointer dereference at 00000030
[ 0.062990] IP: [<c0230385>] tick_periodic+0x63/0x79
[ 0.062990] *pde = 00000000
[ 0.062990] Oops: 0000 [#1] PREEMPT
[ 0.062990]
[ 0.062990] Pid: 3, comm: IRQ-0 Not tainted (2.6.27-rc8-26rt9 #3)
[ 0.062990] EIP: 0060:[<c0230385>] EFLAGS: 00010246 CPU: 0
[ 0.062990] EIP is at tick_periodic+0x63/0x79
[ 0.062990] Call Trace:
[ 0.062990] [<c02303b3>] ? tick_handle_periodic+0x18/0x5d
[ 0.062990] [<c0205525>] ? timer_interrupt+0x19/0x20
[ 0.062990] [<c0238b3d>] ? handle_IRQ_event+0x45/0xb6
[ 0.062990] [<c0239386>] ? do_irqd+0x0/0x270
[ 0.062990] [<c0238f6d>] ? thread_simple_irq+0x5a/0x93
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 4d1ffd1..ae0c6a8 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -902,9 +902,11 @@ static int ok_to_create_irq_threads;
static int start_irq_thread(int irq, struct irq_desc *desc)
{
- if (desc->thread || !ok_to_create_irq_threads)
+ if (desc->thread)
return 0;
+ BUG_ON(!ok_to_create_irq_threads);
+
desc->thread = kthread_create(do_irqd, desc, "IRQ-%d", irq);
if (!desc->thread) {
printk(KERN_ERR "irqd: could not create IRQ thread %d!\n", irq);
@@ -924,15 +926,7 @@ static int start_irq_thread(int irq, struct irq_desc *desc)
void __init init_hardirqs(void)
{
- int i;
ok_to_create_irq_threads = 1;
-
- for (i = 0; i < NR_IRQS; i++) {
- irq_desc_t *desc = irq_desc + i;
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2008-10-02 3:01 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-02 3:01 [PATCH/RFC] init_hardirqs shouldn't call start_irq_thread Paul Gortmaker
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).