Browse Source

Merge branches 'irq/genirq', 'irq/sparseirq' and 'irq/urgent' into irq/core

Ingo Molnar 16 years ago
parent
commit
8f8573ae9f

+ 1 - 1
arch/alpha/kernel/irq.c

@@ -90,7 +90,7 @@ show_interrupts(struct seq_file *p, void *v)
 		seq_printf(p, "%10u ", kstat_irqs(irq));
 		seq_printf(p, "%10u ", kstat_irqs(irq));
 #else
 #else
 		for_each_online_cpu(j)
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
 #endif
 #endif
 		seq_printf(p, " %14s", irq_desc[irq].chip->typename);
 		seq_printf(p, " %14s", irq_desc[irq].chip->typename);
 		seq_printf(p, "  %c%s",
 		seq_printf(p, "  %c%s",

+ 1 - 1
arch/alpha/kernel/irq_alpha.c

@@ -64,7 +64,7 @@ do_entInt(unsigned long type, unsigned long vector,
 		smp_percpu_timer_interrupt(regs);
 		smp_percpu_timer_interrupt(regs);
 		cpu = smp_processor_id();
 		cpu = smp_processor_id();
 		if (cpu != boot_cpuid) {
 		if (cpu != boot_cpuid) {
-		        kstat_cpu(cpu).irqs[RTC_IRQ]++;
+		        kstat_incr_irqs_this_cpu(RTC_IRQ, irq_to_desc(RTC_IRQ));
 		} else {
 		} else {
 			handle_irq(RTC_IRQ);
 			handle_irq(RTC_IRQ);
 		}
 		}

+ 1 - 1
arch/arm/kernel/irq.c

@@ -76,7 +76,7 @@ int show_interrupts(struct seq_file *p, void *v)
 
 
 		seq_printf(p, "%3d: ", i);
 		seq_printf(p, "%3d: ", i);
 		for_each_present_cpu(cpu)
 		for_each_present_cpu(cpu)
-			seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
 		seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
 		seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
 		seq_printf(p, "  %s", action->name);
 		seq_printf(p, "  %s", action->name);
 		for (action = action->next; action; action = action->next)
 		for (action = action->next; action; action = action->next)

+ 1 - 2
arch/arm/mach-ns9xxx/irq.c

@@ -63,7 +63,6 @@ static struct irq_chip ns9xxx_chip = {
 #else
 #else
 static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 {
 {
-	unsigned int cpu = smp_processor_id();
 	struct irqaction *action;
 	struct irqaction *action;
 	irqreturn_t action_ret;
 	irqreturn_t action_ret;
 
 
@@ -72,7 +71,7 @@ static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 	BUG_ON(desc->status & IRQ_INPROGRESS);
 	BUG_ON(desc->status & IRQ_INPROGRESS);
 
 
 	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
 	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
-	kstat_cpu(cpu).irqs[irq]++;
+	kstat_incr_irqs_this_cpu(irq, desc);
 
 
 	action = desc->action;
 	action = desc->action;
 	if (unlikely(!action || (desc->status & IRQ_DISABLED)))
 	if (unlikely(!action || (desc->status & IRQ_DISABLED)))

+ 1 - 1
arch/avr32/kernel/irq.c

@@ -58,7 +58,7 @@ int show_interrupts(struct seq_file *p, void *v)
 
 
 		seq_printf(p, "%3d: ", i);
 		seq_printf(p, "%3d: ", i);
 		for_each_online_cpu(cpu)
 		for_each_online_cpu(cpu)
-			seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
 		seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-");
 		seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-");
 		seq_printf(p, "  %s", action->name);
 		seq_printf(p, "  %s", action->name);
 		for (action = action->next; action; action = action->next)
 		for (action = action->next; action; action = action->next)

+ 1 - 1
arch/blackfin/kernel/irqchip.c

@@ -83,7 +83,7 @@ int show_interrupts(struct seq_file *p, void *v)
 			goto skip;
 			goto skip;
 		seq_printf(p, "%3d: ", i);
 		seq_printf(p, "%3d: ", i);
 		for_each_online_cpu(j)
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 		seq_printf(p, " %8s", irq_desc[i].chip->name);
 		seq_printf(p, " %8s", irq_desc[i].chip->name);
 		seq_printf(p, "  %s", action->name);
 		seq_printf(p, "  %s", action->name);
 		for (action = action->next; action; action = action->next)
 		for (action = action->next; action; action = action->next)

+ 1 - 1
arch/cris/kernel/irq.c

@@ -66,7 +66,7 @@ int show_interrupts(struct seq_file *p, void *v)
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 #else
 		for_each_online_cpu(j)
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->typename);
 		seq_printf(p, " %14s", irq_desc[i].chip->typename);
 		seq_printf(p, "  %s", action->name);
 		seq_printf(p, "  %s", action->name);

+ 1 - 1
arch/frv/kernel/irq.c

@@ -74,7 +74,7 @@ int show_interrupts(struct seq_file *p, void *v)
 		if (action) {
 		if (action) {
 			seq_printf(p, "%3d: ", i);
 			seq_printf(p, "%3d: ", i);
 			for_each_present_cpu(cpu)
 			for_each_present_cpu(cpu)
-				seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+				seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
 			seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
 			seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
 			seq_printf(p, "  %s", action->name);
 			seq_printf(p, "  %s", action->name);
 			for (action = action->next;
 			for (action = action->next;

+ 2 - 2
arch/h8300/kernel/irq.c

@@ -183,7 +183,7 @@ asmlinkage void do_IRQ(int irq)
 #if defined(CONFIG_PROC_FS)
 #if defined(CONFIG_PROC_FS)
 int show_interrupts(struct seq_file *p, void *v)
 int show_interrupts(struct seq_file *p, void *v)
 {
 {
-	int i = *(loff_t *) v, j;
+	int i = *(loff_t *) v;
 	struct irqaction * action;
 	struct irqaction * action;
 	unsigned long flags;
 	unsigned long flags;
 
 
@@ -196,7 +196,7 @@ int show_interrupts(struct seq_file *p, void *v)
 		if (!action)
 		if (!action)
 			goto unlock;
 			goto unlock;
 		seq_printf(p, "%3d: ",i);
 		seq_printf(p, "%3d: ",i);
-		seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
 		seq_printf(p, "-%-8s", irq_desc[i].name);
 		seq_printf(p, "-%-8s", irq_desc[i].name);
 		seq_printf(p, "  %s", action->name);
 		seq_printf(p, "  %s", action->name);

+ 1 - 1
arch/ia64/kernel/irq.c

@@ -80,7 +80,7 @@ int show_interrupts(struct seq_file *p, void *v)
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 #else
 		for_each_online_cpu(j) {
 		for_each_online_cpu(j) {
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 		}
 		}
 #endif
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
 		seq_printf(p, " %14s", irq_desc[i].chip->name);

+ 1 - 1
arch/m32r/kernel/irq.c

@@ -49,7 +49,7 @@ int show_interrupts(struct seq_file *p, void *v)
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 #else
 		for_each_online_cpu(j)
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->typename);
 		seq_printf(p, " %14s", irq_desc[i].chip->typename);
 		seq_printf(p, "  %s", action->name);
 		seq_printf(p, "  %s", action->name);

+ 1 - 1
arch/mips/kernel/irq.c

@@ -108,7 +108,7 @@ int show_interrupts(struct seq_file *p, void *v)
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 #else
 		for_each_online_cpu(j)
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
 		seq_printf(p, "-%-8s", irq_desc[i].name);
 		seq_printf(p, "-%-8s", irq_desc[i].name);

+ 1 - 1
arch/mn10300/kernel/irq.c

@@ -221,7 +221,7 @@ int show_interrupts(struct seq_file *p, void *v)
 		if (action) {
 		if (action) {
 			seq_printf(p, "%3d: ", i);
 			seq_printf(p, "%3d: ", i);
 			for_each_present_cpu(cpu)
 			for_each_present_cpu(cpu)
-				seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+				seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
 			seq_printf(p, " %14s.%u", irq_desc[i].chip->name,
 			seq_printf(p, " %14s.%u", irq_desc[i].chip->name,
 				   (GxICR(i) & GxICR_LEVEL) >>
 				   (GxICR(i) & GxICR_LEVEL) >>
 				   GxICR_LEVEL_SHIFT);
 				   GxICR_LEVEL_SHIFT);

+ 1 - 1
arch/parisc/kernel/irq.c

@@ -183,7 +183,7 @@ int show_interrupts(struct seq_file *p, void *v)
 		seq_printf(p, "%3d: ", i);
 		seq_printf(p, "%3d: ", i);
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
 		for_each_online_cpu(j)
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #else
 #else
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #endif
 #endif

+ 1 - 1
arch/powerpc/kernel/irq.c

@@ -190,7 +190,7 @@ int show_interrupts(struct seq_file *p, void *v)
 		seq_printf(p, "%3d: ", i);
 		seq_printf(p, "%3d: ", i);
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
 		for_each_online_cpu(j)
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #else
 #else
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #endif /* CONFIG_SMP */
 #endif /* CONFIG_SMP */

+ 1 - 1
arch/powerpc/platforms/cell/interrupt.c

@@ -254,7 +254,7 @@ static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
 		goto out_eoi;
 		goto out_eoi;
 	}
 	}
 
 
-	kstat_cpu(cpu).irqs[irq]++;
+	kstat_incr_irqs_this_cpu(irq, desc);
 
 
 	/* Mark the IRQ currently in progress.*/
 	/* Mark the IRQ currently in progress.*/
 	desc->status |= IRQ_INPROGRESS;
 	desc->status |= IRQ_INPROGRESS;

+ 1 - 1
arch/sh/kernel/irq.c

@@ -51,7 +51,7 @@ int show_interrupts(struct seq_file *p, void *v)
 			goto unlock;
 			goto unlock;
 		seq_printf(p, "%3d: ",i);
 		seq_printf(p, "%3d: ",i);
 		for_each_online_cpu(j)
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
 		seq_printf(p, "-%-8s", irq_desc[i].name);
 		seq_printf(p, "-%-8s", irq_desc[i].name);
 		seq_printf(p, "  %s", action->name);
 		seq_printf(p, "  %s", action->name);

+ 1 - 1
arch/sparc/kernel/irq_64.c

@@ -185,7 +185,7 @@ int show_interrupts(struct seq_file *p, void *v)
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 #else
 		for_each_online_cpu(j)
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
 #endif
 		seq_printf(p, " %9s", irq_desc[i].chip->typename);
 		seq_printf(p, " %9s", irq_desc[i].chip->typename);
 		seq_printf(p, "  %s", action->name);
 		seq_printf(p, "  %s", action->name);

+ 1 - 1
arch/sparc/kernel/time_64.c

@@ -36,10 +36,10 @@
 #include <linux/clocksource.h>
 #include <linux/clocksource.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
+#include <linux/irq.h>
 
 
 #include <asm/oplib.h>
 #include <asm/oplib.h>
 #include <asm/timer.h>
 #include <asm/timer.h>
-#include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/prom.h>
 #include <asm/starfire.h>
 #include <asm/starfire.h>

+ 1 - 1
arch/um/kernel/irq.c

@@ -42,7 +42,7 @@ int show_interrupts(struct seq_file *p, void *v)
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 #else
 		for_each_online_cpu(j)
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->typename);
 		seq_printf(p, " %14s", irq_desc[i].chip->typename);
 		seq_printf(p, "  %s", action->name);
 		seq_printf(p, "  %s", action->name);

+ 1 - 1
arch/xtensa/kernel/irq.c

@@ -99,7 +99,7 @@ int show_interrupts(struct seq_file *p, void *v)
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 #else
 		for_each_online_cpu(j)
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->typename);
 		seq_printf(p, " %14s", irq_desc[i].chip->typename);
 		seq_printf(p, "  %s", action->name);
 		seq_printf(p, "  %s", action->name);

+ 5 - 1
drivers/char/random.c

@@ -241,6 +241,10 @@
 #include <linux/percpu.h>
 #include <linux/percpu.h>
 #include <linux/cryptohash.h>
 #include <linux/cryptohash.h>
 
 
+#ifdef CONFIG_GENERIC_HARDIRQS
+# include <linux/irq.h>
+#endif
+
 #include <asm/processor.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 #include <asm/irq.h>
@@ -558,7 +562,7 @@ struct timer_rand_state {
 	unsigned dont_count_entropy:1;
 	unsigned dont_count_entropy:1;
 };
 };
 
 
-#ifndef CONFIG_SPARSE_IRQ
+#ifndef CONFIG_GENERIC_HARDIRQS
 
 
 static struct timer_rand_state *irq_timer_state[NR_IRQS];
 static struct timer_rand_state *irq_timer_state[NR_IRQS];
 
 

+ 1 - 1
drivers/pci/intr_remapping.c

@@ -20,7 +20,7 @@ struct irq_2_iommu {
 	u8  irte_mask;
 	u8  irte_mask;
 };
 };
 
 
-#ifdef CONFIG_SPARSE_IRQ
+#ifdef CONFIG_GENERIC_HARDIRQS
 static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
 static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
 {
 {
 	struct irq_2_iommu *iommu;
 	struct irq_2_iommu *iommu;

+ 6 - 0
include/linux/interrupt.h

@@ -462,6 +462,12 @@ static inline void init_irq_proc(void)
 }
 }
 #endif
 #endif
 
 
+#if defined(CONFIG_GENERIC_HARDIRQS) && defined(CONFIG_DEBUG_SHIRQ)
+extern void debug_poll_all_shared_irqs(void);
+#else
+static inline void debug_poll_all_shared_irqs(void) { }
+#endif
+
 int show_interrupts(struct seq_file *p, void *v);
 int show_interrupts(struct seq_file *p, void *v);
 
 
 struct irq_desc;
 struct irq_desc;

+ 1 - 9
include/linux/irq.h

@@ -160,12 +160,10 @@ struct irq_2_iommu;
  */
  */
 struct irq_desc {
 struct irq_desc {
 	unsigned int		irq;
 	unsigned int		irq;
-#ifdef CONFIG_SPARSE_IRQ
 	struct timer_rand_state *timer_rand_state;
 	struct timer_rand_state *timer_rand_state;
 	unsigned int            *kstat_irqs;
 	unsigned int            *kstat_irqs;
-# ifdef CONFIG_INTR_REMAP
+#ifdef CONFIG_INTR_REMAP
 	struct irq_2_iommu      *irq_2_iommu;
 	struct irq_2_iommu      *irq_2_iommu;
-# endif
 #endif
 #endif
 	irq_flow_handler_t	handle_irq;
 	irq_flow_handler_t	handle_irq;
 	struct irq_chip		*chip;
 	struct irq_chip		*chip;
@@ -202,12 +200,6 @@ extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc
 extern struct irq_desc irq_desc[NR_IRQS];
 extern struct irq_desc irq_desc[NR_IRQS];
 #else /* CONFIG_SPARSE_IRQ */
 #else /* CONFIG_SPARSE_IRQ */
 extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu);
 extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu);
-
-#define kstat_irqs_this_cpu(DESC) \
-	((DESC)->kstat_irqs[smp_processor_id()])
-#define kstat_incr_irqs_this_cpu(irqno, DESC) \
-	((DESC)->kstat_irqs[smp_processor_id()]++)
-
 #endif /* CONFIG_SPARSE_IRQ */
 #endif /* CONFIG_SPARSE_IRQ */
 
 
 extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu);
 extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu);

+ 6 - 2
include/linux/irqnr.h

@@ -28,13 +28,17 @@ extern struct irq_desc *irq_to_desc(unsigned int irq);
 # define for_each_irq_desc(irq, desc)					\
 # define for_each_irq_desc(irq, desc)					\
 	for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs;		\
 	for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs;		\
 	     irq++, desc = irq_to_desc(irq))				\
 	     irq++, desc = irq_to_desc(irq))				\
-		if (desc)
+		if (!desc)						\
+			;						\
+		else
 
 
 
 
 # define for_each_irq_desc_reverse(irq, desc)				\
 # define for_each_irq_desc_reverse(irq, desc)				\
 	for (irq = nr_irqs - 1, desc = irq_to_desc(irq); irq >= 0;	\
 	for (irq = nr_irqs - 1, desc = irq_to_desc(irq); irq >= 0;	\
 	     irq--, desc = irq_to_desc(irq))				\
 	     irq--, desc = irq_to_desc(irq))				\
-		if (desc)
+		if (!desc)						\
+			;						\
+		else
 
 
 #endif /* CONFIG_GENERIC_HARDIRQS */
 #endif /* CONFIG_GENERIC_HARDIRQS */
 
 

+ 8 - 5
include/linux/kernel_stat.h

@@ -28,7 +28,7 @@ struct cpu_usage_stat {
 
 
 struct kernel_stat {
 struct kernel_stat {
 	struct cpu_usage_stat	cpustat;
 	struct cpu_usage_stat	cpustat;
-#ifndef CONFIG_SPARSE_IRQ
+#ifndef CONFIG_GENERIC_HARDIRQS
        unsigned int irqs[NR_IRQS];
        unsigned int irqs[NR_IRQS];
 #endif
 #endif
 };
 };
@@ -41,7 +41,7 @@ DECLARE_PER_CPU(struct kernel_stat, kstat);
 
 
 extern unsigned long long nr_context_switches(void);
 extern unsigned long long nr_context_switches(void);
 
 
-#ifndef CONFIG_SPARSE_IRQ
+#ifndef CONFIG_GENERIC_HARDIRQS
 #define kstat_irqs_this_cpu(irq) \
 #define kstat_irqs_this_cpu(irq) \
 	(kstat_this_cpu.irqs[irq])
 	(kstat_this_cpu.irqs[irq])
 
 
@@ -52,16 +52,19 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq,
 {
 {
 	kstat_this_cpu.irqs[irq]++;
 	kstat_this_cpu.irqs[irq]++;
 }
 }
-#endif
-
 
 
-#ifndef CONFIG_SPARSE_IRQ
 static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
 static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
 {
 {
        return kstat_cpu(cpu).irqs[irq];
        return kstat_cpu(cpu).irqs[irq];
 }
 }
 #else
 #else
+#include <linux/irq.h>
 extern unsigned int kstat_irqs_cpu(unsigned int irq, int cpu);
 extern unsigned int kstat_irqs_cpu(unsigned int irq, int cpu);
+#define kstat_irqs_this_cpu(DESC) \
+	((DESC)->kstat_irqs[smp_processor_id()])
+#define kstat_incr_irqs_this_cpu(irqno, DESC) \
+	((DESC)->kstat_irqs[smp_processor_id()]++)
+
 #endif
 #endif
 
 
 /*
 /*

+ 5 - 2
kernel/irq/chip.c

@@ -78,6 +78,7 @@ void dynamic_irq_cleanup(unsigned int irq)
 	desc->handle_irq = handle_bad_irq;
 	desc->handle_irq = handle_bad_irq;
 	desc->chip = &no_irq_chip;
 	desc->chip = &no_irq_chip;
 	desc->name = NULL;
 	desc->name = NULL;
+	clear_kstat_irqs(desc);
 	spin_unlock_irqrestore(&desc->lock, flags);
 	spin_unlock_irqrestore(&desc->lock, flags);
 }
 }
 
 
@@ -290,7 +291,8 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq)
 		desc->chip->mask_ack(irq);
 		desc->chip->mask_ack(irq);
 	else {
 	else {
 		desc->chip->mask(irq);
 		desc->chip->mask(irq);
-		desc->chip->ack(irq);
+		if (desc->chip->ack)
+			desc->chip->ack(irq);
 	}
 	}
 }
 }
 
 
@@ -476,7 +478,8 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
 	kstat_incr_irqs_this_cpu(irq, desc);
 	kstat_incr_irqs_this_cpu(irq, desc);
 
 
 	/* Start handling the irq */
 	/* Start handling the irq */
-	desc->chip->ack(irq);
+	if (desc->chip->ack)
+		desc->chip->ack(irq);
 	desc = irq_remap_to_desc(irq, desc);
 	desc = irq_remap_to_desc(irq, desc);
 
 
 	/* Mark the IRQ currently in progress.*/
 	/* Mark the IRQ currently in progress.*/

+ 20 - 12
kernel/irq/handle.c

@@ -83,19 +83,21 @@ static struct irq_desc irq_desc_init = {
 
 
 void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
 void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
 {
 {
-	unsigned long bytes;
-	char *ptr;
 	int node;
 	int node;
-
-	/* Compute how many bytes we need per irq and allocate them */
-	bytes = nr * sizeof(unsigned int);
+	void *ptr;
 
 
 	node = cpu_to_node(cpu);
 	node = cpu_to_node(cpu);
-	ptr = kzalloc_node(bytes, GFP_ATOMIC, node);
-	printk(KERN_DEBUG "  alloc kstat_irqs on cpu %d node %d\n", cpu, node);
+	ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs), GFP_ATOMIC, node);
 
 
-	if (ptr)
-		desc->kstat_irqs = (unsigned int *)ptr;
+	/*
+	 * don't overwite if can not get new one
+	 * init_copy_kstat_irqs() could still use old one
+	 */
+	if (ptr) {
+		printk(KERN_DEBUG "  alloc kstat_irqs on cpu %d node %d\n",
+			 cpu, node);
+		desc->kstat_irqs = ptr;
+	}
 }
 }
 
 
 static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu)
 static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu)
