diff options
| -rw-r--r-- | arch/x86/include/asm/hw_irq.h | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 20 | ||||
| -rw-r--r-- | arch/x86/kernel/irq.c | 19 | ||||
| -rw-r--r-- | arch/x86/kernel/irqinit.c | 4 |
4 files changed, 28 insertions, 18 deletions
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index cba45d99ac1a..67d69b8e2d20 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h | |||
| @@ -191,6 +191,9 @@ extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void); | |||
| 191 | #define trace_interrupt interrupt | 191 | #define trace_interrupt interrupt |
| 192 | #endif | 192 | #endif |
| 193 | 193 | ||
| 194 | #define VECTOR_UNDEFINED -1 | ||
| 195 | #define VECTOR_RETRIGGERED -2 | ||
| 196 | |||
| 194 | typedef int vector_irq_t[NR_VECTORS]; | 197 | typedef int vector_irq_t[NR_VECTORS]; |
| 195 | DECLARE_PER_CPU(vector_irq_t, vector_irq); | 198 | DECLARE_PER_CPU(vector_irq_t, vector_irq); |
| 196 | extern void setup_vector_irq(int cpu); | 199 | extern void setup_vector_irq(int cpu); |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index e63a5bd2a78f..a43f068ebec1 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -1142,9 +1142,10 @@ next: | |||
| 1142 | if (test_bit(vector, used_vectors)) | 1142 | if (test_bit(vector, used_vectors)) |
| 1143 | goto next; | 1143 | goto next; |
| 1144 | 1144 | ||
| 1145 | for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask) | 1145 | for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask) { |
| 1146 | if (per_cpu(vector_irq, new_cpu)[vector] != -1) | 1146 | if (per_cpu(vector_irq, new_cpu)[vector] > VECTOR_UNDEFINED) |
| 1147 | goto next; | 1147 | goto next; |
| 1148 | } | ||
| 1148 | /* Found one! */ | 1149 | /* Found one! */ |
| 1149 | current_vector = vector; | 1150 | current_vector = vector; |
| 1150 | current_offset = offset; | 1151 | current_offset = offset; |
| @@ -1183,7 +1184,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) | |||
| 1183 | 1184 | ||
| 1184 | vector = cfg->vector; | 1185 | vector = cfg->vector; |
| 1185 | for_each_cpu_and(cpu, cfg->domain, cpu_online_mask) | 1186 | for_each_cpu_and(cpu, cfg->domain, cpu_online_mask) |
| 1186 | per_cpu(vector_irq, cpu)[vector] = -1; | 1187 | per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED; |
| 1187 | 1188 | ||
| 1188 | cfg->vector = 0; | 1189 | cfg->vector = 0; |
| 1189 | cpumask_clear(cfg->domain); | 1190 | cpumask_clear(cfg->domain); |
| @@ -1191,11 +1192,10 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) | |||
| 1191 | if (likely(!cfg->move_in_progress)) | 1192 | if (likely(!cfg->move_in_progress)) |
| 1192 | return; | 1193 | return; |
| 1193 | for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) { | 1194 | for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) { |
| 1194 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; | 1195 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { |
| 1195 | vector++) { | ||
| 1196 | if (per_cpu(vector_irq, cpu)[vector] != irq) | 1196 | if (per_cpu(vector_irq, cpu)[vector] != irq) |
| 1197 | continue; | 1197 | continue; |
| 1198 | per_cpu(vector_irq, cpu)[vector] = -1; | 1198 | per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED; |
| 1199 | break; | 1199 | break; |
| 1200 | } | 1200 | } |
| 1201 | } | 1201 | } |
| @@ -1228,12 +1228,12 @@ void __setup_vector_irq(int cpu) | |||
| 1228 | /* Mark the free vectors */ | 1228 | /* Mark the free vectors */ |
| 1229 | for (vector = 0; vector < NR_VECTORS; ++vector) { | 1229 | for (vector = 0; vector < NR_VECTORS; ++vector) { |
| 1230 | irq = per_cpu(vector_irq, cpu)[vector]; | 1230 | irq = per_cpu(vector_irq, cpu)[vector]; |
| 1231 | if (irq < 0) | 1231 | if (irq <= VECTOR_UNDEFINED) |
| 1232 | continue; | 1232 | continue; |
| 1233 | 1233 | ||
| 1234 | cfg = irq_cfg(irq); | 1234 | cfg = irq_cfg(irq); |
| 1235 | if (!cpumask_test_cpu(cpu, cfg->domain)) | 1235 | if (!cpumask_test_cpu(cpu, cfg->domain)) |
| 1236 | per_cpu(vector_irq, cpu)[vector] = -1; | 1236 | per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED; |
| 1237 | } | 1237 | } |
| 1238 | raw_spin_unlock(&vector_lock); | 1238 | raw_spin_unlock(&vector_lock); |
| 1239 | } | 1239 | } |
| @@ -2202,13 +2202,13 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) | |||
| 2202 | 2202 | ||
| 2203 | me = smp_processor_id(); | 2203 | me = smp_processor_id(); |
| 2204 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { | 2204 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { |
| 2205 | unsigned int irq; | 2205 | int irq; |
| 2206 | unsigned int irr; | 2206 | unsigned int irr; |
| 2207 | struct irq_desc *desc; | 2207 | struct irq_desc *desc; |
| 2208 | struct irq_cfg *cfg; | 2208 | struct irq_cfg *cfg; |
| 2209 | irq = __this_cpu_read(vector_irq[vector]); | 2209 | irq = __this_cpu_read(vector_irq[vector]); |
| 2210 | 2210 | ||
| 2211 | if (irq == -1) | 2211 | if (irq <= VECTOR_UNDEFINED) |
| 2212 | continue; | 2212 | continue; |
| 2213 | 2213 | ||
| 2214 | desc = irq_to_desc(irq); | 2214 | desc = irq_to_desc(irq); |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 22d0687e7fda..884d875c1434 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
| @@ -193,9 +193,13 @@ __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs) | |||
| 193 | if (!handle_irq(irq, regs)) { | 193 | if (!handle_irq(irq, regs)) { |
| 194 | ack_APIC_irq(); | 194 | ack_APIC_irq(); |
| 195 | 195 | ||
| 196 | if (printk_ratelimit()) | 196 | if (irq != VECTOR_RETRIGGERED) { |
| 197 | pr_emerg("%s: %d.%d No irq handler for vector (irq %d)\n", | 197 | pr_emerg_ratelimited("%s: %d.%d No irq handler for vector (irq %d)\n", |
| 198 | __func__, smp_processor_id(), vector, irq); | 198 | __func__, smp_processor_id(), |
| 199 | vector, irq); | ||
| 200 | } else { | ||
| 201 | __this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED); | ||
| 202 | } | ||
| 199 | } | 203 | } |
| 200 | 204 | ||
| 201 | irq_exit(); | 205 | irq_exit(); |
| @@ -344,7 +348,7 @@ void fixup_irqs(void) | |||
| 344 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { | 348 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { |
| 345 | unsigned int irr; | 349 | unsigned int irr; |
| 346 | 350 | ||
| 347 | if (__this_cpu_read(vector_irq[vector]) < 0) | 351 | if (__this_cpu_read(vector_irq[vector]) <= VECTOR_UNDEFINED) |
| 348 | continue; | 352 | continue; |
| 349 | 353 | ||
| 350 | irr = apic_read(APIC_IRR + (vector / 32 * 0x10)); | 354 | irr = apic_read(APIC_IRR + (vector / 32 * 0x10)); |
| @@ -355,11 +359,14 @@ void fixup_irqs(void) | |||
| 355 | data = irq_desc_get_irq_data(desc); | 359 | data = irq_desc_get_irq_data(desc); |
| 356 | chip = irq_data_get_irq_chip(data); | 360 | chip = irq_data_get_irq_chip(data); |
| 357 | raw_spin_lock(&desc->lock); | 361 | raw_spin_lock(&desc->lock); |
| 358 | if (chip->irq_retrigger) | 362 | if (chip->irq_retrigger) { |
| 359 | chip->irq_retrigger(data); | 363 | chip->irq_retrigger(data); |
| 364 | __this_cpu_write(vector_irq[vector], VECTOR_RETRIGGERED); | ||
| 365 | } | ||
| 360 | raw_spin_unlock(&desc->lock); | 366 | raw_spin_unlock(&desc->lock); |
| 361 | } | 367 | } |
| 362 | __this_cpu_write(vector_irq[vector], -1); | 368 | if (__this_cpu_read(vector_irq[vector]) != VECTOR_RETRIGGERED) |
| 369 | __this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED); | ||
| 363 | } | 370 | } |
| 364 | } | 371 | } |
| 365 | #endif | 372 | #endif |
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index a2a1fbc594ff..7f50156542fb 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c | |||
| @@ -52,7 +52,7 @@ static struct irqaction irq2 = { | |||
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { | 54 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { |
| 55 | [0 ... NR_VECTORS - 1] = -1, | 55 | [0 ... NR_VECTORS - 1] = VECTOR_UNDEFINED, |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | int vector_used_by_percpu_irq(unsigned int vector) | 58 | int vector_used_by_percpu_irq(unsigned int vector) |
| @@ -60,7 +60,7 @@ int vector_used_by_percpu_irq(unsigned int vector) | |||
| 60 | int cpu; | 60 | int cpu; |
| 61 | 61 | ||
| 62 | for_each_online_cpu(cpu) { | 62 | for_each_online_cpu(cpu) { |
| 63 | if (per_cpu(vector_irq, cpu)[vector] != -1) | 63 | if (per_cpu(vector_irq, cpu)[vector] > VECTOR_UNDEFINED) |
| 64 | return 1; | 64 | return 1; |
| 65 | } | 65 | } |
| 66 | 66 | ||
