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>
apic_icr_write(APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT,
phys_apicid);
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();
- 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 ?
/*
* Should we send STARTUP IPIs ?
apic_icr_write(APIC_DM_STARTUP | (start_eip >> 12),
phys_apicid);
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);
if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
apic_write(APIC_ESR, 0);