git: 0d745e16f2d7 - stable/12 - Move time math out of disabled interrupts sections.

Alexander Motin mav at FreeBSD.org
Wed Apr 7 00:34:18 UTC 2021


The branch stable/12 has been updated by mav:

URL: https://cgit.FreeBSD.org/src/commit/?id=0d745e16f2d79951a35d822a26c7145de804cc26

commit 0d745e16f2d79951a35d822a26c7145de804cc26
Author:     Alexander Motin <mav at FreeBSD.org>
AuthorDate: 2021-03-10 18:39:15 +0000
Commit:     Alexander Motin <mav at FreeBSD.org>
CommitDate: 2021-04-07 00:34:12 +0000

    Move time math out of disabled interrupts sections.
    
    We don't need the result before next sleep time, so no reason to
    additionally increase interrupt latency.
    
    While there, remove extra PM ticks to microseconds conversion, making
    C2/C3 sleep times look 4 times smaller than really.  The conversion
    is already done by AcpiGetTimerDuration().  Now I see reported sleep
    times up to 0.5s, just as expected for planned 2 wakeups per second.
    
    MFC after:      1 month
    
    (cherry picked from commit 2cee045b4d62568d065b838a6cf129fed2424709)
---
 sys/dev/acpica/acpi_cpu.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
index 44662741a040..ca4162e5faa5 100644
--- a/sys/dev/acpica/acpi_cpu.c
+++ b/sys/dev/acpica/acpi_cpu.c
@@ -114,8 +114,6 @@ struct acpi_cpu_device {
     (bus_space_write_ ## width(rman_get_bustag((reg)), 			\
 		       rman_get_bushandle((reg)), 0, (val)))
 
-#define PM_USEC(x)	 ((x) >> 2)	/* ~4 clocks per usec (3.57955 Mhz) */
-
 #define ACPI_NOTIFY_CX_STATES	0x81	/* _CST changed. */
 
 #define CPU_QUIRK_NO_C3		(1<<0)	/* C3-type states are not usable. */
@@ -1109,7 +1107,7 @@ acpi_cpu_idle(sbintime_t sbt)
 {
     struct	acpi_cpu_softc *sc;
     struct	acpi_cx *cx_next;
-    uint64_t	cputicks;
+    uint64_t	start_ticks, end_ticks;
     uint32_t	start_time, end_time;
     ACPI_STATUS	status;
     int		bm_active, cx_next_idx, i, us;
@@ -1178,7 +1176,7 @@ acpi_cpu_idle(sbintime_t sbt)
      * we are called inside critical section, delaying context switch.
      */
     if (cx_next->type == ACPI_STATE_C1) {
-	cputicks = cpu_ticks();
+	start_ticks = cpu_ticks();
 	if (cx_next->p_lvlx != NULL) {
 	    /* C1 I/O then Halt */
 	    CPU_GET_REG(cx_next->p_lvlx, 1);
@@ -1187,12 +1185,13 @@ acpi_cpu_idle(sbintime_t sbt)
 	    acpi_cpu_idle_mwait(cx_next->mwait_hint);
 	else
 	    acpi_cpu_c1();
-	end_time = ((cpu_ticks() - cputicks) << 20) / cpu_tickrate();
-	if (curthread->td_critnest == 0)
-		end_time = min(end_time, 500000 / hz);
+	end_ticks = cpu_ticks();
 	/* acpi_cpu_c1() returns with interrupts enabled. */
 	if (cx_next->do_mwait)
 	    ACPI_ENABLE_IRQS();
+	end_time = ((end_ticks - start_ticks) << 20) / cpu_tickrate();
+	if (!cx_next->do_mwait && curthread->td_critnest == 0)
+		end_time = min(end_time, 500000 / hz);
 	sc->cpu_prev_sleep = (sc->cpu_prev_sleep * 3 + end_time) / 4;
 	return;
     }
@@ -1217,10 +1216,10 @@ acpi_cpu_idle(sbintime_t sbt)
      */
     if (cx_next->type == ACPI_STATE_C3) {
 	AcpiGetTimer(&start_time);
-	cputicks = 0;
+	start_ticks = 0;
     } else {
 	start_time = 0;
-	cputicks = cpu_ticks();
+	start_ticks = cpu_ticks();
     }
     if (cx_next->do_mwait) {
 	acpi_cpu_idle_mwait(cx_next->mwait_hint);
@@ -1235,11 +1234,10 @@ acpi_cpu_idle(sbintime_t sbt)
 	AcpiGetTimer(&end_time);
     }
 
-    if (cx_next->type == ACPI_STATE_C3) {
+    if (cx_next->type == ACPI_STATE_C3)
 	AcpiGetTimer(&end_time);
-	AcpiGetTimerDuration(start_time, end_time, &end_time);
-    } else
-	end_time = ((cpu_ticks() - cputicks) << 20) / cpu_tickrate();
+    else
+	end_ticks = cpu_ticks();
 
     /* Enable bus master arbitration and disable bus master wakeup. */
     if (cx_next->type == ACPI_STATE_C3 &&
@@ -1249,7 +1247,11 @@ acpi_cpu_idle(sbintime_t sbt)
     }
     ACPI_ENABLE_IRQS();
 
-    sc->cpu_prev_sleep = (sc->cpu_prev_sleep * 3 + PM_USEC(end_time)) / 4;
+    if (cx_next->type == ACPI_STATE_C3)
+	AcpiGetTimerDuration(start_time, end_time, &end_time);
+    else
+	end_time = ((end_ticks - start_ticks) << 20) / cpu_tickrate();
+    sc->cpu_prev_sleep = (sc->cpu_prev_sleep * 3 + end_time) / 4;
 }
 #endif
 


More information about the dev-commits-src-all mailing list