Handle Appolo Lake errata APL31.

If the workaround is activated, always send IPI for wake up, not rely
on the write to the monitor line.  This fixes Appolo Lake machines
early hang in sched_bind(), without requiring user to manually select
idle method.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2018-04-26 18:24:31 +00:00
parent a5f472c579
commit 3f3937b4ae

View File

@ -575,6 +575,11 @@ cpu_idle(int busy)
busy, curcpu);
}
static int cpu_idle_apl31_workaround;
SYSCTL_INT(_machdep, OID_AUTO, idle_apl31, CTLFLAG_RW,
&cpu_idle_apl31_workaround, 0,
"Appolo Lake APL31 MWAIT bug workaround");
int
cpu_idle_wakeup(int cpu)
{
@ -586,7 +591,7 @@ cpu_idle_wakeup(int cpu)
return (0);
case STATE_MWAIT:
atomic_store_int(state, STATE_RUNNING);
return (1);
return (cpu_idle_apl31_workaround ? 0 : 1);
case STATE_RUNNING:
return (1);
default:
@ -689,6 +694,13 @@ cpu_idle_tun(void *unused __unused)
if (TUNABLE_STR_FETCH("machdep.idle", tunvar, sizeof(tunvar)))
cpu_idle_selector(tunvar);
if (cpu_vendor_id == CPU_VENDOR_INTEL && cpu_id == 0x506c9) {
/*
* Appolo Lake errata APL31.
*/
cpu_idle_apl31_workaround = 1;
}
TUNABLE_INT_FETCH("machdep.idle_apl31", &cpu_idle_apl31_workaround);
}
SYSINIT(cpu_idle_tun, SI_SUB_CPU, SI_ORDER_MIDDLE, cpu_idle_tun, NULL);