forked from Minki/linux
Revert f5d6a52f51
("x86/smpboot: Skip delays during SMP initialization similar to Xen")
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:
1a744cb356
("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>
This commit is contained in:
parent
1a744cb356
commit
853b160aaa
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user