From: Kirill A. Korinsky Subject: Re: powersave CPU policy To: Philip Guenther , "Lorenz (xha)" , OpenBSD tech Date: Wed, 15 May 2024 12:20:21 +0100 On Wed, 15 May 2024 11:32:48 +0100, Kirill A. Korinsky wrote: > > Well, I see simpler solution here. CPU has SPCF_HALTED on my case which can > be used to go into long sleep, until such flag is removed. > I mean something like this: diff --git sys/dev/acpi/acpicpu.c sys/dev/acpi/acpicpu.c index 0a5ee1fea7d..29e712a8c12 100644 --- sys/dev/acpi/acpicpu.c +++ sys/dev/acpi/acpicpu.c @@ -1155,6 +1155,7 @@ acpicpu_idle(void) struct acpicpu_softc *sc = (struct acpicpu_softc *)ci->ci_acpicpudev; struct acpi_cstate *best, *cx; unsigned long itime; + int is_halted; if (sc == NULL) { __asm volatile("sti"); @@ -1199,16 +1200,25 @@ acpicpu_idle(void) atomic_inc_long(&cst_stats[best->state]); + /* avoid statisitcs when CPU is halted, and sleep until unidle */ + is_halted = sc->sc_flags & SPCF_HALTED; + itime = tick / 2; switch (best->method) { default: case CST_METH_HALT: - __asm volatile("sti; hlt"); + if (is_halted) + __asm volatile("hlt"); + else + __asm volatile("sti; hlt"); break; case CST_METH_IO_HALT: inb((u_short)best->address); - __asm volatile("sti; hlt"); + if (is_halted) + __asm volatile("hlt"); + else + __asm volatile("sti; hlt"); break; case CST_METH_MWAIT: @@ -1250,7 +1260,8 @@ acpicpu_idle(void) membar_sync(); } - monitor(&ci->ci_mwait, 0, 0); + if (!is_halted) + monitor(&ci->ci_mwait, 0, 0); if ((ci->ci_mwait & MWAIT_IDLING) == MWAIT_IDLING) mwait(0, hints); } @@ -1272,8 +1283,10 @@ acpicpu_idle(void) } - sc->sc_last_itime = itime; - itime >>= 1; - sc->sc_prev_sleep = (sc->sc_prev_sleep + (sc->sc_prev_sleep >> 1) - + itime) >> 1; + if (is_halted) { + sc->sc_last_itime = itime; + itime >>= 1; + sc->sc_prev_sleep = (sc->sc_prev_sleep + (sc->sc_prev_sleep >> 1) + + itime) >> 1; + } } -- wbr, Kirill