Ensure the idle thread's loop services interrupts in a timely way when
using the ACPI C1/mwait sleep method. Previously, the mwait instruction would return when an interrupt was pending; however, the idle loop did not actually enable interrupts when this occurred. This led to a situation where the idle loop could quickly spin through the C1/mwait sleep method a number of times when an interrupt was pending. (Eventually, the situation corrected itself when something other than an interrupt triggered the idle loop to either enable interrupts or schedule another thread.) Reviewed by: kib, imp (earlier version) Input from: jhb MFC after: 1 week Sponsored by: Netflix
This commit is contained in:
parent
d9cd65922e
commit
df0094cab8
@ -1158,6 +1158,9 @@ acpi_cpu_idle(sbintime_t sbt)
|
||||
end_time = ((cpu_ticks() - cputicks) << 20) / cpu_tickrate();
|
||||
if (curthread->td_critnest == 0)
|
||||
end_time = min(end_time, 500000 / hz);
|
||||
/* acpi_cpu_c1() returns with interrupts enabled. */
|
||||
if (cx_next->do_mwait)
|
||||
ACPI_ENABLE_IRQS();
|
||||
sc->cpu_prev_sleep = (sc->cpu_prev_sleep * 3 + end_time) / 4;
|
||||
return;
|
||||
}
|
||||
|
@ -129,6 +129,14 @@ acpi_cpu_c1(void)
|
||||
__asm __volatile("sti; hlt");
|
||||
}
|
||||
|
||||
/*
|
||||
* Use mwait to pause execution while waiting for an interrupt or
|
||||
* another thread to signal that there is more work.
|
||||
*
|
||||
* NOTE: Interrupts will cause a wakeup; however, this function does
|
||||
* not enable interrupt handling. The caller is responsible to enable
|
||||
* interrupts.
|
||||
*/
|
||||
void
|
||||
acpi_cpu_idle_mwait(uint32_t mwait_hint)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user