diff options
Diffstat (limited to 'sys/dev/acpica/acpi_cpu.c')
| -rw-r--r-- | sys/dev/acpica/acpi_cpu.c | 30 |
1 files changed, 30 insertions, 0 deletions
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) |
