diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2009-08-17 08:07:16 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2009-08-18 11:22:43 -0400 |
commit | 69ab849439b506cd8dd2879527fdb64d95dd5211 (patch) | |
tree | 059fba8bcb8147fafcd4e86db61f0f88d6a84095 /kernel | |
parent | 2d860ad76f4ee4d2eba0fe3797c8d7cdce432cc0 (diff) |
genirq: Wake up irq thread after action has been installed
The wake_up_process() of the new irq thread in __setup_irq() is too
early as the irqaction is not yet fully initialized especially
action->irq is not yet set. The interrupt thread might dereference the
wrong irq descriptor.
Move the wakeup after the action is installed and action->irq has been
set.
Reported-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Michael Buesch <mb@bu3sch.de>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/irq/manage.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index d222515a5a06..0ec9ed831737 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -607,7 +607,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
607 | */ | 607 | */ |
608 | get_task_struct(t); | 608 | get_task_struct(t); |
609 | new->thread = t; | 609 | new->thread = t; |
610 | wake_up_process(t); | ||
611 | } | 610 | } |
612 | 611 | ||
613 | /* | 612 | /* |
@@ -690,6 +689,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
690 | (int)(new->flags & IRQF_TRIGGER_MASK)); | 689 | (int)(new->flags & IRQF_TRIGGER_MASK)); |
691 | } | 690 | } |
692 | 691 | ||
692 | new->irq = irq; | ||
693 | *old_ptr = new; | 693 | *old_ptr = new; |
694 | 694 | ||
695 | /* Reset broken irq detection when installing new handler */ | 695 | /* Reset broken irq detection when installing new handler */ |
@@ -707,7 +707,13 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
707 | 707 | ||
708 | spin_unlock_irqrestore(&desc->lock, flags); | 708 | spin_unlock_irqrestore(&desc->lock, flags); |
709 | 709 | ||
710 | new->irq = irq; | 710 | /* |
711 | * Strictly no need to wake it up, but hung_task complains | ||
712 | * when no hard interrupt wakes the thread up. | ||
713 | */ | ||
714 | if (new->thread) | ||
715 | wake_up_process(new->thread); | ||
716 | |||
711 | register_irq_proc(irq, desc); | 717 | register_irq_proc(irq, desc); |
712 | new->dir = NULL; | 718 | new->dir = NULL; |
713 | register_handler_proc(irq, new); | 719 | register_handler_proc(irq, new); |