Revert f5d6a52f5111 ("x86/smpboot: Skip delays during SMP initialization similar...
authorIngo Molnar <mingo@kernel.org>
Wed, 13 May 2015 06:40:49 +0000 (08:40 +0200)
committerIngo Molnar <mingo@kernel.org>
Wed, 13 May 2015 06:40:49 +0000 (08:40 +0200)
Huang Ying reported x86 boot hangs due to this commit.

Turns out that the change, despite its changelog, does more
than just change timeouts: it also changes the way we
assert/deassert INIT via the APIC_DM_INIT IPI, in the x2apic
case it skips the deassert step.

This is historically fragile code and the patch did not
improve it, so revert these changes.

This commit:

  1a744cb356c5 ("x86/smp/boot: Remove 10ms delay from cpu_up() on modern processors")

independently removes the worst of the delays (the 10 msec delay).

The remaining delays can be addressed one by one, combined
with careful testing.

Reported-by: Huang Ying <ying.huang@intel.com>
Cc: Anthony Liguori <aliguori@amazon.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Gang Wei <gang.wei@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jan H. Schönherr <jschoenh@amazon.de>
Cc: Len Brown <len.brown@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tim Deegan <tim@xen.org>
Link: http://lkml.kernel.org/r/1430732554-7294-1-git-send-email-jschoenh@amazon.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/kernel/smpboot.c

index 85bd6aad8c74ba8f541b798e82346642f2dab0d0..b9aaa3930b2fae16e0c01a166e9f6c49b17a2467 100644 (file)
@@ -614,34 +614,22 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
        apic_icr_write(APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT,
                       phys_apicid);
 
-       if (!cpu_has_x2apic) {
-               pr_debug("Waiting for send to finish...\n");
-               send_status = safe_apic_wait_icr_idle();
+       pr_debug("Waiting for send to finish...\n");
+       send_status = safe_apic_wait_icr_idle();
 
-               mdelay(init_udelay);
+       mdelay(init_udelay);
 
-               pr_debug("Deasserting INIT\n");
+       pr_debug("Deasserting INIT\n");
 
-               /* Target chip */
-               /* Send IPI */
-               apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid);
+       /* Target chip */
+       /* Send IPI */
+       apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid);
 
-               pr_debug("Waiting for send to finish...\n");
-               send_status = safe_apic_wait_icr_idle();
+       pr_debug("Waiting for send to finish...\n");
+       send_status = safe_apic_wait_icr_idle();
 
-               mb();
-               atomic_set(&init_deasserted, 1);
-       } else if (tboot_enabled()) {
-               /*
-                * With tboot AP is actually spinning in a mini-guest before
-                * receiving INIT. Upon receiving INIT ipi, AP need time to
-                * VMExit, update VMCS to tracking SIPIs and VMResume.
-                *
-                * While AP is in root mode handling the INIT the CPU will drop
-                * any SIPIs
-                */
-               udelay(10);
-       }
+       mb();
+       atomic_set(&init_deasserted, 1);
 
        /*
         * Should we send STARTUP IPIs ?
@@ -683,22 +671,20 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
                apic_icr_write(APIC_DM_STARTUP | (start_eip >> 12),
                               phys_apicid);
 
-               if (!cpu_has_x2apic) {
-                       /*
-                        * Give the other CPU some time to accept the IPI.
-                        */
-                       udelay(300);
+               /*
+                * Give the other CPU some time to accept the IPI.
+                */
+               udelay(300);
 
-                       pr_debug("Startup point 1\n");
+               pr_debug("Startup point 1\n");
 
-                       pr_debug("Waiting for send to finish...\n");
-                       send_status = safe_apic_wait_icr_idle();
+               pr_debug("Waiting for send to finish...\n");
+               send_status = safe_apic_wait_icr_idle();
 
-                       /*
-                        * Give the other CPU some time to accept the IPI.
-                        */
-                       udelay(200);
-               }
+               /*
+                * Give the other CPU some time to accept the IPI.
+                */
+               udelay(200);
 
                if (maxlvt > 3)         /* Due to the Pentium erratum 3AP.  */
                        apic_write(APIC_ESR, 0);