aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/irq.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2015-08-05 17:55:52 -0400
committerThomas Gleixner <tglx@linutronix.de>2015-08-05 18:00:32 -0400
commitb7edaca4e825fd5d7a6ddce3548cc1f7a7337cf8 (patch)
tree221d6c5be36fa3b2133200ebc3e520d4382dca8f /arch/x86/kernel/irq.c
parentc948c26048ecb1023d2e68222c736f7da41da498 (diff)
parentcbfe8fa6cd672011c755c3cd85c9ffd4e2d10a6f (diff)
Merge branch 'linus' into x86/apic
Pull in upstream changes to avoid conflicts
Diffstat (limited to 'arch/x86/kernel/irq.c')
-rw-r--r--arch/x86/kernel/irq.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 7ed9cba27637..bc28496fd196 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -347,15 +347,23 @@ int check_irq_vectors_for_cpu_disable(void)
347 if (!desc) 347 if (!desc)
348 continue; 348 continue;
349 349
350 /*
351 * Protect against concurrent action removal,
352 * affinity changes etc.
353 */
354 raw_spin_lock(&desc->lock);
350 data = irq_desc_get_irq_data(desc); 355 data = irq_desc_get_irq_data(desc);
351 cpumask_copy(&affinity_new, 356 cpumask_copy(&affinity_new,
352 irq_data_get_affinity_mask(data)); 357 irq_data_get_affinity_mask(data));
353 cpumask_clear_cpu(this_cpu, &affinity_new); 358 cpumask_clear_cpu(this_cpu, &affinity_new);
354 359
355 /* Do not count inactive or per-cpu irqs. */ 360 /* Do not count inactive or per-cpu irqs. */
356 if (!irq_has_action(irq) || irqd_is_per_cpu(data)) 361 if (!irq_has_action(irq) || irqd_is_per_cpu(data)) {
362 raw_spin_unlock(&desc->lock);
357 continue; 363 continue;
364 }
358 365
366 raw_spin_unlock(&desc->lock);
359 /* 367 /*
360 * A single irq may be mapped to multiple 368 * A single irq may be mapped to multiple
361 * cpu's vector_irq[] (for example IOAPIC cluster 369 * cpu's vector_irq[] (for example IOAPIC cluster
@@ -386,6 +394,9 @@ int check_irq_vectors_for_cpu_disable(void)
386 * vector. If the vector is marked in the used vectors 394 * vector. If the vector is marked in the used vectors
387 * bitmap or an irq is assigned to it, we don't count 395 * bitmap or an irq is assigned to it, we don't count
388 * it as available. 396 * it as available.
397 *
398 * As this is an inaccurate snapshot anyway, we can do
399 * this w/o holding vector_lock.
389 */ 400 */
390 for (vector = FIRST_EXTERNAL_VECTOR; 401 for (vector = FIRST_EXTERNAL_VECTOR;
391 vector < first_system_vector; vector++) { 402 vector < first_system_vector; vector++) {
@@ -487,6 +498,11 @@ void fixup_irqs(void)
487 */ 498 */
488 mdelay(1); 499 mdelay(1);
489 500
501 /*
502 * We can walk the vector array of this cpu without holding
503 * vector_lock because the cpu is already marked !online, so
504 * nothing else will touch it.
505 */
490 for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { 506 for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
491 unsigned int irr; 507 unsigned int irr;
492 508
@@ -498,9 +514,9 @@ void fixup_irqs(void)
498 irq = __this_cpu_read(vector_irq[vector]); 514 irq = __this_cpu_read(vector_irq[vector]);
499 515
500 desc = irq_to_desc(irq); 516 desc = irq_to_desc(irq);
517 raw_spin_lock(&desc->lock);
501 data = irq_desc_get_irq_data(desc); 518 data = irq_desc_get_irq_data(desc);
502 chip = irq_data_get_irq_chip(data); 519 chip = irq_data_get_irq_chip(data);
503 raw_spin_lock(&desc->lock);
504 if (chip->irq_retrigger) { 520 if (chip->irq_retrigger) {
505 chip->irq_retrigger(data); 521 chip->irq_retrigger(data);
506 __this_cpu_write(vector_irq[vector], VECTOR_RETRIGGERED); 522 __this_cpu_write(vector_irq[vector], VECTOR_RETRIGGERED);