aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-08 13:09:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-08 13:09:49 -0400
commitbb077d600689dbf9305758efed1e16775db1c84c (patch)
tree266abae1925d2c232c42fc0e36628fb8f5940352
parentc593e8978722f7f4a12932733cfeed6c0c74fbaa (diff)
Revert "x86/smpboot: Initialize secondary CPU only if master CPU will wait for it"
This reverts commit 3e1a878b7ccdb31da6d9d2b855c72ad87afeba3f. It came in very late, and already has one reported failure: Sitsofe reports that the current tree fails to boot on his EeePC, and bisected it down to this. Rather than waste time trying to figure out what's wrong, just revert it. Reported-by: Sitsofe Wheeler <sitsofe@gmail.com> Cc: Igor Mammedov <imammedo@redhat.com> Cc: Toshi Kani <toshi.kani@hp.com> Cc: Thomas Gleixner <tglx@linutronix.de> Acked-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/x86/kernel/cpu/common.c27
-rw-r--r--arch/x86/kernel/smpboot.c99
2 files changed, 79 insertions, 47 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index a4bcbacdbe0b..a135239badb7 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1221,17 +1221,6 @@ static void dbg_restore_debug_regs(void)
1221#define dbg_restore_debug_regs() 1221#define dbg_restore_debug_regs()
1222#endif /* ! CONFIG_KGDB */ 1222#endif /* ! CONFIG_KGDB */
1223 1223
1224static void wait_for_master_cpu(int cpu)
1225{
1226 /*
1227 * wait for ACK from master CPU before continuing
1228 * with AP initialization
1229 */
1230 WARN_ON(cpumask_test_and_set_cpu(cpu, cpu_initialized_mask));
1231 while (!cpumask_test_cpu(cpu, cpu_callout_mask))
1232 cpu_relax();
1233}
1234
1235/* 1224/*
1236 * cpu_init() initializes state that is per-CPU. Some data is already 1225 * cpu_init() initializes state that is per-CPU. Some data is already
1237 * initialized (naturally) in the bootstrap process, such as the GDT 1226 * initialized (naturally) in the bootstrap process, such as the GDT
@@ -1247,17 +1236,16 @@ void cpu_init(void)
1247 struct task_struct *me; 1236 struct task_struct *me;
1248 struct tss_struct *t; 1237 struct tss_struct *t;
1249 unsigned long v; 1238 unsigned long v;
1250 int cpu = stack_smp_processor_id(); 1239 int cpu;
1251 int i; 1240 int i;
1252 1241
1253 wait_for_master_cpu(cpu);
1254
1255 /* 1242 /*
1256 * Load microcode on this cpu if a valid microcode is available. 1243 * Load microcode on this cpu if a valid microcode is available.
1257 * This is early microcode loading procedure. 1244 * This is early microcode loading procedure.
1258 */ 1245 */
1259 load_ucode_ap(); 1246 load_ucode_ap();
1260 1247
1248 cpu = stack_smp_processor_id();
1261 t = &per_cpu(init_tss, cpu); 1249 t = &per_cpu(init_tss, cpu);
1262 oist = &per_cpu(orig_ist, cpu); 1250 oist = &per_cpu(orig_ist, cpu);
1263 1251
@@ -1269,6 +1257,9 @@ void cpu_init(void)
1269 1257
1270 me = current; 1258 me = current;
1271 1259
1260 if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask))
1261 panic("CPU#%d already initialized!\n", cpu);
1262
1272 pr_debug("Initializing CPU#%d\n", cpu); 1263 pr_debug("Initializing CPU#%d\n", cpu);
1273 1264
1274 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); 1265 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
@@ -1345,10 +1336,14 @@ void cpu_init(void)
1345 struct tss_struct *t = &per_cpu(init_tss, cpu); 1336 struct tss_struct *t = &per_cpu(init_tss, cpu);
1346 struct thread_struct *thread = &curr->thread; 1337 struct thread_struct *thread = &curr->thread;
1347 1338
1348 wait_for_master_cpu(cpu);
1349
1350 show_ucode_info_early(); 1339 show_ucode_info_early();
1351 1340
1341 if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) {
1342 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
1343 for (;;)
1344 local_irq_enable();
1345 }
1346
1352 printk(KERN_INFO "Initializing CPU#%d\n", cpu); 1347 printk(KERN_INFO "Initializing CPU#%d\n", cpu);
1353 1348
1354 if (cpu_has_vme || cpu_has_tsc || cpu_has_de) 1349 if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index bc52fac39dd3..ae2fd975b782 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -111,6 +111,7 @@ 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;
114 115
115 /* 116 /*
116 * If waken up by an INIT in an 82489DX configuration 117 * If waken up by an INIT in an 82489DX configuration
@@ -129,6 +130,37 @@ static void smp_callin(void)
129 * (This works even if the APIC is not enabled.) 130 * (This works even if the APIC is not enabled.)
130 */ 131 */
131 phys_id = read_apic_id(); 132 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 }
132 164
133 /* 165 /*
134 * the boot CPU has finished the init stage and is spinning 166 * the boot CPU has finished the init stage and is spinning
@@ -718,8 +750,8 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
718 unsigned long start_ip = real_mode_header->trampoline_start; 750 unsigned long start_ip = real_mode_header->trampoline_start;
719 751
720 unsigned long boot_error = 0; 752 unsigned long boot_error = 0;
753 int timeout;
721 int cpu0_nmi_registered = 0; 754 int cpu0_nmi_registered = 0;
722 unsigned long timeout;
723 755
724 /* Just in case we booted with a single CPU. */ 756 /* Just in case we booted with a single CPU. */
725 alternatives_enable_smp(); 757 alternatives_enable_smp();
@@ -767,15 +799,6 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
767 } 799 }
768 800
769 /* 801 /*
770 * AP might wait on cpu_callout_mask in cpu_init() with
771 * cpu_initialized_mask set if previous attempt to online
772 * it timed-out. Clear cpu_initialized_mask so that after
773 * INIT/SIPI it could start with a clean state.
774 */
775 cpumask_clear_cpu(cpu, cpu_initialized_mask);
776 smp_mb();
777
778 /*
779 * Wake up a CPU in difference cases: 802 * Wake up a CPU in difference cases:
780 * - Use the method in the APIC driver if it's defined 803 * - Use the method in the APIC driver if it's defined
781 * Otherwise, 804 * Otherwise,
@@ -787,41 +810,55 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
787 boot_error = wakeup_cpu_via_init_nmi(cpu, start_ip, apicid, 810 boot_error = wakeup_cpu_via_init_nmi(cpu, start_ip, apicid,
788 &cpu0_nmi_registered); 811 &cpu0_nmi_registered);
789 812
790
791 if (!boot_error) { 813 if (!boot_error) {
792 /* 814 /*
793 * Wait 10s total for a response from AP 815 * allow APs to start initializing.
794 */ 816 */
795 boot_error = -1; 817 pr_debug("Before Callout %d\n", cpu);
796 timeout = jiffies + 10*HZ; 818 cpumask_set_cpu(cpu, cpu_callout_mask);
797 while (time_before(jiffies, timeout)) { 819 pr_debug("After Callout %d\n", cpu);
798 if (cpumask_test_cpu(cpu, cpu_initialized_mask)) {
799 /*
800 * Tell AP to proceed with initialization
801 */
802 cpumask_set_cpu(cpu, cpu_callout_mask);
803 boot_error = 0;
804 break;
805 }
806 udelay(100);
807 schedule();
808 }
809 }
810 820
811 if (!boot_error) {
812 /* 821 /*
813 * Wait till AP completes initial initialization 822 * Wait 5s total for a response
814 */ 823 */
815 while (!cpumask_test_cpu(cpu, cpu_callin_mask)) { 824 for (timeout = 0; timeout < 50000; timeout++) {
825 if (cpumask_test_cpu(cpu, cpu_callin_mask))
826 break; /* It has booted */
827 udelay(100);
816 /* 828 /*
817 * Allow other tasks to run while we wait for the 829 * Allow other tasks to run while we wait for the
818 * AP to come online. This also gives a chance 830 * AP to come online. This also gives a chance
819 * for the MTRR work(triggered by the AP coming online) 831 * for the MTRR work(triggered by the AP coming online)
820 * to be completed in the stop machine context. 832 * to be completed in the stop machine context.
821 */ 833 */
822 udelay(100);
823 schedule(); 834 schedule();
824 } 835 }
836
837 if (cpumask_test_cpu(cpu, cpu_callin_mask)) {
838 print_cpu_msr(&cpu_data(cpu));
839 pr_debug("CPU%d: has booted.\n", cpu);
840 } else {
841 boot_error = 1;
842 if (*trampoline_status == 0xA5A5A5A5)
843 /* trampoline started but...? */
844 pr_err("CPU%d: Stuck ??\n", cpu);
845 else
846 /* trampoline code not run */
847 pr_err("CPU%d: Not responding\n", cpu);
848 if (apic->inquire_remote_apic)
849 apic->inquire_remote_apic(apicid);
850 }
851 }
852
853 if (boot_error) {
854 /* Try to put things back the way they were before ... */
855 numa_remove_cpu(cpu); /* was set by numa_add_cpu */
856
857 /* was set by do_boot_cpu() */
858 cpumask_clear_cpu(cpu, cpu_callout_mask);
859
860 /* was set by cpu_init() */
861 cpumask_clear_cpu(cpu, cpu_initialized_mask);
825 } 862 }
826 863
827 /* mark "stuck" area as not stuck */ 864 /* mark "stuck" area as not stuck */