Can you checkout -current, and try this diff: It has one additional check for cpu_setperf being NULL, near the top of setperf_auto()
Index: dev/acpi/acpiac.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpiac.c,v retrieving revision 1.33 diff -u -p -u -r1.33 acpiac.c --- dev/acpi/acpiac.c 10 Jun 2020 22:26:40 -0000 1.33 +++ dev/acpi/acpiac.c 24 Oct 2021 04:00:38 -0000 @@ -70,6 +70,7 @@ void acpiac_attach(struct device *parent, struct device *self, void *aux) { struct acpiac_softc *sc = (struct acpiac_softc *)self; + extern int hw_power; struct acpi_attach_args *aa = aux; sc->sc_acpi = (struct acpi_softc *)parent; @@ -83,6 +84,7 @@ acpiac_attach(struct device *parent, str printf("offline\n"); else printf("in unknown state\n"); + hw_power = (sc->sc_ac_stat == PSR_ONLINE); strlcpy(sc->sc_sensdev.xname, DEVNAME(sc), sizeof(sc->sc_sensdev.xname)); @@ -140,6 +142,7 @@ int acpiac_notify(struct aml_node *node, int notify_type, void *arg) { struct acpiac_softc *sc = arg; + extern int hw_power; dnprintf(10, "acpiac_notify: %.2x %s\n", notify_type, DEVNAME(sc)); @@ -159,5 +162,6 @@ acpiac_notify(struct aml_node *node, int dnprintf(10, "A/C status: %d\n", sc->sc_ac_stat); break; } + hw_power = (sc->sc_ac_stat == PSR_ONLINE); return (0); } Index: kern/kern_sysctl.c =================================================================== RCS file: /cvs/src/sys/kern/kern_sysctl.c,v retrieving revision 1.395 diff -u -p -u -r1.395 kern_sysctl.c --- kern/kern_sysctl.c 24 Oct 2021 00:02:25 -0000 1.395 +++ kern/kern_sysctl.c 26 Oct 2021 04:41:33 -0000 @@ -654,6 +654,7 @@ kern_sysctl(int *name, u_int namelen, vo */ char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver; int allowpowerdown = 1; +int hw_power = 1; /* morally const values reported by sysctl_bounded_arr */ static int byte_order = BYTE_ORDER; @@ -665,6 +666,7 @@ const struct sysctl_bounded_args hw_vars {HW_BYTEORDER, &byte_order, SYSCTL_INT_READONLY}, {HW_PAGESIZE, &page_size, SYSCTL_INT_READONLY}, {HW_DISKCOUNT, &disk_count, SYSCTL_INT_READONLY}, + {HW_POWER, &hw_power, SYSCTL_INT_READONLY}, }; int Index: kern/sched_bsd.c =================================================================== RCS file: /cvs/src/sys/kern/sched_bsd.c,v retrieving revision 1.69 diff -u -p -u -r1.69 sched_bsd.c --- kern/sched_bsd.c 9 Sep 2021 18:41:39 -0000 1.69 +++ kern/sched_bsd.c 26 Oct 2021 05:13:22 -0000 @@ -65,23 +65,6 @@ struct __mp_lock sched_lock; void schedcpu(void *); uint32_t decay_aftersleep(uint32_t, uint32_t); -void -scheduler_start(void) -{ - static struct timeout schedcpu_to; - - /* - * We avoid polluting the global namespace by keeping the scheduler - * timeouts static in this function. - * We setup the timeout here and kick schedcpu once to make it do - * its job. - */ - timeout_set(&schedcpu_to, schedcpu, &schedcpu_to); - - rrticks_init = hz / 10; - schedcpu(&schedcpu_to); -} - /* * Force switch among equal priority processes every 100ms. */ @@ -532,7 +515,7 @@ void (*cpu_setperf)(int); #define PERFPOL_AUTO 1 #define PERFPOL_HIGH 2 int perflevel = 100; -int perfpolicy = PERFPOL_MANUAL; +int perfpolicy = PERFPOL_AUTO; #ifndef SMALL_KERNEL /* @@ -542,22 +525,30 @@ int perfpolicy = PERFPOL_MANUAL; void setperf_auto(void *); struct timeout setperf_to = TIMEOUT_INITIALIZER(setperf_auto, NULL); +extern int hw_power; void setperf_auto(void *v) { static uint64_t *idleticks, *totalticks; static int downbeats; - - int i, j; - int speedup; + int i, j = 0; + int speedup = 0; CPU_INFO_ITERATOR cii; struct cpu_info *ci; - uint64_t idle, total, allidle, alltotal; + uint64_t idle, total, allidle = 0, alltotal = 0; if (perfpolicy != PERFPOL_AUTO) return; + if (cpu_setperf == NULL) + return; + + if (hw_power) { + speedup = 1; + goto faster; + } + if (!idleticks) if (!(idleticks = mallocarray(ncpusfound, sizeof(*idleticks), M_DEVBUF, M_NOWAIT | M_ZERO))) @@ -569,10 +560,6 @@ setperf_auto(void *v) sizeof(*idleticks) * ncpusfound); return; } - - alltotal = allidle = 0; - j = 0; - speedup = 0; CPU_INFO_FOREACH(cii, ci) { if (!cpu_is_online(ci)) continue; @@ -596,6 +583,7 @@ setperf_auto(void *v) downbeats = 5; if (speedup && perflevel != 100) { +faster: perflevel = 100; cpu_setperf(perflevel); } else if (!speedup && perflevel != 0 && --downbeats <= 0) { @@ -676,3 +664,26 @@ sysctl_hwperfpolicy(void *oldp, size_t * return 0; } #endif + +void +scheduler_start(void) +{ + static struct timeout schedcpu_to; + + /* + * We avoid polluting the global namespace by keeping the scheduler + * timeouts static in this function. + * We setup the timeout here and kick schedcpu once to make it do + * its job. + */ + timeout_set(&schedcpu_to, schedcpu, &schedcpu_to); + + rrticks_init = hz / 10; + schedcpu(&schedcpu_to); + +#ifndef SMALL_KERNEL + if (perfpolicy == PERFPOL_AUTO) + timeout_add_msec(&setperf_to, 200); +#endif +} + Index: sys/sysctl.h =================================================================== RCS file: /cvs/src/sys/sys/sysctl.h,v retrieving revision 1.218 diff -u -p -u -r1.218 sysctl.h --- sys/sysctl.h 17 May 2021 17:54:31 -0000 1.218 +++ sys/sysctl.h 23 Oct 2021 23:53:06 -0000 @@ -928,7 +928,8 @@ struct kinfo_file { #define HW_PERFPOLICY 23 /* set performance policy */ #define HW_SMT 24 /* int: enable SMT/HT/CMT */ #define HW_NCPUONLINE 25 /* int: number of cpus being used */ -#define HW_MAXID 26 /* number of valid hw ids */ +#define HW_POWER 26 /* int: machine has wall-power */ +#define HW_MAXID 27 /* number of valid hw ids */ #define CTL_HW_NAMES { \ { 0, 0 }, \ @@ -957,6 +958,7 @@ struct kinfo_file { { "perfpolicy", CTLTYPE_STRING }, \ { "smt", CTLTYPE_INT }, \ { "ncpuonline", CTLTYPE_INT }, \ + { "power", CTLTYPE_INT }, \ } /*