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

This commit is contained in:
Ingo Molnar 2009-02-13 11:57:18 +01:00
Коммит 8f8573ae9f
33 изменённых файлов: 97 добавлений и 70 удалений

Просмотреть файл

@ -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",

Просмотреть файл

@ -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);
} }

Просмотреть файл

@ -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)

Просмотреть файл

@ -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)))

Просмотреть файл

@ -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)

Просмотреть файл

@ -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)

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -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

Просмотреть файл

@ -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 */

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -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>

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -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];

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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 */

Просмотреть файл

@ -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
/* /*

Просмотреть файл

@ -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.*/

Просмотреть файл

@ -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;
void *ptr;
/* Compute how many bytes we need per irq and allocate them */
bytes = nr * sizeof(unsigned int);
node = cpu_to_node(cpu); node = cpu_to_node(cpu);
ptr = kzalloc_node(bytes, GFP_ATOMIC, node); ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs), GFP_ATOMIC, node);
printk(KERN_DEBUG " alloc kstat_irqs on cpu %d node %d\n", cpu, 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);

Просмотреть файл

@ -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];

Просмотреть файл

@ -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;

Просмотреть файл

@ -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) { if (desc->kstat_irqs != old_desc->kstat_irqs)
/* Compute how many bytes we need per irq and allocate them */ memcpy(desc->kstat_irqs, old_desc->kstat_irqs,
bytes = nr * sizeof(unsigned int); nr * sizeof(*desc->kstat_irqs));
memcpy(desc->kstat_irqs, old_desc->kstat_irqs, bytes);
}
} }
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)

Просмотреть файл

@ -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