Index | Thread | Search

From:
Kirill A. Korinsky <kirill@korins.ky>
Subject:
Re: powersave CPU policy
To:
Philip Guenther <guenther@gmail.com>, "Lorenz (xha)" <me@xha.li>, OpenBSD tech <tech@openbsd.org>
Date:
Wed, 15 May 2024 12:20:21 +0100

Download raw body.

Thread
On Wed, 15 May 2024 11:32:48 +0100,
Kirill A. Korinsky <kirill@korins.ky> 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