aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2021-03-10 18:39:15 +0000
committerAlexander Motin <mav@FreeBSD.org>2021-04-07 00:34:12 +0000
commit0d745e16f2d79951a35d822a26c7145de804cc26 (patch)
treea4b9ab510b26f7cfd49e2ec0acbf6eab79c4f701
parent40074783d8189c1f278d4fe5c373e45a85168534 (diff)
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)
-rw-r--r--sys/dev/acpica/acpi_cpu.c30
1 files 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