@@ -227,6 +229,7 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
 	}
 	}
 };
 };
 
 
+static unsigned int kstat_irqs_all[NR_IRQS][NR_CPUS];
 int __init early_irq_init(void)
 int __init early_irq_init(void)
 {
 {
 	struct irq_desc *desc;
 	struct irq_desc *desc;
@@ -238,8 +241,10 @@ int __init early_irq_init(void)
 	desc = irq_desc;
 	desc = irq_desc;
 	count = ARRAY_SIZE(irq_desc);
 	count = ARRAY_SIZE(irq_desc);
 
 
-	for (i = 0; i < count; i++)
+	for (i = 0; i < count; i++) {
 		desc[i].irq = i;
 		desc[i].irq = i;
+		desc[i].kstat_irqs = kstat_irqs_all[i];
+	}
 
 
 	return arch_early_irq_init();
 	return arch_early_irq_init();
 }
 }
@@ -255,6 +260,11 @@ struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
 }
 }
 #endif /* !CONFIG_SPARSE_IRQ */
 #endif /* !CONFIG_SPARSE_IRQ */
 
 
+void clear_kstat_irqs(struct irq_desc *desc)
+{
+	memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
+}
+
 /*
 /*
  * What should we do if we get a hw irq event on an illegal vector?
  * What should we do if we get a hw irq event on an illegal vector?
  * Each architecture has to answer this themself.
  * Each architecture has to answer this themself.
@@ -467,12 +477,10 @@ void early_init_irq_lock_class(void)
 	}
 	}
 }
 }
 
 
-#ifdef CONFIG_SPARSE_IRQ
 unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
 unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
 {
 {
 	struct irq_desc *desc = irq_to_desc(irq);
 	struct irq_desc *desc = irq_to_desc(irq);
 	return desc ? desc->kstat_irqs[cpu] : 0;
 	return desc ? desc->kstat_irqs[cpu] : 0;
 }
 }
-#endif
 EXPORT_SYMBOL(kstat_irqs_cpu);
 EXPORT_SYMBOL(kstat_irqs_cpu);
 
 

+ 1 - 0
kernel/irq/internals.h

@@ -15,6 +15,7 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
 
 
 extern struct lock_class_key irq_desc_lock_class;
 extern struct lock_class_key irq_desc_lock_class;
 extern void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr);
 extern void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr);
+extern void clear_kstat_irqs(struct irq_desc *desc);
 extern spinlock_t sparse_irq_lock;
 extern spinlock_t sparse_irq_lock;
 extern struct irq_desc *irq_desc_ptrs[NR_IRQS];
 extern struct irq_desc *irq_desc_ptrs[NR_IRQS];
 
 

+ 6 - 6
kernel/irq/manage.c

@@ -109,7 +109,7 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
 /*
 /*
  * Generic version of the affinity autoselector.
  * Generic version of the affinity autoselector.
  */
  */
