aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2008-12-05 21:58:31 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-08 08:31:51 -0500
commit0b8f1efad30bd58f89961b82dfe68b9edf8fd2ac (patch)
tree239251bad791fd60af8c0f2ba365b7188395c83f
parent218d11a8b071b23b76c484fd5f72a4fe3306801e (diff)
sparse irq_desc[] array: core kernel and x86 changes
Impact: new feature Problem on distro kernels: irq_desc[NR_IRQS] takes megabytes of RAM with NR_CPUS set to large values. The goal is to be able to scale up to much larger NR_IRQS value without impacting the (important) common case. To solve this, we generalize irq_desc[NR_IRQS] to an (optional) array of irq_desc pointers. When CONFIG_SPARSE_IRQ=y is used, we use kzalloc_node to get irq_desc, this also makes the IRQ descriptors NUMA-local (to the site that calls request_irq()). This gets rid of the irq_cfg[] static array on x86 as well: irq_cfg now uses desc->chip_data for x86 to store irq_cfg. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/Kconfig10
-rw-r--r--arch/x86/include/asm/irq_vectors.h9
-rw-r--r--arch/x86/kernel/io_apic.c301
-rw-r--r--arch/x86/kernel/irq.c3
-rw-r--r--arch/x86/kernel/irq_32.c2
-rw-r--r--arch/x86/kernel/irq_64.c2
-rw-r--r--arch/x86/kernel/irqinit_32.c1
-rw-r--r--arch/x86/kernel/irqinit_64.c1
-rw-r--r--drivers/char/random.c22
-rw-r--r--drivers/pci/intr_remapping.c76
-rw-r--r--drivers/xen/events.c12
-rw-r--r--fs/proc/stat.c17
-rw-r--r--include/linux/interrupt.h2
-rw-r--r--include/linux/irq.h54
-rw-r--r--include/linux/irqnr.h14
-rw-r--r--include/linux/kernel_stat.h14
-rw-r--r--include/linux/random.h51
-rw-r--r--init/main.c11
-rw-r--r--kernel/irq/autoprobe.c15
-rw-r--r--kernel/irq/chip.c3
-rw-r--r--kernel/irq/handle.c181
-rw-r--r--kernel/irq/proc.c6
-rw-r--r--kernel/irq/spurious.c5
23 files changed, 649 insertions, 163 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ac22bb7719f7..48ac688de3cd 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -238,6 +238,16 @@ config X86_HAS_BOOT_CPU_ID
238 def_bool y 238 def_bool y
239 depends on X86_VOYAGER 239 depends on X86_VOYAGER
240 240
241config SPARSE_IRQ
242 bool "Support sparse irq numbering"
243 depends on PCI_MSI || HT_IRQ
244 default y
245 help
246 This enables support for sparse irq, esp for msi/msi-x. You may need
247 if you have lots of cards supports msi-x installed.
248
249 If you don't know what to do here, say Y.
250
241config X86_FIND_SMP_CONFIG 251config X86_FIND_SMP_CONFIG
242 def_bool y 252 def_bool y
243 depends on X86_MPPARSE || X86_VOYAGER 253 depends on X86_MPPARSE || X86_VOYAGER
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 0005adb0f941..bb6b69a6b125 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -102,11 +102,20 @@
102#define invalid_vm86_irq(irq) ((irq) < 3 || (irq) > 15) 102#define invalid_vm86_irq(irq) ((irq) < 3 || (irq) > 15)
103 103
104#if defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_VOYAGER) 104#if defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_VOYAGER)
105
106#ifndef CONFIG_SPARSE_IRQ
105# if NR_CPUS < MAX_IO_APICS 107# if NR_CPUS < MAX_IO_APICS
106# define NR_IRQS (NR_VECTORS + (32 * NR_CPUS)) 108# define NR_IRQS (NR_VECTORS + (32 * NR_CPUS))
107# else 109# else
108# define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS)) 110# define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS))
109# endif 111# endif
112#else
113# if (8 * NR_CPUS) > (32 * MAX_IO_APICS)
114# define NR_IRQS (NR_VECTORS + (8 * NR_CPUS))
115# else
116# define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS))
117# endif
118#endif
110 119
111#elif defined(CONFIG_X86_VOYAGER) 120#elif defined(CONFIG_X86_VOYAGER)
112 121
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c
index 9043251210fb..9de17f5c1125 100644
--- a/arch/x86/kernel/io_apic.c
+++ b/arch/x86/kernel/io_apic.c
@@ -108,8 +108,33 @@ static int __init parse_noapic(char *str)
108early_param("noapic", parse_noapic); 108early_param("noapic", parse_noapic);
109 109
110struct irq_pin_list; 110struct irq_pin_list;
111
112/*
113 * This is performance-critical, we want to do it O(1)
114 *
115 * the indexing order of this array favors 1:1 mappings
116 * between pins and IRQs.
117 */
118
119struct irq_pin_list {
120 int apic, pin;
121 struct irq_pin_list *next;
122};
123
124static struct irq_pin_list *get_one_free_irq_2_pin(int cpu)
125{
126 struct irq_pin_list *pin;
127 int node;
128
129 node = cpu_to_node(cpu);
130
131 pin = kzalloc_node(sizeof(*pin), GFP_ATOMIC, node);
132 printk(KERN_DEBUG " alloc irq_2_pin on cpu %d node %d\n", cpu, node);
133
134 return pin;
135}
136
111struct irq_cfg { 137struct irq_cfg {
112 unsigned int irq;
113 struct irq_pin_list *irq_2_pin; 138 struct irq_pin_list *irq_2_pin;
114 cpumask_t domain; 139 cpumask_t domain;
115 cpumask_t old_domain; 140 cpumask_t old_domain;
@@ -119,83 +144,93 @@ struct irq_cfg {
119}; 144};
120 145
121/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ 146/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
147#ifdef CONFIG_SPARSE_IRQ
148static struct irq_cfg irq_cfgx[] = {
149#else
122static struct irq_cfg irq_cfgx[NR_IRQS] = { 150static struct irq_cfg irq_cfgx[NR_IRQS] = {
123 [0] = { .irq = 0, .domain = CPU_MASK_ALL, .vector = IRQ0_VECTOR, }, 151#endif
124 [1] = { .irq = 1, .domain = CPU_MASK_ALL, .vector = IRQ1_VECTOR, }, 152 [0] = { .domain = CPU_MASK_ALL, .vector = IRQ0_VECTOR, },
125 [2] = { .irq = 2, .domain = CPU_MASK_ALL, .vector = IRQ2_VECTOR, }, 153 [1] = { .domain = CPU_MASK_ALL, .vector = IRQ1_VECTOR, },
126 [3] = { .irq = 3, .domain = CPU_MASK_ALL, .vector = IRQ3_VECTOR, }, 154 [2] = { .domain = CPU_MASK_ALL, .vector = IRQ2_VECTOR, },
127 [4] = { .irq = 4, .domain = CPU_MASK_ALL, .vector = IRQ4_VECTOR, }, 155 [3] = { .domain = CPU_MASK_ALL, .vector = IRQ3_VECTOR, },
128 [5] = { .irq = 5, .domain = CPU_MASK_ALL, .vector = IRQ5_VECTOR, }, 156 [4] = { .domain = CPU_MASK_ALL, .vector = IRQ4_VECTOR, },
129 [6] = { .irq = 6, .domain = CPU_MASK_ALL, .vector = IRQ6_VECTOR, }, 157 [5] = { .domain = CPU_MASK_ALL, .vector = IRQ5_VECTOR, },
130 [7] = { .irq = 7, .domain = CPU_MASK_ALL, .vector = IRQ7_VECTOR, }, 158 [6] = { .domain = CPU_MASK_ALL, .vector = IRQ6_VECTOR, },
131 [8] = { .irq = 8, .domain = CPU_MASK_ALL, .vector = IRQ8_VECTOR, }, 159 [7] = { .domain = CPU_MASK_ALL, .vector = IRQ7_VECTOR, },
132 [9] = { .irq = 9, .domain = CPU_MASK_ALL, .vector = IRQ9_VECTOR, }, 160 [8] = { .domain = CPU_MASK_ALL, .vector = IRQ8_VECTOR, },
133 [10] = { .irq = 10, .domain = CPU_MASK_ALL, .vector = IRQ10_VECTOR, }, 161 [9] = { .domain = CPU_MASK_ALL, .vector = IRQ9_VECTOR, },
134 [11] = { .irq = 11, .domain = CPU_MASK_ALL, .vector = IRQ11_VECTOR, }, 162 [10] = { .domain = CPU_MASK_ALL, .vector = IRQ10_VECTOR, },
135 [12] = { .irq = 12, .domain = CPU_MASK_ALL, .vector = IRQ12_VECTOR, }, 163 [11] = { .domain = CPU_MASK_ALL, .vector = IRQ11_VECTOR, },
136 [13] = { .irq = 13, .domain = CPU_MASK_ALL, .vector = IRQ13_VECTOR, }, 164 [12] = { .domain = CPU_MASK_ALL, .vector = IRQ12_VECTOR, },
137 [14] = { .irq = 14, .domain = CPU_MASK_ALL, .vector = IRQ14_VECTOR, }, 165 [13] = { .domain = CPU_MASK_ALL, .vector = IRQ13_VECTOR, },
138 [15] = { .irq = 15, .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, }, 166 [14] = { .domain = CPU_MASK_ALL, .vector = IRQ14_VECTOR, },
167 [15] = { .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, },
139}; 168};
140 169
141#define for_each_irq_cfg(irq, cfg) \ 170void __init arch_early_irq_init(void)
142 for (irq = 0, cfg = irq_cfgx; irq < nr_irqs; irq++, cfg++)
143
144static struct irq_cfg *irq_cfg(unsigned int irq)
145{ 171{
146 return irq < nr_irqs ? irq_cfgx + irq : NULL; 172 struct irq_cfg *cfg;
147} 173 struct irq_desc *desc;
174 int count;
175 int i;
148 176
149static struct irq_cfg *irq_cfg_alloc(unsigned int irq) 177 cfg = irq_cfgx;
150{ 178 count = ARRAY_SIZE(irq_cfgx);
151 return irq_cfg(irq);
152}
153 179
154/* 180 for (i = 0; i < count; i++) {
155 * Rough estimation of how many shared IRQs there are, can be changed 181 desc = irq_to_desc(i);
156 * anytime. 182 desc->chip_data = &cfg[i];
157 */ 183 }
158#define MAX_PLUS_SHARED_IRQS NR_IRQS 184}
159#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
160 185
161/* 186#ifdef CONFIG_SPARSE_IRQ
162 * This is performance-critical, we want to do it O(1) 187static struct irq_cfg *irq_cfg(unsigned int irq)
163 * 188{
164 * the indexing order of this array favors 1:1 mappings 189 struct irq_cfg *cfg = NULL;
165 * between pins and IRQs. 190 struct irq_desc *desc;
166 */
167 191
168struct irq_pin_list { 192 desc = irq_to_desc(irq);
169 int apic, pin; 193 if (desc)
170 struct irq_pin_list *next; 194 cfg = desc->chip_data;
171};
172 195
173static struct irq_pin_list irq_2_pin_head[PIN_MAP_SIZE]; 196 return cfg;
174static struct irq_pin_list *irq_2_pin_ptr; 197}
175 198
176static void __init irq_2_pin_init(void) 199static struct irq_cfg *get_one_free_irq_cfg(int cpu)
177{ 200{
178 struct irq_pin_list *pin = irq_2_pin_head; 201 struct irq_cfg *cfg;
179 int i; 202 int node;
203
204 node = cpu_to_node(cpu);
180 205
181 for (i = 1; i < PIN_MAP_SIZE; i++) 206 cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node);
182 pin[i-1].next = &pin[i]; 207 printk(KERN_DEBUG " alloc irq_cfg on cpu %d node %d\n", cpu, node);
183 208
184 irq_2_pin_ptr = &pin[0]; 209 return cfg;
185} 210}
186 211
187static struct irq_pin_list *get_one_free_irq_2_pin(void) 212void arch_init_chip_data(struct irq_desc *desc, int cpu)
188{ 213{
189 struct irq_pin_list *pin = irq_2_pin_ptr; 214 struct irq_cfg *cfg;
190 215
191 if (!pin) 216 cfg = desc->chip_data;
192 panic("can not get more irq_2_pin\n"); 217 if (!cfg) {
218 desc->chip_data = get_one_free_irq_cfg(cpu);
219 if (!desc->chip_data) {
220 printk(KERN_ERR "can not alloc irq_cfg\n");
221 BUG_ON(1);
222 }
223 }
224}
193 225
194 irq_2_pin_ptr = pin->next; 226#else
195 pin->next = NULL; 227static struct irq_cfg *irq_cfg(unsigned int irq)
196 return pin; 228{
229 return irq < nr_irqs ? irq_cfgx + irq : NULL;
197} 230}
198 231
232#endif
233
199struct io_apic { 234struct io_apic {
200 unsigned int index; 235 unsigned int index;
201 unsigned int unused[3]; 236 unsigned int unused[3];
@@ -397,16 +432,19 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
397 * shared ISA-space IRQs, so we have to support them. We are super 432 * shared ISA-space IRQs, so we have to support them. We are super
398 * fast in the common case, and fast for shared ISA-space IRQs. 433 * fast in the common case, and fast for shared ISA-space IRQs.
399 */ 434 */
400static void add_pin_to_irq(unsigned int irq, int apic, int pin) 435static void add_pin_to_irq_cpu(unsigned int irq, int cpu, int apic, int pin)
401{ 436{
402 struct irq_cfg *cfg;
403 struct irq_pin_list *entry; 437 struct irq_pin_list *entry;
438 struct irq_cfg *cfg = irq_cfg(irq);
404 439
405 /* first time to refer irq_cfg, so with new */
406 cfg = irq_cfg_alloc(irq);
407 entry = cfg->irq_2_pin; 440 entry = cfg->irq_2_pin;
408 if (!entry) { 441 if (!entry) {
409 entry = get_one_free_irq_2_pin(); 442 entry = get_one_free_irq_2_pin(cpu);
443 if (!entry) {
444 printk(KERN_ERR "can not alloc irq_2_pin to add %d - %d\n",
445 apic, pin);
446 return;
447 }
410 cfg->irq_2_pin = entry; 448 cfg->irq_2_pin = entry;
411 entry->apic = apic; 449 entry->apic = apic;
412 entry->pin = pin; 450 entry->pin = pin;
@@ -421,7 +459,7 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin)
421 entry = entry->next; 459 entry = entry->next;
422 } 460 }
423 461
424 entry->next = get_one_free_irq_2_pin(); 462 entry->next = get_one_free_irq_2_pin(cpu);
425 entry = entry->next; 463 entry = entry->next;
426 entry->apic = apic; 464 entry->apic = apic;
427 entry->pin = pin; 465 entry->pin = pin;
@@ -430,7 +468,7 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin)
430/* 468/*
431 * Reroute an IRQ to a different pin. 469 * Reroute an IRQ to a different pin.
432 */ 470 */
433static void __init replace_pin_at_irq(unsigned int irq, 471static void __init replace_pin_at_irq(unsigned int irq, int cpu,
434 int oldapic, int oldpin, 472 int oldapic, int oldpin,
435 int newapic, int newpin) 473 int newapic, int newpin)
436{ 474{
@@ -451,7 +489,7 @@ static void __init replace_pin_at_irq(unsigned int irq,
451 489
452 /* why? call replace before add? */ 490 /* why? call replace before add? */
453 if (!replaced) 491 if (!replaced)
454 add_pin_to_irq(irq, newapic, newpin); 492 add_pin_to_irq_cpu(irq, cpu, newapic, newpin);
455} 493}
456 494
457static inline void io_apic_modify_irq(unsigned int irq, 495static inline void io_apic_modify_irq(unsigned int irq,
@@ -1162,9 +1200,13 @@ void __setup_vector_irq(int cpu)
1162 /* This function must be called with vector_lock held */ 1200 /* This function must be called with vector_lock held */
1163 int irq, vector; 1201 int irq, vector;
1164 struct irq_cfg *cfg; 1202 struct irq_cfg *cfg;
1203 struct irq_desc *desc;
1165 1204
1166 /* Mark the inuse vectors */ 1205 /* Mark the inuse vectors */
1167 for_each_irq_cfg(irq, cfg) { 1206 for_each_irq_desc(irq, desc) {
1207 if (!desc)
1208 continue;
1209 cfg = desc->chip_data;
1168 if (!cpu_isset(cpu, cfg->domain)) 1210 if (!cpu_isset(cpu, cfg->domain))
1169 continue; 1211 continue;
1170 vector = cfg->vector; 1212 vector = cfg->vector;
@@ -1356,6 +1398,8 @@ static void __init setup_IO_APIC_irqs(void)
1356{ 1398{
1357 int apic, pin, idx, irq; 1399 int apic, pin, idx, irq;
1358 int notcon = 0; 1400 int notcon = 0;
1401 struct irq_desc *desc;
1402 int cpu = boot_cpu_id;
1359 1403
1360 apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); 1404 apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
1361 1405
@@ -1387,7 +1431,12 @@ static void __init setup_IO_APIC_irqs(void)
1387 if (multi_timer_check(apic, irq)) 1431 if (multi_timer_check(apic, irq))
1388 continue; 1432 continue;
1389#endif 1433#endif
1390 add_pin_to_irq(irq, apic, pin); 1434 desc = irq_to_desc_alloc_cpu(irq, cpu);
1435 if (!desc) {
1436 printk(KERN_INFO "can not get irq_desc for %d\n", irq);
1437 continue;
1438 }
1439 add_pin_to_irq_cpu(irq, cpu, apic, pin);
1391 1440
1392 setup_IO_APIC_irq(apic, pin, irq, 1441 setup_IO_APIC_irq(apic, pin, irq,
1393 irq_trigger(idx), irq_polarity(idx)); 1442 irq_trigger(idx), irq_polarity(idx));
@@ -1448,6 +1497,7 @@ __apicdebuginit(void) print_IO_APIC(void)
1448 union IO_APIC_reg_03 reg_03; 1497 union IO_APIC_reg_03 reg_03;
1449 unsigned long flags; 1498 unsigned long flags;
1450 struct irq_cfg *cfg; 1499 struct irq_cfg *cfg;
1500 struct irq_desc *desc;
1451 unsigned int irq; 1501 unsigned int irq;
1452 1502
1453 if (apic_verbosity == APIC_QUIET) 1503 if (apic_verbosity == APIC_QUIET)
@@ -1537,8 +1587,13 @@ __apicdebuginit(void) print_IO_APIC(void)
1537 } 1587 }
1538 } 1588 }
1539 printk(KERN_DEBUG "IRQ to pin mappings:\n"); 1589 printk(KERN_DEBUG "IRQ to pin mappings:\n");
1540 for_each_irq_cfg(irq, cfg) { 1590 for_each_irq_desc(irq, desc) {
1541 struct irq_pin_list *entry = cfg->irq_2_pin; 1591 struct irq_pin_list *entry;
1592
1593 if (!desc)
1594 continue;
1595 cfg = desc->chip_data;
1596 entry = cfg->irq_2_pin;
1542 if (!entry) 1597 if (!entry)
1543 continue; 1598 continue;
1544 printk(KERN_DEBUG "IRQ%d ", irq); 1599 printk(KERN_DEBUG "IRQ%d ", irq);
@@ -2022,6 +2077,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
2022{ 2077{
2023 int was_pending = 0; 2078 int was_pending = 0;
2024 unsigned long flags; 2079 unsigned long flags;
2080 struct irq_cfg *cfg;
2025 2081
2026 spin_lock_irqsave(&ioapic_lock, flags); 2082 spin_lock_irqsave(&ioapic_lock, flags);
2027 if (irq < 16) { 2083 if (irq < 16) {
@@ -2029,6 +2085,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
2029 if (i8259A_irq_pending(irq)) 2085 if (i8259A_irq_pending(irq))
2030 was_pending = 1; 2086 was_pending = 1;
2031 } 2087 }
2088 cfg = irq_cfg(irq);
2032 __unmask_IO_APIC_irq(irq); 2089 __unmask_IO_APIC_irq(irq);
2033 spin_unlock_irqrestore(&ioapic_lock, flags); 2090 spin_unlock_irqrestore(&ioapic_lock, flags);
2034 2091
@@ -2178,6 +2235,9 @@ static void ir_irq_migration(struct work_struct *work)
2178 struct irq_desc *desc; 2235 struct irq_desc *desc;
2179 2236
2180 for_each_irq_desc(irq, desc) { 2237 for_each_irq_desc(irq, desc) {
2238 if (!desc)
2239 continue;
2240
2181 if (desc->status & IRQ_MOVE_PENDING) { 2241 if (desc->status & IRQ_MOVE_PENDING) {
2182 unsigned long flags; 2242 unsigned long flags;
2183 2243
@@ -2229,6 +2289,9 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
2229 struct irq_cfg *cfg; 2289 struct irq_cfg *cfg;
2230 irq = __get_cpu_var(vector_irq)[vector]; 2290 irq = __get_cpu_var(vector_irq)[vector];
2231 2291
2292 if (irq == -1)
2293 continue;
2294
2232 desc = irq_to_desc(irq); 2295 desc = irq_to_desc(irq);
2233 if (!desc) 2296 if (!desc)
2234 continue; 2297 continue;
@@ -2430,8 +2493,12 @@ static inline void init_IO_APIC_traps(void)
2430 * Also, we've got to be careful not to trash gate 2493 * Also, we've got to be careful not to trash gate
2431 * 0x80, because int 0x80 is hm, kind of importantish. ;) 2494 * 0x80, because int 0x80 is hm, kind of importantish. ;)
2432 */ 2495 */
2433 for_each_irq_cfg(irq, cfg) { 2496 for_each_irq_desc(irq, desc) {
2434 if (IO_APIC_IRQ(irq) && !cfg->vector) { 2497 if (!desc)
2498 continue;
2499
2500 cfg = desc->chip_data;
2501 if (IO_APIC_IRQ(irq) && cfg && !cfg->vector) {
2435 /* 2502 /*
2436 * Hmm.. We don't have an entry for this, 2503 * Hmm.. We don't have an entry for this,
2437 * so default to an old-fashioned 8259 2504 * so default to an old-fashioned 8259
@@ -2439,11 +2506,9 @@ static inline void init_IO_APIC_traps(void)
2439 */ 2506 */
2440 if (irq < 16) 2507 if (irq < 16)
2441 make_8259A_irq(irq); 2508 make_8259A_irq(irq);
2442 else { 2509 else
2443 desc = irq_to_desc(irq);
2444 /* Strange. Oh, well.. */ 2510 /* Strange. Oh, well.. */
2445 desc->chip = &no_irq_chip; 2511 desc->chip = &no_irq_chip;
2446 }
2447 } 2512 }
2448 } 2513 }
2449} 2514}
@@ -2654,7 +2719,7 @@ static inline void __init check_timer(void)
2654 * Ok, does IRQ0 through the IOAPIC work? 2719 * Ok, does IRQ0 through the IOAPIC work?
2655 */ 2720 */
2656 if (no_pin1) { 2721 if (no_pin1) {
2657 add_pin_to_irq(0, apic1, pin1); 2722 add_pin_to_irq_cpu(0, boot_cpu_id, apic1, pin1);
2658 setup_timer_IRQ0_pin(apic1, pin1, cfg->vector); 2723 setup_timer_IRQ0_pin(apic1, pin1, cfg->vector);
2659 } 2724 }
2660 unmask_IO_APIC_irq(0); 2725 unmask_IO_APIC_irq(0);
@@ -2683,7 +2748,7 @@ static inline void __init check_timer(void)
2683 /* 2748 /*
2684 * legacy devices should be connected to IO APIC #0 2749 * legacy devices should be connected to IO APIC #0
2685 */ 2750 */
2686 replace_pin_at_irq(0, apic1, pin1, apic2, pin2); 2751 replace_pin_at_irq(0, boot_cpu_id, apic1, pin1, apic2, pin2);
2687 setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); 2752 setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
2688 unmask_IO_APIC_irq(0); 2753 unmask_IO_APIC_irq(0);
2689 enable_8259A_irq(0); 2754 enable_8259A_irq(0);
@@ -2902,21 +2967,25 @@ unsigned int create_irq_nr(unsigned int irq_want)
2902 unsigned int irq; 2967 unsigned int irq;
2903 unsigned int new; 2968 unsigned int new;
2904 unsigned long flags; 2969 unsigned long flags;
2905 struct irq_cfg *cfg_new; 2970 struct irq_cfg *cfg_new = NULL;
2906 2971 int cpu = boot_cpu_id;
2907 irq_want = nr_irqs - 1; 2972 struct irq_desc *desc_new = NULL;
2908 2973
2909 irq = 0; 2974 irq = 0;
2910 spin_lock_irqsave(&vector_lock, flags); 2975 spin_lock_irqsave(&vector_lock, flags);
2911 for (new = irq_want; new > 0; new--) { 2976 for (new = irq_want; new > 0; new--) {
2912 if (platform_legacy_irq(new)) 2977 if (platform_legacy_irq(new))
2913 continue; 2978 continue;
2914 cfg_new = irq_cfg(new); 2979
2915 if (cfg_new && cfg_new->vector != 0) 2980 desc_new = irq_to_desc_alloc_cpu(new, cpu);
2981 if (!desc_new) {
2982 printk(KERN_INFO "can not get irq_desc for %d\n", new);
2983 continue;
2984 }
2985 cfg_new = desc_new->chip_data;
2986
2987 if (cfg_new->vector != 0)
2916 continue; 2988 continue;
2917 /* check if need to create one */
2918 if (!cfg_new)
2919 cfg_new = irq_cfg_alloc(new);
2920 if (__assign_irq_vector(new, TARGET_CPUS) == 0) 2989 if (__assign_irq_vector(new, TARGET_CPUS) == 0)
2921 irq = new; 2990 irq = new;
2922 break; 2991 break;
@@ -2925,6 +2994,9 @@ unsigned int create_irq_nr(unsigned int irq_want)
2925 2994
2926 if (irq > 0) { 2995 if (irq > 0) {
2927 dynamic_irq_init(irq); 2996 dynamic_irq_init(irq);
2997 /* restore it, in case dynamic_irq_init clear it */
2998 if (desc_new)
2999 desc_new->chip_data = cfg_new;
2928 } 3000 }
2929 return irq; 3001 return irq;
2930} 3002}
@@ -2944,8 +3016,16 @@ int create_irq(void)
2944void destroy_irq(unsigned int irq) 3016void destroy_irq(unsigned int irq)
2945{ 3017{
2946 unsigned long flags; 3018 unsigned long flags;
3019 struct irq_cfg *cfg;
3020 struct irq_desc *desc;
2947 3021
3022 /* store it, in case dynamic_irq_cleanup clear it */
3023 desc = irq_to_desc(irq);
3024 cfg = desc->chip_data;
2948 dynamic_irq_cleanup(irq); 3025 dynamic_irq_cleanup(irq);
3026 /* connect back irq_cfg */
3027 if (desc)
3028 desc->chip_data = cfg;
2949 3029
2950#ifdef CONFIG_INTR_REMAP 3030#ifdef CONFIG_INTR_REMAP
2951 free_irte(irq); 3031 free_irte(irq);
@@ -3195,26 +3275,13 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc, int irq)
3195 return 0; 3275 return 0;
3196} 3276}
3197 3277
3198static unsigned int build_irq_for_pci_dev(struct pci_dev *dev) 3278int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc)
3199{
3200 unsigned int irq;
3201
3202 irq = dev->bus->number;
3203 irq <<= 8;
3204 irq |= dev->devfn;
3205 irq <<= 12;
3206
3207 return irq;
3208}
3209
3210int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
3211{ 3279{
3212 unsigned int irq; 3280 unsigned int irq;
3213 int ret; 3281 int ret;
3214 unsigned int irq_want; 3282 unsigned int irq_want;
3215 3283
3216 irq_want = build_irq_for_pci_dev(dev) + 0x100; 3284 irq_want = nr_irqs - 1;
3217
3218 irq = create_irq_nr(irq_want); 3285 irq = create_irq_nr(irq_want);
3219 if (irq == 0) 3286 if (irq == 0)
3220 return -1; 3287 return -1;
@@ -3228,7 +3295,7 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
3228 goto error; 3295 goto error;
3229no_ir: 3296no_ir:
3230#endif 3297#endif
3231 ret = setup_msi_irq(dev, desc, irq); 3298 ret = setup_msi_irq(dev, msidesc, irq);
3232 if (ret < 0) { 3299 if (ret < 0) {
3233 destroy_irq(irq); 3300 destroy_irq(irq);
3234 return ret; 3301 return ret;
@@ -3246,7 +3313,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
3246{ 3313{
3247 unsigned int irq; 3314 unsigned int irq;
3248 int ret, sub_handle; 3315 int ret, sub_handle;
3249 struct msi_desc *desc; 3316 struct msi_desc *msidesc;
3250 unsigned int irq_want; 3317 unsigned int irq_want;
3251 3318
3252#ifdef CONFIG_INTR_REMAP 3319#ifdef CONFIG_INTR_REMAP
@@ -3254,10 +3321,11 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
3254 int index = 0; 3321 int index = 0;
3255#endif 3322#endif
3256 3323
3257 irq_want = build_irq_for_pci_dev(dev) + 0x100; 3324 irq_want = nr_irqs - 1;
3258 sub_handle = 0; 3325 sub_handle = 0;
3259 list_for_each_entry(desc, &dev->msi_list, list) { 3326 list_for_each_entry(msidesc, &dev->msi_list, list) {
3260 irq = create_irq_nr(irq_want--); 3327 irq = create_irq_nr(irq_want);
3328 irq_want--;
3261 if (irq == 0) 3329 if (irq == 0)
3262 return -1; 3330 return -1;
3263#ifdef CONFIG_INTR_REMAP 3331#ifdef CONFIG_INTR_REMAP
@@ -3289,7 +3357,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
3289 } 3357 }
3290no_ir: 3358no_ir:
3291#endif 3359#endif
3292 ret = setup_msi_irq(dev, desc, irq); 3360 ret = setup_msi_irq(dev, msidesc, irq);
3293 if (ret < 0) 3361 if (ret < 0)
3294 goto error; 3362 goto error;
3295 sub_handle++; 3363 sub_handle++;
@@ -3707,17 +3775,29 @@ int __init io_apic_get_version(int ioapic)
3707 3775
3708int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity) 3776int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity)
3709{ 3777{
3778 struct irq_desc *desc;
3779 struct irq_cfg *cfg;
3780 int cpu = boot_cpu_id;
3781
3710 if (!IO_APIC_IRQ(irq)) { 3782 if (!IO_APIC_IRQ(irq)) {
3711 apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", 3783 apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
3712 ioapic); 3784 ioapic);
3713 return -EINVAL; 3785 return -EINVAL;
3714 } 3786 }
3715 3787
3788 desc = irq_to_desc_alloc_cpu(irq, cpu);
3789 if (!desc) {
3790 printk(KERN_INFO "can not get irq_desc %d\n", irq);
3791 return 0;
3792 }
3793
3716 /* 3794 /*
3717 * IRQs < 16 are already in the irq_2_pin[] map 3795 * IRQs < 16 are already in the irq_2_pin[] map
3718 */ 3796 */
3719 if (irq >= 16) 3797 if (irq >= 16) {
3720 add_pin_to_irq(irq, ioapic, pin); 3798 cfg = desc->chip_data;
3799 add_pin_to_irq_cpu(irq, cpu, ioapic, pin);
3800 }
3721 3801
3722 setup_IO_APIC_irq(ioapic, pin, irq, triggering, polarity); 3802 setup_IO_APIC_irq(ioapic, pin, irq, triggering, polarity);
3723 3803
@@ -3773,7 +3853,8 @@ void __init setup_ioapic_dest(void)
3773 * when you have too many devices, because at that time only boot 3853 * when you have too many devices, because at that time only boot
3774 * cpu is online. 3854 * cpu is online.
3775 */ 3855 */
3776 cfg = irq_cfg(irq); 3856 desc = irq_to_desc(irq);
3857 cfg = desc->chip_data;
3777 if (!cfg->vector) { 3858 if (!cfg->vector) {
3778 setup_IO_APIC_irq(ioapic, pin, irq, 3859 setup_IO_APIC_irq(ioapic, pin, irq,
3779 irq_trigger(irq_entry), 3860 irq_trigger(irq_entry),
@@ -3785,7 +3866,6 @@ void __init setup_ioapic_dest(void)
3785 /* 3866 /*
3786 * Honour affinities which have been set in early boot 3867 * Honour affinities which have been set in early boot
3787 */ 3868 */
3788 desc = irq_to_desc(irq);
3789 if (desc->status & 3869 if (desc->status &
3790 (IRQ_NO_BALANCING | IRQ_AFFINITY_SET)) 3870 (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
3791 mask = desc->affinity; 3871 mask = desc->affinity;
@@ -3846,7 +3926,6 @@ void __init ioapic_init_mappings(void)
3846 struct resource *ioapic_res; 3926 struct resource *ioapic_res;
3847 int i; 3927 int i;
3848 3928
3849 irq_2_pin_init();
3850 ioapic_res = ioapic_setup_resources(); 3929 ioapic_res = ioapic_setup_resources();
3851 for (i = 0; i < nr_ioapics; i++) { 3930 for (i = 0; i < nr_ioapics; i++) {
3852 if (smp_found_config) { 3931 if (smp_found_config) {
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index d1d4dc52f649..3f1d9d18df67 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -118,6 +118,9 @@ int show_interrupts(struct seq_file *p, void *v)
118 } 118 }
119 119
120 desc = irq_to_desc(i); 120 desc = irq_to_desc(i);
121 if (!desc)
122 return 0;
123
121 spin_lock_irqsave(&desc->lock, flags); 124 spin_lock_irqsave(&desc->lock, flags);
122#ifndef CONFIG_SMP 125#ifndef CONFIG_SMP
123 any_count = kstat_irqs(i); 126 any_count = kstat_irqs(i);
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index a51382672de0..119fc9c8ff7f 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -242,6 +242,8 @@ void fixup_irqs(cpumask_t map)
242 for_each_irq_desc(irq, desc) { 242 for_each_irq_desc(irq, desc) {
243 cpumask_t mask; 243 cpumask_t mask;
244 244
245 if (!desc)
246 continue;
245 if (irq == 2) 247 if (irq == 2)
246 continue; 248 continue;
247 249
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 60eb84eb77a0..900009c70591 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -94,6 +94,8 @@ void fixup_irqs(cpumask_t map)
94 int break_affinity = 0; 94 int break_affinity = 0;
95 int set_affinity = 1; 95 int set_affinity = 1;
96 96
97 if (!desc)
98 continue;
97 if (irq == 2) 99 if (irq == 2)
98 continue; 100 continue;
99 101
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c
index 845aa9803e80..5a5651b7f9e6 100644
--- a/arch/x86/kernel/irqinit_32.c
+++ b/arch/x86/kernel/irqinit_32.c
@@ -69,7 +69,6 @@ void __init init_ISA_irqs (void)
69 * 16 old-style INTA-cycle interrupts: 69 * 16 old-style INTA-cycle interrupts:
70 */ 70 */
71 for (i = 0; i < 16; i++) { 71 for (i = 0; i < 16; i++) {
72 /* first time call this irq_desc */
73 struct irq_desc *desc = irq_to_desc(i); 72 struct irq_desc *desc = irq_to_desc(i);
74 73
75 desc->status = IRQ_DISABLED; 74 desc->status = IRQ_DISABLED;
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c
index ff0235391285..cd9f42d028d9 100644
--- a/arch/x86/kernel/irqinit_64.c
+++ b/arch/x86/kernel/irqinit_64.c
@@ -143,7 +143,6 @@ void __init init_ISA_irqs(void)
143 init_8259A(0); 143 init_8259A(0);
144 144
145 for (i = 0; i < 16; i++) { 145 for (i = 0; i < 16; i++) {
146 /* first time call this irq_desc */
147 struct irq_desc *desc = irq_to_desc(i); 146 struct irq_desc *desc = irq_to_desc(i);
148 147
149 desc->status = IRQ_DISABLED; 148 desc->status = IRQ_DISABLED;
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 675076f5fca8..d26891bfcd41 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -558,23 +558,9 @@ struct timer_rand_state {
558 unsigned dont_count_entropy:1; 558 unsigned dont_count_entropy:1;
559}; 559};
560 560
561static struct timer_rand_state *irq_timer_state[NR_IRQS]; 561#ifndef CONFIG_SPARSE_IRQ
562 562struct timer_rand_state *irq_timer_state[NR_IRQS];
563static struct timer_rand_state *get_timer_rand_state(unsigned int irq) 563#endif
564{
565 if (irq >= nr_irqs)
566 return NULL;
567
568 return irq_timer_state[irq];
569}
570
571static void set_timer_rand_state(unsigned int irq, struct timer_rand_state *state)
572{
573 if (irq >= nr_irqs)
574 return;
575
576 irq_timer_state[irq] = state;
577}
578 564
579static struct timer_rand_state input_timer_state; 565static struct timer_rand_state input_timer_state;
580 566
@@ -933,8 +919,10 @@ void rand_initialize_irq(int irq)
933{ 919{
934 struct timer_rand_state *state; 920 struct timer_rand_state *state;
935 921
922#ifndef CONFIG_SPARSE_IRQ
936 if (irq >= nr_irqs) 923 if (irq >= nr_irqs)
937 return; 924 return;
925#endif
938 926
939 state = get_timer_rand_state(irq); 927 state = get_timer_rand_state(irq);
940 928
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index 2de5a3238c94..c9958ec5e25e 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -19,17 +19,75 @@ struct irq_2_iommu {
19 u8 irte_mask; 19 u8 irte_mask;
20}; 20};
21 21
22static struct irq_2_iommu irq_2_iommuX[NR_IRQS]; 22#ifdef CONFIG_SPARSE_IRQ
23static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
24{
25 struct irq_2_iommu *iommu;
26 int node;
27
28 node = cpu_to_node(cpu);
29
30 iommu = kzalloc_node(sizeof(*iommu), GFP_ATOMIC, node);
31 printk(KERN_DEBUG "alloc irq_2_iommu on cpu %d node %d\n", cpu, node);
32
33 return iommu;
34}
23 35
24static struct irq_2_iommu *irq_2_iommu(unsigned int irq) 36static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
25{ 37{
26 return (irq < nr_irqs) ? irq_2_iommuX + irq : NULL; 38 struct irq_desc *desc;
39
40 desc = irq_to_desc(irq);
41
42 if (WARN_ON_ONCE(!desc))
43 return NULL;
44
45 return desc->irq_2_iommu;
46}
47
48static struct irq_2_iommu *irq_2_iommu_alloc_cpu(unsigned int irq, int cpu)
49{
50 struct irq_desc *desc;
51 struct irq_2_iommu *irq_iommu;
52
53 /*
54 * alloc irq desc if not allocated already.
55 */
56 desc = irq_to_desc_alloc_cpu(irq, cpu);
57 if (!desc) {
58 printk(KERN_INFO "can not get irq_desc for %d\n", irq);
59 return NULL;
60 }
61
62 irq_iommu = desc->irq_2_iommu;
63
64 if (!irq_iommu)
65 desc->irq_2_iommu = get_one_free_irq_2_iommu(cpu);
66
67 return desc->irq_2_iommu;
27} 68}
28 69
29static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq) 70static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
30{ 71{
72 return irq_2_iommu_alloc_cpu(irq, boot_cpu_id);
73}
74
75#else /* !CONFIG_SPARSE_IRQ */
76
77static struct irq_2_iommu irq_2_iommuX[NR_IRQS];
78
79static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
80{
81 if (irq < nr_irqs)
82 return &irq_2_iommuX[irq];
83
84 return NULL;
85}
86static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
87{
31 return irq_2_iommu(irq); 88 return irq_2_iommu(irq);
32} 89}
90#endif
33 91
34static DEFINE_SPINLOCK(irq_2_ir_lock); 92static DEFINE_SPINLOCK(irq_2_ir_lock);
35 93
@@ -86,9 +144,11 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
86 if (!count) 144 if (!count)
87 return -1; 145 return -1;
88 146
147#ifndef CONFIG_SPARSE_IRQ
89 /* protect irq_2_iommu_alloc later */ 148 /* protect irq_2_iommu_alloc later */
90 if (irq >= nr_irqs) 149 if (irq >= nr_irqs)
91 return -1; 150 return -1;
151#endif
92 152
93 /* 153 /*
94 * start the IRTE search from index 0. 154 * start the IRTE search from index 0.
@@ -130,6 +190,12 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
130 table->base[i].present = 1; 190 table->base[i].present = 1;
131 191
132 irq_iommu = irq_2_iommu_alloc(irq); 192 irq_iommu = irq_2_iommu_alloc(irq);
193 if (!irq_iommu) {
194 spin_unlock(&irq_2_ir_lock);
195 printk(KERN_ERR "can't allocate irq_2_iommu\n");
196 return -1;
197 }
198
133 irq_iommu->iommu = iommu; 199 irq_iommu->iommu = iommu;
134 irq_iommu->irte_index = index; 200 irq_iommu->irte_index = index;
135 irq_iommu->sub_handle = 0; 201 irq_iommu->sub_handle = 0;
@@ -177,6 +243,12 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
177 243
178 irq_iommu = irq_2_iommu_alloc(irq); 244 irq_iommu = irq_2_iommu_alloc(irq);
179 245
246 if (!irq_iommu) {
247 spin_unlock(&irq_2_ir_lock);
248 printk(KERN_ERR "can't allocate irq_2_iommu\n");
249 return -1;
250 }
251
180 irq_iommu->iommu = iommu; 252 irq_iommu->iommu = iommu;
181 irq_iommu->irte_index = index; 253 irq_iommu->irte_index = index;
182 irq_iommu->sub_handle = subhandle; 254 irq_iommu->sub_handle = subhandle;
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 1e3b934a4cf7..2924faa7f6c4 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -141,8 +141,12 @@ static void init_evtchn_cpu_bindings(void)
141 int i; 141 int i;
142 142
143 /* By default all event channels notify CPU#0. */ 143 /* By default all event channels notify CPU#0. */
144 for_each_irq_desc(i, desc) 144 for_each_irq_desc(i, desc) {
145 if (!desc)
146 continue;
147
145 desc->affinity = cpumask_of_cpu(0); 148 desc->affinity = cpumask_of_cpu(0);
149 }
146#endif 150#endif
147 151
148 memset(cpu_evtchn, 0, sizeof(cpu_evtchn)); 152 memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
@@ -231,7 +235,7 @@ static int find_unbound_irq(void)
231 int irq; 235 int irq;
232 236
233 /* Only allocate from dynirq range */ 237 /* Only allocate from dynirq range */
234 for_each_irq_nr(irq) 238 for (irq = 0; irq < nr_irqs; irq++)
235 if (irq_bindcount[irq] == 0) 239 if (irq_bindcount[irq] == 0)
236 break; 240 break;
237 241
@@ -792,7 +796,7 @@ void xen_irq_resume(void)
792 mask_evtchn(evtchn); 796 mask_evtchn(evtchn);
793 797
794 /* No IRQ <-> event-channel mappings. */ 798 /* No IRQ <-> event-channel mappings. */
795 for_each_irq_nr(irq) 799 for (irq = 0; irq < nr_irqs; irq++)
796 irq_info[irq].evtchn = 0; /* zap event-channel binding */ 800 irq_info[irq].evtchn = 0; /* zap event-channel binding */
797 801
798 for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) 802 for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
@@ -824,7 +828,7 @@ void __init xen_init_IRQ(void)
824 mask_evtchn(i); 828 mask_evtchn(i);
825 829
826 /* Dynamic IRQ space is currently unbound. Zero the refcnts. */ 830 /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
827 for_each_irq_nr(i) 831 for (i = 0; i < nr_irqs; i++)
828 irq_bindcount[i] = 0; 832 irq_bindcount[i] = 0;
829 833
830 irq_ctx_init(smp_processor_id()); 834 irq_ctx_init(smp_processor_id());
diff --git a/fs/proc/stat.c b/fs/proc/stat.c
index 81904f07679d..a13431ab7c65 100644
--- a/fs/proc/stat.c
+++ b/fs/proc/stat.c
@@ -27,6 +27,7 @@ static int show_stat(struct seq_file *p, void *v)
27 u64 sum = 0; 27 u64 sum = 0;
28 struct timespec boottime; 28 struct timespec boottime;
29 unsigned int per_irq_sum; 29 unsigned int per_irq_sum;
30 struct irq_desc *desc;
30 31
31 user = nice = system = idle = iowait = 32 user = nice = system = idle = iowait =
32 irq = softirq = steal = cputime64_zero; 33 irq = softirq = steal = cputime64_zero;
@@ -44,10 +45,11 @@ static int show_stat(struct seq_file *p, void *v)
44 softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq); 45 softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
45 steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal); 46 steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
46 guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); 47 guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
47 48 for_each_irq_desc(j, desc) {
48 for_each_irq_nr(j) 49 if (!desc)
50 continue;
49 sum += kstat_irqs_cpu(j, i); 51 sum += kstat_irqs_cpu(j, i);
50 52 }
51 sum += arch_irq_stat_cpu(i); 53 sum += arch_irq_stat_cpu(i);
52 } 54 }
53 sum += arch_irq_stat(); 55 sum += arch_irq_stat();
@@ -90,11 +92,14 @@ static int show_stat(struct seq_file *p, void *v)
90 seq_printf(p, "intr %llu", (unsigned long long)sum); 92 seq_printf(p, "intr %llu", (unsigned long long)sum);
91 93
92 /* sum again ? it could be updated? */ 94 /* sum again ? it could be updated? */
93 for_each_irq_nr(j) { 95 for (j = 0; j < NR_IRQS; j++) {
96 desc = irq_to_desc(j);
94 per_irq_sum = 0; 97 per_irq_sum = 0;
95 98
96 for_each_possible_cpu(i) 99 if (desc) {
97 per_irq_sum += kstat_irqs_cpu(j, i); 100 for_each_possible_cpu(i)
101 per_irq_sum += kstat_irqs_cpu(j, i);
102 }
98 103
99 seq_printf(p, " %u", per_irq_sum); 104 seq_printf(p, " %u", per_irq_sum);
100 } 105 }
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index f58a0cf8929a..79e915e7e8a5 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -18,6 +18,8 @@
18#include <asm/ptrace.h> 18#include <asm/ptrace.h>
19#include <asm/system.h> 19#include <asm/system.h>
20 20
21extern int nr_irqs;
22
21/* 23/*
22 * These correspond to the IORESOURCE_IRQ_* defines in 24 * These correspond to the IORESOURCE_IRQ_* defines in
23 * linux/ioport.h to select the interrupt line behaviour. When 25 * linux/ioport.h to select the interrupt line behaviour. When
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 3dddfa703ebd..63b00439d4d2 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -129,6 +129,8 @@ struct irq_chip {
129 const char *typename; 129 const char *typename;
130}; 130};
131 131
132struct timer_rand_state;
133struct irq_2_iommu;
132/** 134/**
133 * struct irq_desc - interrupt descriptor 135 * struct irq_desc - interrupt descriptor
134 * @irq: interrupt number for this descriptor 136 * @irq: interrupt number for this descriptor
@@ -154,6 +156,13 @@ struct irq_chip {
154 */ 156 */
155struct irq_desc { 157struct irq_desc {
156 unsigned int irq; 158 unsigned int irq;
159#ifdef CONFIG_SPARSE_IRQ
160 struct timer_rand_state *timer_rand_state;
161 unsigned int *kstat_irqs;
162# ifdef CONFIG_INTR_REMAP
163 struct irq_2_iommu *irq_2_iommu;
164# endif
165#endif
157 irq_flow_handler_t handle_irq; 166 irq_flow_handler_t handle_irq;
158 struct irq_chip *chip; 167 struct irq_chip *chip;
159 struct msi_desc *msi_desc; 168 struct msi_desc *msi_desc;
@@ -181,14 +190,52 @@ struct irq_desc {
181 const char *name; 190 const char *name;
182} ____cacheline_internodealigned_in_smp; 191} ____cacheline_internodealigned_in_smp;
183 192
193extern void early_irq_init(void);
194extern void arch_early_irq_init(void);
195extern void arch_init_chip_data(struct irq_desc *desc, int cpu);
196extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
197 struct irq_desc *desc, int cpu);
198extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
199
200#ifndef CONFIG_SPARSE_IRQ
184 201
185extern struct irq_desc irq_desc[NR_IRQS]; 202extern struct irq_desc irq_desc[NR_IRQS];
186 203
187static inline struct irq_desc *irq_to_desc(unsigned int irq) 204static inline struct irq_desc *irq_to_desc(unsigned int irq)
188{ 205{
189 return (irq < nr_irqs) ? irq_desc + irq : NULL; 206 return (irq < NR_IRQS) ? irq_desc + irq : NULL;
207}
208static inline struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
209{
210 return irq_to_desc(irq);
190} 211}
191 212
213#ifdef CONFIG_GENERIC_HARDIRQS
214# define for_each_irq_desc(irq, desc) \
215 for (irq = 0, desc = irq_desc; irq < nr_irqs; irq++, desc++)
216# define for_each_irq_desc_reverse(irq, desc) \
217 for (irq = nr_irqs - 1, desc = irq_desc + (nr_irqs - 1); \
218 irq >= 0; irq--, desc--)
219#endif
220
221#else
222
223extern struct irq_desc *irq_to_desc(unsigned int irq);
224extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu);
225extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu);
226
227# define for_each_irq_desc(irq, desc) \
228 for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs; irq++, desc = irq_to_desc(irq))
229# define for_each_irq_desc_reverse(irq, desc) \
230 for (irq = nr_irqs - 1, desc = irq_to_desc(irq); irq >= 0; irq--, desc = irq_to_desc(irq))
231
232#define kstat_irqs_this_cpu(DESC) \
233 ((DESC)->kstat_irqs[smp_processor_id()])
234#define kstat_incr_irqs_this_cpu(irqno, DESC) \
235 ((DESC)->kstat_irqs[smp_processor_id()]++)
236
237#endif
238
192/* 239/*
193 * Migration helpers for obsolete names, they will go away: 240 * Migration helpers for obsolete names, they will go away:
194 */ 241 */
@@ -380,6 +427,11 @@ extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
380#define get_irq_data(irq) (irq_to_desc(irq)->handler_data) 427#define get_irq_data(irq) (irq_to_desc(irq)->handler_data)
381#define get_irq_msi(irq) (irq_to_desc(irq)->msi_desc) 428#define get_irq_msi(irq) (irq_to_desc(irq)->msi_desc)
382 429
430#define get_irq_desc_chip(desc) ((desc)->chip)
431#define get_irq_desc_chip_data(desc) ((desc)->chip_data)
432#define get_irq_desc_data(desc) ((desc)->handler_data)
433#define get_irq_desc_msi(desc) ((desc)->msi_desc)
434
383#endif /* CONFIG_GENERIC_HARDIRQS */ 435#endif /* CONFIG_GENERIC_HARDIRQS */
384 436
385#endif /* !CONFIG_S390 */ 437#endif /* !CONFIG_S390 */
diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h
index 452c280c8115..7a299e989f8b 100644
--- a/include/linux/irqnr.h
+++ b/include/linux/irqnr.h
@@ -7,18 +7,10 @@
7 7
8# define for_each_irq_desc(irq, desc) \ 8# define for_each_irq_desc(irq, desc) \
9 for (irq = 0; irq < nr_irqs; irq++) 9 for (irq = 0; irq < nr_irqs; irq++)
10#else
11extern int nr_irqs;
12 10
13# define for_each_irq_desc(irq, desc) \ 11static inline early_sparse_irq_init(void)
14 for (irq = 0, desc = irq_desc; irq < nr_irqs; irq++, desc++) 12{
15 13}
16# define for_each_irq_desc_reverse(irq, desc) \
17 for (irq = nr_irqs - 1, desc = irq_desc + (nr_irqs - 1); \
18 irq >= 0; irq--, desc--)
19#endif 14#endif
20 15
21#define for_each_irq_nr(irq) \
22 for (irq = 0; irq < nr_irqs; irq++)
23
24#endif 16#endif
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 4a145caeee07..4ee4b3d2316f 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -28,7 +28,9 @@ struct cpu_usage_stat {
28 28
29struct kernel_stat { 29struct kernel_stat {
30 struct cpu_usage_stat cpustat; 30 struct cpu_usage_stat cpustat;
31 unsigned int irqs[NR_IRQS]; 31#ifndef CONFIG_SPARSE_IRQ
32 unsigned int irqs[NR_IRQS];
33#endif
32}; 34};
33 35
34DECLARE_PER_CPU(struct kernel_stat, kstat); 36DECLARE_PER_CPU(struct kernel_stat, kstat);
@@ -39,6 +41,10 @@ DECLARE_PER_CPU(struct kernel_stat, kstat);
39 41
40extern unsigned long long nr_context_switches(void); 42extern unsigned long long nr_context_switches(void);
41 43
44#ifndef CONFIG_SPARSE_IRQ
45#define kstat_irqs_this_cpu(irq) \
46 (kstat_this_cpu.irqs[irq])
47
42struct irq_desc; 48struct irq_desc;
43 49
44static inline void kstat_incr_irqs_this_cpu(unsigned int irq, 50static inline void kstat_incr_irqs_this_cpu(unsigned int irq,
@@ -46,11 +52,17 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq,
46{ 52{
47 kstat_this_cpu.irqs[irq]++; 53 kstat_this_cpu.irqs[irq]++;
48} 54}
55#endif
56
49 57
58#ifndef CONFIG_SPARSE_IRQ
50static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) 59static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
51{ 60{
52 return kstat_cpu(cpu).irqs[irq]; 61 return kstat_cpu(cpu).irqs[irq];
53} 62}
63#else
64extern unsigned int kstat_irqs_cpu(unsigned int irq, int cpu);
65#endif
54 66
55/* 67/*
56 * Number of interrupts per specific IRQ source, since bootup 68 * Number of interrupts per specific IRQ source, since bootup
diff --git a/include/linux/random.h b/include/linux/random.h
index 36f125c0c603..ad9daa2374d5 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -44,6 +44,57 @@ struct rand_pool_info {
44 44
45extern void rand_initialize_irq(int irq); 45extern void rand_initialize_irq(int irq);
46 46
47struct timer_rand_state;
48#ifndef CONFIG_SPARSE_IRQ
49
50extern struct timer_rand_state *irq_timer_state[];
51
52extern int nr_irqs;
53static inline struct timer_rand_state *get_timer_rand_state(unsigned int irq)
54{
55 if (irq >= nr_irqs)
56 return NULL;
57
58 return irq_timer_state[irq];
59}
60
61static inline void set_timer_rand_state(unsigned int irq, struct timer_rand_state *state)
62{
63 if (irq >= nr_irqs)
64 return;
65
66 irq_timer_state[irq] = state;
67}
68
69#else
70
71#include <linux/irq.h>
72static inline struct timer_rand_state *get_timer_rand_state(unsigned int irq)
73{
74 struct irq_desc *desc;
75
76 desc = irq_to_desc(irq);
77
78 if (!desc)
79 return NULL;
80
81 return desc->timer_rand_state;
82}
83
84static inline void set_timer_rand_state(unsigned int irq, struct timer_rand_state *state)
85{
86 struct irq_desc *desc;
87
88 desc = irq_to_desc(irq);
89
90 if (!desc)
91 return;
92
93 desc->timer_rand_state = state;
94}
95#endif
96
97
47extern void add_input_randomness(unsigned int type, unsigned int code, 98extern void add_input_randomness(unsigned int type, unsigned int code,
48 unsigned int value); 99 unsigned int value);
49extern void add_interrupt_randomness(int irq); 100extern void add_interrupt_randomness(int irq);
diff --git a/init/main.c b/init/main.c
index 7e117a231af1..c1f999a3cf31 100644
--- a/init/main.c
+++ b/init/main.c
@@ -539,6 +539,15 @@ void __init __weak thread_info_cache_init(void)
539{ 539{
540} 540}
541 541
542void __init __weak arch_early_irq_init(void)
543{
544}
545
546void __init __weak early_irq_init(void)
547{
548 arch_early_irq_init();
549}
550
542asmlinkage void __init start_kernel(void) 551asmlinkage void __init start_kernel(void)
543{ 552{
544 char * command_line; 553 char * command_line;
@@ -603,6 +612,8 @@ asmlinkage void __init start_kernel(void)
603 sort_main_extable(); 612 sort_main_extable();
604 trap_init(); 613 trap_init();
605 rcu_init(); 614 rcu_init();
615 /* init some links before init_ISA_irqs() */
616 early_irq_init();
606 init_IRQ(); 617 init_IRQ();
607 pidhash_init(); 618 pidhash_init();
608 init_timers(); 619 init_timers();
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index cc0f7321b8ce..650ce4102a63 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -40,6 +40,9 @@ unsigned long probe_irq_on(void)
40 * flush such a longstanding irq before considering it as spurious. 40 * flush such a longstanding irq before considering it as spurious.
41 */ 41 */
42 for_each_irq_desc_reverse(i, desc) { 42 for_each_irq_desc_reverse(i, desc) {
43 if (!desc)
44 continue;
45
43 spin_lock_irq(&desc->lock); 46 spin_lock_irq(&desc->lock);
44 if (!desc->action && !(desc->status & IRQ_NOPROBE)) { 47 if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
45 /* 48 /*
@@ -68,6 +71,9 @@ unsigned long probe_irq_on(void)
68 * happened in the previous stage, it may have masked itself) 71 * happened in the previous stage, it may have masked itself)
69 */ 72 */
70 for_each_irq_desc_reverse(i, desc) { 73 for_each_irq_desc_reverse(i, desc) {
74 if (!desc)
75 continue;
76
71 spin_lock_irq(&desc->lock); 77 spin_lock_irq(&desc->lock);
72 if (!desc->action && !(desc->status & IRQ_NOPROBE)) { 78 if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
73 desc->status |= IRQ_AUTODETECT | IRQ_WAITING; 79 desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
@@ -86,6 +92,9 @@ unsigned long probe_irq_on(void)
86 * Now filter out any obviously spurious interrupts 92 * Now filter out any obviously spurious interrupts
87 */ 93 */
88 for_each_irq_desc(i, desc) { 94 for_each_irq_desc(i, desc) {
95 if (!desc)
96 continue;
97
89 spin_lock_irq(&desc->lock); 98 spin_lock_irq(&desc->lock);
90 status = desc->status; 99 status = desc->status;
91 100
@@ -124,6 +133,9 @@ unsigned int probe_irq_mask(unsigned long val)
124 int i; 133 int i;
125 134
126 for_each_irq_desc(i, desc) { 135 for_each_irq_desc(i, desc) {
136 if (!desc)
137 continue;
138
127 spin_lock_irq(&desc->lock); 139 spin_lock_irq(&desc->lock);
128 status = desc->status; 140 status = desc->status;
129 141
@@ -166,6 +178,9 @@ int probe_irq_off(unsigned long val)
166 unsigned int status; 178 unsigned int status;
167 179
168 for_each_irq_desc(i, desc) { 180 for_each_irq_desc(i, desc) {
181 if (!desc)
182 continue;
183
169 spin_lock_irq(&desc->lock); 184 spin_lock_irq(&desc->lock);
170 status = desc->status; 185 status = desc->status;
171 186
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 10b5092e9bfe..8e4fce4a1b1f 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -24,9 +24,10 @@
24 */ 24 */
25void dynamic_irq_init(unsigned int irq) 25void dynamic_irq_init(unsigned int irq)
26{ 26{
27 struct irq_desc *desc = irq_to_desc(irq); 27 struct irq_desc *desc;
28 unsigned long flags; 28 unsigned long flags;
29 29
30 desc = irq_to_desc(irq);
30 if (!desc) { 31 if (!desc) {
31 WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); 32 WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
32 return; 33 return;
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index c815b42d0f5b..96ca203eb51b 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -15,9 +15,16 @@
15#include <linux/random.h> 15#include <linux/random.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/kernel_stat.h> 17#include <linux/kernel_stat.h>
18#include <linux/rculist.h>
19#include <linux/hash.h>
18 20
19#include "internals.h" 21#include "internals.h"
20 22
23/*
24 * lockdep: we want to handle all irq_desc locks as a single lock-class:
25 */
26static struct lock_class_key irq_desc_lock_class;
27
21/** 28/**
22 * handle_bad_irq - handle spurious and unhandled irqs 29 * handle_bad_irq - handle spurious and unhandled irqs
23 * @irq: the interrupt number 30 * @irq: the interrupt number
@@ -49,6 +56,155 @@ void handle_bad_irq(unsigned int irq, struct irq_desc *desc)
49int nr_irqs = NR_IRQS; 56int nr_irqs = NR_IRQS;
50EXPORT_SYMBOL_GPL(nr_irqs); 57EXPORT_SYMBOL_GPL(nr_irqs);
51 58
59void __init __attribute__((weak)) arch_early_irq_init(void)
60{
61}
62
63#ifdef CONFIG_SPARSE_IRQ
64static struct irq_desc irq_desc_init = {
65 .irq = -1,
66 .status = IRQ_DISABLED,
67 .chip = &no_irq_chip,
68 .handle_irq = handle_bad_irq,
69 .depth = 1,
70 .lock = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
71#ifdef CONFIG_SMP
72 .affinity = CPU_MASK_ALL
73#endif
74};
75
76static void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
77{
78 unsigned long bytes;
79 char *ptr;
80 int node;
81
82 /* Compute how many bytes we need per irq and allocate them */
83 bytes = nr * sizeof(unsigned int);
84
85 node = cpu_to_node(cpu);
86 ptr = kzalloc_node(bytes, GFP_ATOMIC, node);
87 printk(KERN_DEBUG " alloc kstat_irqs on cpu %d node %d\n", cpu, node);
88
89 if (ptr)
90 desc->kstat_irqs = (unsigned int *)ptr;
91}
92
93void __attribute__((weak)) arch_init_chip_data(struct irq_desc *desc, int cpu)
94{
95}
96
97static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu)
98{
99 memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
100 desc->irq = irq;
101#ifdef CONFIG_SMP
102 desc->cpu = cpu;
103#endif
104 lockdep_set_class(&desc->lock, &irq_desc_lock_class);
105 init_kstat_irqs(desc, cpu, nr_cpu_ids);
106 if (!desc->kstat_irqs) {
107 printk(KERN_ERR "can not alloc kstat_irqs\n");
108 BUG_ON(1);
109 }
110 arch_init_chip_data(desc, cpu);
111}
112
113/*
114 * Protect the sparse_irqs:
115 */
116static DEFINE_SPINLOCK(sparse_irq_lock);
117
118struct irq_desc *irq_desc_ptrs[NR_IRQS] __read_mostly;
119
120static struct irq_desc irq_desc_legacy[16] __cacheline_aligned_in_smp = {
121 [0 ... 15] = {
122 .irq = -1,
123 .status = IRQ_DISABLED,
124 .chip = &no_irq_chip,
125 .handle_irq = handle_bad_irq,
126 .depth = 1,
127 .lock = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
128#ifdef CONFIG_SMP
129 .affinity = CPU_MASK_ALL
130#endif
131 }
132};
133
134/* FIXME: use bootmem alloc ...*/
135static unsigned int kstat_irqs_legacy[16][NR_CPUS];
136
137void __init early_irq_init(void)
138{
139 struct irq_desc *desc;
140 int legacy_count;
141 int i;
142
143 desc = irq_desc_legacy;
144 legacy_count = ARRAY_SIZE(irq_desc_legacy);
145
146 for (i = 0; i < legacy_count; i++) {
147 desc[i].irq = i;
148 desc[i].kstat_irqs = kstat_irqs_legacy[i];
149
150 irq_desc_ptrs[i] = desc + i;
151 }
152
153 for (i = legacy_count; i < NR_IRQS; i++)
154 irq_desc_ptrs[i] = NULL;
155
156 arch_early_irq_init();
157}
158
159struct irq_desc *irq_to_desc(unsigned int irq)
160{
161 return (irq < NR_IRQS) ? irq_desc_ptrs[irq] : NULL;
162}
163
164struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
165{
166 struct irq_desc *desc;
167 unsigned long flags;
168 int node;
169
170 if (irq >= NR_IRQS) {
171 printk(KERN_WARNING "irq >= NR_IRQS in irq_to_desc_alloc: %d %d\n",
172 irq, NR_IRQS);
173 WARN_ON(1);
174 return NULL;
175 }
176
177 desc = irq_desc_ptrs[irq];
178 if (desc)
179 return desc;
180
181 spin_lock_irqsave(&sparse_irq_lock, flags);
182
183 /* We have to check it to avoid races with another CPU */
184 desc = irq_desc_ptrs[irq];
185 if (desc)
186 goto out_unlock;
187
188 node = cpu_to_node(cpu);
189 desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
190 printk(KERN_DEBUG " alloc irq_desc for %d on cpu %d node %d\n",
191 irq, cpu, node);
192 if (!desc) {
193 printk(KERN_ERR "can not alloc irq_desc\n");
194 BUG_ON(1);
195 }
196 init_one_irq_desc(irq, desc, cpu);
197
198 irq_desc_ptrs[irq] = desc;
199
200out_unlock:
201 spin_unlock_irqrestore(&sparse_irq_lock, flags);
202
203 return desc;
204}
205
206#else
207
52struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { 208struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
53 [0 ... NR_IRQS-1] = { 209 [0 ... NR_IRQS-1] = {
54 .status = IRQ_DISABLED, 210 .status = IRQ_DISABLED,
@@ -62,6 +218,8 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
62 } 218 }
63}; 219};
64 220
221#endif
222
65/* 223/*
66 * What should we do if we get a hw irq event on an illegal vector? 224 * What should we do if we get a hw irq event on an illegal vector?
67 * Each architecture has to answer this themself. 225 * Each architecture has to answer this themself.
@@ -261,17 +419,28 @@ out:
261 419
262 420
263#ifdef CONFIG_TRACE_IRQFLAGS 421#ifdef CONFIG_TRACE_IRQFLAGS
264/*
265 * lockdep: we want to handle all irq_desc locks as a single lock-class:
266 */
267static struct lock_class_key irq_desc_lock_class;
268
269void early_init_irq_lock_class(void) 422void early_init_irq_lock_class(void)
270{ 423{
424#ifndef CONFIG_SPARSE_IRQ
271 struct irq_desc *desc; 425 struct irq_desc *desc;
272 int i; 426 int i;
273 427
274 for_each_irq_desc(i, desc) 428 for_each_irq_desc(i, desc) {
429 if (!desc)
430 continue;
431
275 lockdep_set_class(&desc->lock, &irq_desc_lock_class); 432 lockdep_set_class(&desc->lock, &irq_desc_lock_class);
433 }
434#endif
435}
436#endif
437
438#ifdef CONFIG_SPARSE_IRQ
439unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
440{
441 struct irq_desc *desc = irq_to_desc(irq);
442 return desc->kstat_irqs[cpu];
276} 443}
277#endif 444#endif
445EXPORT_SYMBOL(kstat_irqs_cpu);
446
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index d257e7d6a8a4..f6b3440f05bc 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -243,7 +243,11 @@ void init_irq_proc(void)
243 /* 243 /*
244 * Create entries for all existing IRQs. 244 * Create entries for all existing IRQs.
245 */ 245 */
246 for_each_irq_desc(irq, desc) 246 for_each_irq_desc(irq, desc) {
247 if (!desc)
248 continue;
249
247 register_irq_proc(irq, desc); 250 register_irq_proc(irq, desc);
251 }
248} 252}
249 253
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index dd364c11e56e..3738107531fd 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -91,6 +91,9 @@ static int misrouted_irq(int irq)
91 int i, ok = 0; 91 int i, ok = 0;
92 92
93 for_each_irq_desc(i, desc) { 93 for_each_irq_desc(i, desc) {
94 if (!desc)
95 continue;
96
94 if (!i) 97 if (!i)
95 continue; 98 continue;
96 99
@@ -112,6 +115,8 @@ static void poll_spurious_irqs(unsigned long dummy)
112 for_each_irq_desc(i, desc) { 115 for_each_irq_desc(i, desc) {
113 unsigned int status; 116 unsigned int status;
114 117
118 if (!desc)
119 continue;
115 if (!i) 120 if (!i)
116 continue; 121 continue;
117 122