]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[IA64] Fix possible race in destroy_and_reserve_irq()
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Mon, 30 Jul 2007 02:56:30 +0000 (11:56 +0900)
committerTony Luck <tony.luck@intel.com>
Mon, 30 Jul 2007 23:30:42 +0000 (16:30 -0700)
Currently, destroy_and_reserve_irq() sets irq_status[irq] UNUSED using
clear_irq_vector() and sets irq_status[irq] RSVD using reserve_irq().
But there is a race window because vector_lock is once released between
them. This patch fixes this race window.

Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
arch/ia64/kernel/irq_ia64.c

index 9386b955eed1652ea1694919272a937c5a3714d7..c47c8acc96e37a270eeb8198fc8cf11b80cf9b09 100644 (file)
@@ -101,15 +101,6 @@ int check_irq_used(int irq)
        return -1;
 }
 
-static void reserve_irq(unsigned int irq)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&vector_lock, flags);
-       irq_status[irq] = IRQ_RSVD;
-       spin_unlock_irqrestore(&vector_lock, flags);
-}
-
 static inline int find_unassigned_irq(void)
 {
        int irq;
@@ -302,10 +293,14 @@ static cpumask_t vector_allocation_domain(int cpu)
 
 void destroy_and_reserve_irq(unsigned int irq)
 {
+       unsigned long flags;
+
        dynamic_irq_cleanup(irq);
 
-       clear_irq_vector(irq);
-       reserve_irq(irq);
+       spin_lock_irqsave(&vector_lock, flags);
+       __clear_irq_vector(irq);
+       irq_status[irq] = IRQ_RSVD;
+       spin_unlock_irqrestore(&vector_lock, flags);
 }
 
 static int __reassign_irq_vector(int irq, int cpu)