-int do_irq_select_affinity(unsigned int irq, struct irq_desc *desc)
+static int setup_affinity(unsigned int irq, struct irq_desc *desc)
 {
 {
 	if (!irq_can_set_affinity(irq))
 	if (!irq_can_set_affinity(irq))
 		return 0;
 		return 0;
@@ -133,7 +133,7 @@ set_affinity:
 	return 0;
 	return 0;
 }
 }
 #else
 #else
-static inline int do_irq_select_affinity(unsigned int irq, struct irq_desc *d)
+static inline int setup_affinity(unsigned int irq, struct irq_desc *d)
 {
 {
 	return irq_select_affinity(irq);
 	return irq_select_affinity(irq);
 }
 }
@@ -149,14 +149,14 @@ int irq_select_affinity_usr(unsigned int irq)
 	int ret;
 	int ret;
 
 
 	spin_lock_irqsave(&desc->lock, flags);
 	spin_lock_irqsave(&desc->lock, flags);
-	ret = do_irq_select_affinity(irq, desc);
+	ret = setup_affinity(irq, desc);
 	spin_unlock_irqrestore(&desc->lock, flags);
 	spin_unlock_irqrestore(&desc->lock, flags);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
 #else
 #else
-static inline int do_irq_select_affinity(int irq, struct irq_desc *desc)
+static inline int setup_affinity(unsigned int irq, struct irq_desc *desc)
 {
 {
 	return 0;
 	return 0;
 }
 }
