git: 88fe518973b7 - stable/13 - Move time math out of disabled interrupts sections.

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


The branch stable/13 has been updated by mav:

URL: https://cgit.FreeBSD.org/src/commit/?id=88fe518973b7d94736394e379ed50cce01f6cc70

commit 88fe518973b7d94736394e379ed50cce01f6cc70
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:33:59 +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 56182ed743de..3c81d55436ca 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. */
@@ -1107,7 +1105,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;
@@ -1176,7 +1174,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);
@@ -1185,12 +1183,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;
     }
@@ -1215,10 +1214,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);
@@ -1233,11 +1232,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 &&
@@ -1247,7 +1245,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