git: 53880f09fb1b - main - acpi: add counters for cumulative time spent in each sleep state.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 11 Nov 2025 20:45:24 UTC
The branch main has been updated by adrian:
URL: https://cgit.FreeBSD.org/src/commit/?id=53880f09fb1b485cf5c4af2b81081112e0c7cea3
commit 53880f09fb1b485cf5c4af2b81081112e0c7cea3
Author: Adrian Chadd <adrian@FreeBSD.org>
AuthorDate: 2025-11-07 03:45:24 +0000
Commit: Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2025-11-11 20:45:09 +0000
acpi: add counters for cumulative time spent in each sleep state.
Add this so it can be consumed/graphed.
Differential Revision: https://reviews.freebsd.org/D53633
Reviewed by: gallatin, imp
---
sys/dev/acpica/acpi_cpu.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
index f9b9a386c0c5..2cd6c8bd4758 100644
--- a/sys/dev/acpica/acpi_cpu.c
+++ b/sys/dev/acpica/acpi_cpu.c
@@ -92,6 +92,7 @@ struct acpi_cpu_softc {
int cpu_non_c2; /* Index of lowest non-C2 state. */
int cpu_non_c3; /* Index of lowest non-C3 state. */
u_int cpu_cx_stats[MAX_CX_STATES];/* Cx usage history. */
+ uint64_t cpu_cx_duration[MAX_CX_STATES];/* Cx cumulative sleep */
/* Values for sysctl. */
struct sysctl_ctx_list cpu_sysctl_ctx;
struct sysctl_oid *cpu_sysctl_tree;
@@ -185,6 +186,7 @@ static void acpi_cpu_quirks(void);
static void acpi_cpu_quirks_piix4(void);
static int acpi_cpu_usage_sysctl(SYSCTL_HANDLER_ARGS);
static int acpi_cpu_usage_counters_sysctl(SYSCTL_HANDLER_ARGS);
+static int acpi_cpu_duration_counters_sysctl(SYSCTL_HANDLER_ARGS);
static int acpi_cpu_set_cx_lowest(struct acpi_cpu_softc *sc);
static int acpi_cpu_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS);
static int acpi_cpu_global_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS);
@@ -1055,6 +1057,12 @@ acpi_cpu_startup_cx(struct acpi_cpu_softc *sc)
"cx_usage_counters", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
(void *)sc, 0, acpi_cpu_usage_counters_sysctl, "A",
"Cx sleep state counters");
+ SYSCTL_ADD_PROC(&sc->cpu_sysctl_ctx,
+ SYSCTL_CHILDREN(device_get_sysctl_tree(sc->cpu_dev)), OID_AUTO,
+ "cx_duration_counters", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ (void *)sc, 0, acpi_cpu_duration_counters_sysctl, "A",
+ "Cx sleep duration cumulative time");
+
#if defined(__i386__) || defined(__amd64__)
SYSCTL_ADD_PROC(&sc->cpu_sysctl_ctx,
SYSCTL_CHILDREN(device_get_sysctl_tree(sc->cpu_dev)), OID_AUTO,
@@ -1168,6 +1176,7 @@ acpi_cpu_idle(sbintime_t sbt)
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;
+ sc->cpu_cx_duration[cx_next_idx] += end_time;
return;
}
@@ -1224,6 +1233,7 @@ acpi_cpu_idle(sbintime_t sbt)
else
end_time = ((end_ticks - start_ticks) << 20) / cpu_tickrate();
sc->cpu_prev_sleep = (sc->cpu_prev_sleep * 3 + end_time) / 4;
+ sc->cpu_cx_duration[cx_next_idx] += end_time;
}
#endif
@@ -1408,6 +1418,26 @@ acpi_cpu_usage_counters_sysctl(SYSCTL_HANDLER_ARGS)
return (error);
}
+static int
+acpi_cpu_duration_counters_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct acpi_cpu_softc *sc = (struct acpi_cpu_softc *)arg1;
+ struct sbuf sb;
+ char buf[128];
+ int error, i;
+
+ sbuf_new_for_sysctl(&sb, buf, sizeof(buf), req);
+ for (i = 0; i < sc->cpu_cx_count; i++) {
+ if (i > 0)
+ sbuf_putc(&sb, ' ');
+ sbuf_printf(&sb, "%ju", (uintmax_t) sc->cpu_cx_duration[i]);
+ }
+ error = sbuf_finish(&sb);
+ sbuf_delete(&sb);
+ return (error);
+}
+
+
#if defined(__i386__) || defined(__amd64__)
static int
acpi_cpu_method_sysctl(SYSCTL_HANDLER_ARGS)