@@ -488,7 +488,7 @@ __setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new)
 			desc->status |= IRQ_NO_BALANCING;
 			desc->status |= IRQ_NO_BALANCING;
 
 
 		/* Set default affinity mask once everything is setup */
 		/* Set default affinity mask once everything is setup */
-		do_irq_select_affinity(irq, desc);
+		setup_affinity(irq, desc);
 
 
 	} else if ((new->flags & IRQF_TRIGGER_MASK)
 	} else if ((new->flags & IRQF_TRIGGER_MASK)
 			&& (new->flags & IRQF_TRIGGER_MASK)
 			&& (new->flags & IRQF_TRIGGER_MASK)
@@ -709,7 +709,7 @@ int request_irq(unsigned int irq, irq_handler_t handler,
 	if (!handler)
 	if (!handler)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
+	action = kmalloc(sizeof(struct irqaction), GFP_KERNEL);
 	if (!action)
 	if (!action)
 		return -ENOMEM;
 		return -ENOMEM;
 
 

+ 3 - 8
kernel/irq/numa_migrate.c

@@ -17,16 +17,11 @@ static void init_copy_kstat_irqs(struct irq_desc *old_desc,
 				 struct irq_desc *desc,
 				 struct irq_desc *desc,
 				 int cpu, int nr)
 				 int cpu, int nr)
 {
 {
-	unsigned long bytes;
-
 	init_kstat_irqs(desc, cpu, nr);
 	init_kstat_irqs(desc, cpu, nr);
 
 
-	if (desc->kstat_irqs != old_desc->kstat_irqs) {
-		/* Compute how many bytes we need per irq and allocate them */
-		bytes = nr * sizeof(unsigned int);
-
-		memcpy(desc->kstat_irqs, old_desc->kstat_irqs, bytes);
-	}
+	if (desc->kstat_irqs != old_desc->kstat_irqs)
+		memcpy(desc->kstat_irqs, old_desc->kstat_irqs,
+			 nr * sizeof(*desc->kstat_irqs));
 }
 }
 
 
 static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc)
 static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc)

