aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2015-07-14 16:03:57 -0400
committerThomas Gleixner <tglx@linutronix.de>2015-07-15 04:39:17 -0400
commitce0d3c0a6fb1422101498ef378c0851dabbbf67f (patch)
treefbeaaa029b5308bf0bf04dc84615a135620dfedb
parent20483d04ae6f373858f3ca28cd7e26b66106d937 (diff)
genirq: Revert sparse irq locking around __cpu_up() and move it to x86 for now
Boris reported that the sparse_irq protection around __cpu_up() in the generic code causes a regression on Xen. Xen allocates interrupts and some more in the xen_cpu_up() function, so it deadlocks on the sparse_irq_lock. There is no simple fix for this and we really should have the protection for all architectures, but for now the only solution is to move it to x86 where actual wreckage due to the lack of protection has been observed. Reported-and-tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Fixes: a89941816726 'hotplug: Prevent alloc/free of irq descriptors during cpu up/down' Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: xiao jin <jin.xiao@intel.com> Cc: Joerg Roedel <jroedel@suse.de> Cc: Borislav Petkov <bp@suse.de> Cc: Yanmin Zhang <yanmin_zhang@linux.intel.com> Cc: xen-devel <xen-devel@lists.xenproject.org>
-rw-r--r--arch/x86/kernel/smpboot.c11
-rw-r--r--kernel/cpu.c9
2 files changed, 11 insertions, 9 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index d3010aa79daf..b1f3ed9c7a9e 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -992,8 +992,17 @@ int native_cpu_up(unsigned int cpu, struct task_struct *tidle)
992 992
993 common_cpu_up(cpu, tidle); 993 common_cpu_up(cpu, tidle);
994 994
995 /*
996 * We have to walk the irq descriptors to setup the vector
997 * space for the cpu which comes online. Prevent irq
998 * alloc/free across the bringup.
999 */
1000 irq_lock_sparse();
1001
995 err = do_boot_cpu(apicid, cpu, tidle); 1002 err = do_boot_cpu(apicid, cpu, tidle);
1003
996 if (err) { 1004 if (err) {
1005 irq_unlock_sparse();
997 pr_err("do_boot_cpu failed(%d) to wakeup CPU#%u\n", err, cpu); 1006 pr_err("do_boot_cpu failed(%d) to wakeup CPU#%u\n", err, cpu);
998 return -EIO; 1007 return -EIO;
999 } 1008 }
@@ -1011,6 +1020,8 @@ int native_cpu_up(unsigned int cpu, struct task_struct *tidle)
1011 touch_nmi_watchdog(); 1020 touch_nmi_watchdog();
1012 } 1021 }
1013 1022
1023 irq_unlock_sparse();
1024
1014 return 0; 1025 return 0;
1015} 1026}
1016 1027
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 6a374544d495..5644ec5582b9 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -527,18 +527,9 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen)
527 goto out_notify; 527 goto out_notify;
528 } 528 }
529 529
530 /*
531 * Some architectures have to walk the irq descriptors to
532 * setup the vector space for the cpu which comes online.
533 * Prevent irq alloc/free across the bringup.
534 */
535 irq_lock_sparse();
536
537 /* Arch-specific enabling code. */ 530 /* Arch-specific enabling code. */
538 ret = __cpu_up(cpu, idle); 531 ret = __cpu_up(cpu, idle);
539 532
540 irq_unlock_sparse();
541
542 if (ret != 0) 533 if (ret != 0)
543 goto out_notify; 534 goto out_notify;
544 BUG_ON(!cpu_online(cpu)); 535 BUG_ON(!cpu_online(cpu));