aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 12:16:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 12:16:32 -0400
commit19e00d593e9a273ecbfbe131676ed11c140670ac (patch)
tree35198f6fc524976db5465e9bb57cd26c759b67e0
parent197fe6b0e6843b6859c6a1436ff19e3c444c0502 (diff)
parenteeeda4cd06e828b331b15741a204ff9f5874d28d (diff)
Merge branch 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 bootup updates from Ingo Molnar: "The changes in this cycle were: - Fix rare SMP-boot hang (mostly in virtual environments) - Fix build warning with certain (rare) toolchains" * 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/relocs: Make per_cpu_load_addr static x86/smpboot: Initialize secondary CPU only if master CPU will wait for it
-rw-r--r--arch/x86/kernel/cpu/common.c29
-rw-r--r--arch/x86/kernel/smpboot.c98
-rw-r--r--arch/x86/tools/relocs.c2
-rw-r--r--arch/x86/xen/smp.c2
4 files changed, 51 insertions, 80 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index c649f236e288..d8b1166c7888 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1266,6 +1266,19 @@ static void dbg_restore_debug_regs(void)
1266#define dbg_restore_debug_regs() 1266#define dbg_restore_debug_regs()
1267#endif /* ! CONFIG_KGDB */ 1267#endif /* ! CONFIG_KGDB */
1268 1268
1269static void wait_for_master_cpu(int cpu)
1270{
1271#ifdef CONFIG_SMP
1272 /*
1273 * wait for ACK from master CPU before continuing
1274 * with AP initialization
1275 */
1276 WARN_ON(cpumask_test_and_set_cpu(cpu, cpu_initialized_mask));
1277 while (!cpumask_test_cpu(cpu, cpu_callout_mask))
1278 cpu_relax();
1279#endif
1280}
1281
1269/* 1282/*
1270 * cpu_init() initializes state that is per-CPU. Some data is already 1283 * cpu_init() initializes state that is per-CPU. Some data is already
1271 * initialized (naturally) in the bootstrap process, such as the GDT 1284 * initialized (naturally) in the bootstrap process, such as the GDT
@@ -1281,16 +1294,17 @@ void cpu_init(void)
1281 struct task_struct *me; 1294 struct task_struct *me;
1282 struct tss_struct *t; 1295 struct tss_struct *t;
1283 unsigned long v; 1296 unsigned long v;
1284 int cpu; 1297 int cpu = stack_smp_processor_id();
1285 int i; 1298 int i;
1286 1299
1300 wait_for_master_cpu(cpu);
1301
1287 /* 1302 /*
1288 * Load microcode on this cpu if a valid microcode is available. 1303 * Load microcode on this cpu if a valid microcode is available.
1289 * This is early microcode loading procedure. 1304 * This is early microcode loading procedure.
1290 */ 1305 */
1291 load_ucode_ap(); 1306 load_ucode_ap();
1292 1307
1293 cpu = stack_smp_processor_id();
1294 t = &per_cpu(init_tss, cpu); 1308 t = &per_cpu(init_tss, cpu);
1295 oist = &per_cpu(orig_ist, cpu); 1309 oist = &per_cpu(orig_ist, cpu);
1296 1310
@@ -1302,9 +1316,6 @@ void cpu_init(void)
1302 1316
1303 me = current; 1317 me = current;
1304 1318
1305 if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask))
1306 panic("CPU#%d already initialized!\n", cpu);
1307
1308 pr_debug("Initializing CPU#%d\n", cpu); 1319 pr_debug("Initializing CPU#%d\n", cpu);
1309 1320
1310 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); 1321 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
@@ -1381,13 +1392,9 @@ void cpu_init(void)
1381 struct tss_struct *t = &per_cpu(init_tss, cpu); 1392 struct tss_struct *t = &per_cpu(init_tss, cpu);
1382 struct thread_struct *thread = &curr->thread; 1393 struct thread_struct *thread = &curr->thread;
1383 1394
1384 show_ucode_info_early(); 1395 wait_for_master_cpu(cpu);
1385 1396
1386 if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) { 1397 show_ucode_info_early();
1387 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
1388 for (;;)
1389 local_irq_enable();
1390 }
1391 1398
1392 printk(KERN_INFO "Initializing CPU#%d\n", cpu); 1399 printk(KERN_INFO "Initializing CPU#%d\n", cpu);
1393 1400
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 9b1c0f8f68e6..1c3443d98105 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -111,7 +111,6 @@ atomic_t init_deasserted;
111static void smp_callin(void) 111static void smp_callin(void)
112{ 112{
113 int cpuid, phys_id; 113 int cpuid, phys_id;
114 unsigned long timeout;
115 114
116 /* 115 /*
117 * If waken up by an INIT in an 82489DX configuration 116 * If waken up by an INIT in an 82489DX configuration
@@ -130,37 +129,6 @@ static void smp_callin(void)
130 * (This works even if the APIC is not enabled.) 129 * (This works even if the APIC is not enabled.)
131 */ 130 */
132 phys_id = read_apic_id(); 131 phys_id = read_apic_id();
133 if (cpumask_test_cpu(cpuid, cpu_callin_mask)) {
134 panic("%s: phys CPU#%d, CPU#%d already present??\n", __func__,
135 phys_id, cpuid);
136 }
137 pr_debug("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpuid, phys_id);
138
139 /*
140 * STARTUP IPIs are fragile beasts as they might sometimes
141 * trigger some glue motherboard logic. Complete APIC bus
142 * silence for 1 second, this overestimates the time the
143 * boot CPU is spending to send the up to 2 STARTUP IPIs
144 * by a factor of two. This should be enough.
145 */
146
147 /*
148 * Waiting 2s total for startup (udelay is not yet working)
149 */
150 timeout = jiffies + 2*HZ;
151 while (time_before(jiffies, timeout)) {
152 /*
153 * Has the boot CPU finished it's STARTUP sequence?
154 */
155 if (cpumask_test_cpu(cpuid, cpu_callout_mask))
156 break;
157 cpu_relax();
158 }
159
160 if (!time_before(jiffies, timeout)) {
161 panic("%s: CPU%d started up but did not get a callout!\n",
162 __func__, cpuid);
163 }
164 132
165 /* 133 /*
166 * the boot CPU has finished the init stage and is spinning 134 * the boot CPU has finished the init stage and is spinning
@@ -790,8 +758,8 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
790 unsigned long start_ip = real_mode_header->trampoline_start; 758 unsigned long start_ip = real_mode_header->trampoline_start;
791 759
792 unsigned long boot_error = 0; 760 unsigned long boot_error = 0;
793 int timeout;
794 int cpu0_nmi_registered = 0; 761 int cpu0_nmi_registered = 0;
762 unsigned long timeout;
795 763
796 /* Just in case we booted with a single CPU. */ 764 /* Just in case we booted with a single CPU. */
797 alternatives_enable_smp(); 765 alternatives_enable_smp();
@@ -839,6 +807,15 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
839 } 807 }
840 808
841 /* 809 /*
810 * AP might wait on cpu_callout_mask in cpu_init() with
811 * cpu_initialized_mask set if previous attempt to online
812 * it timed-out. Clear cpu_initialized_mask so that after
813 * INIT/SIPI it could start with a clean state.
814 */
815 cpumask_clear_cpu(cpu, cpu_initialized_mask);
816 smp_mb();
817
818 /*
842 * Wake up a CPU in difference cases: 819 * Wake up a CPU in difference cases:
843 * - Use the method in the APIC driver if it's defined 820 * - Use the method in the APIC driver if it's defined
844 * Otherwise, 821 * Otherwise,
@@ -852,53 +829,38 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
852 829
853 if (!boot_error) { 830 if (!boot_error) {
854 /* 831 /*
855 * allow APs to start initializing. 832 * Wait 10s total for a response from AP
856 */ 833 */
857 pr_debug("Before Callout %d\n", cpu); 834 boot_error = -1;
858 cpumask_set_cpu(cpu, cpu_callout_mask); 835 timeout = jiffies + 10*HZ;
859 pr_debug("After Callout %d\n", cpu); 836 while (time_before(jiffies, timeout)) {
837 if (cpumask_test_cpu(cpu, cpu_initialized_mask)) {
838 /*
839 * Tell AP to proceed with initialization
840 */
841 cpumask_set_cpu(cpu, cpu_callout_mask);
842 boot_error = 0;
843 break;
844 }
845 udelay(100);
846 schedule();
847 }
848 }
860 849
850 if (!boot_error) {
861 /* 851 /*
862 * Wait 5s total for a response 852 * Wait till AP completes initial initialization
863 */ 853 */
864 for (timeout = 0; timeout < 50000; timeout++) { 854 while (!cpumask_test_cpu(cpu, cpu_callin_mask)) {
865 if (cpumask_test_cpu(cpu, cpu_callin_mask))
866 break; /* It has booted */
867 udelay(100);
868 /* 855 /*
869 * Allow other tasks to run while we wait for the 856 * Allow other tasks to run while we wait for the
870 * AP to come online. This also gives a chance 857 * AP to come online. This also gives a chance
871 * for the MTRR work(triggered by the AP coming online) 858 * for the MTRR work(triggered by the AP coming online)
872 * to be completed in the stop machine context. 859 * to be completed in the stop machine context.
873 */ 860 */
861 udelay(100);
874 schedule(); 862 schedule();
875 } 863 }
876
877 if (cpumask_test_cpu(cpu, cpu_callin_mask)) {
878 print_cpu_msr(&cpu_data(cpu));
879 pr_debug("CPU%d: has booted.\n", cpu);
880 } else {
881 boot_error = 1;
882 if (*trampoline_status == 0xA5A5A5A5)
883 /* trampoline started but...? */
884 pr_err("CPU%d: Stuck ??\n", cpu);
885 else
886 /* trampoline code not run */
887 pr_err("CPU%d: Not responding\n", cpu);
888 if (apic->inquire_remote_apic)
889 apic->inquire_remote_apic(apicid);
890 }
891 }
892
893 if (boot_error) {
894 /* Try to put things back the way they were before ... */
895 numa_remove_cpu(cpu); /* was set by numa_add_cpu */
896
897 /* was set by do_boot_cpu() */
898 cpumask_clear_cpu(cpu, cpu_callout_mask);
899
900 /* was set by cpu_init() */
901 cpumask_clear_cpu(cpu, cpu_initialized_mask);
902 } 864 }
903 865
904 /* mark "stuck" area as not stuck */ 866 /* mark "stuck" area as not stuck */
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index bbb1d2259ecf..a5efb21d5228 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -695,7 +695,7 @@ static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
695 * 695 *
696 */ 696 */
697static int per_cpu_shndx = -1; 697static int per_cpu_shndx = -1;
698Elf_Addr per_cpu_load_addr; 698static Elf_Addr per_cpu_load_addr;
699 699
700static void percpu_init(void) 700static void percpu_init(void)
701{ 701{
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index c670d7518cf4..8650cdb53209 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -365,6 +365,8 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
365 struct desc_struct *gdt; 365 struct desc_struct *gdt;
366 unsigned long gdt_mfn; 366 unsigned long gdt_mfn;
367 367
368 /* used to tell cpu_init() that it can proceed with initialization */
369 cpumask_set_cpu(cpu, cpu_callout_mask);
368 if (cpumask_test_and_set_cpu(cpu, xen_cpu_initialized_map)) 370 if (cpumask_test_and_set_cpu(cpu, xen_cpu_initialized_map))
369 return 0; 371 return 0;
370 372