+ 13 - 1
kernel/irq/spurious.c

@@ -104,7 +104,7 @@ static int misrouted_irq(int irq)
 	return ok;
 	return ok;
 }
 }
 
 
-static void poll_spurious_irqs(unsigned long dummy)
+static void poll_all_shared_irqs(void)
 {
 {
 	struct irq_desc *desc;
 	struct irq_desc *desc;
 	int i;
 	int i;
@@ -123,11 +123,23 @@ static void poll_spurious_irqs(unsigned long dummy)
 
 
 		try_one_irq(i, desc);
 		try_one_irq(i, desc);
 	}
 	}
+}
+
+static void poll_spurious_irqs(unsigned long dummy)
+{
+	poll_all_shared_irqs();
 
 
 	mod_timer(&poll_spurious_irq_timer,
 	mod_timer(&poll_spurious_irq_timer,
 		  jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
 		  jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
 }
 }
 
 
+#ifdef CONFIG_DEBUG_SHIRQ
+void debug_poll_all_shared_irqs(void)
+{
+	poll_all_shared_irqs();
+}
+#endif
+
 /*
 /*
  * If 99,900 of the previous 100,000 interrupts have not been handled
  * If 99,900 of the previous 100,000 interrupts have not been handled
  * then assume that the IRQ is stuck in some manner. Drop a diagnostic
  * then assume that the IRQ is stuck in some manner. Drop a diagnostic