Change hw.perfpolicy=auto by default, at startup. If the system has AC
authorderaadt <deraadt@openbsd.org>
Sat, 30 Oct 2021 23:24:46 +0000 (23:24 +0000)
committerderaadt <deraadt@openbsd.org>
Sat, 30 Oct 2021 23:24:46 +0000 (23:24 +0000)
power connected (default is yes when no driver differentiates) then default
to 100% performance. On battery, use the existing auto algorithm (which is
admittedly somewhat unrefined).
This change overrides the system/BIOS speed and puts OpenBSD in control.
As this happens very early during boot, besides speedups in all usage usage
patterns, some surprises: unhibernate and sysupgrade times are cut in half.
note: on a few architectures, the setperf fn pointer is changed late, and
thus the auto algorithm stops timeing out.  kettenis and i will look for
a solution.
in snaps for more than a week.
ok kettenis

sys/dev/acpi/acpi.c
sys/dev/acpi/acpiac.c
sys/kern/kern_sysctl.c
sys/kern/sched_bsd.c
sys/sys/sysctl.h

index 1250bc3..8e2ac09 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.399 2021/07/20 00:41:54 mlarkin Exp $ */
+/* $OpenBSD: acpi.c,v 1.400 2021/10/30 23:24:46 deraadt Exp $ */
 /*
  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
  * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -3556,6 +3556,7 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
        case APM_IOC_GETPOWER:
                /* A/C */
                pi->ac_state = APM_AC_UNKNOWN;
+// XXX replace with new power code
                SLIST_FOREACH(ac, &sc->sc_ac, aac_link) {
                        if (ac->aac_softc->sc_ac_stat == PSR_ONLINE)
                                pi->ac_state = APM_AC_ON;
index e2943ea..acd9322 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpiac.c,v 1.33 2020/06/10 22:26:40 jca Exp $ */
+/* $OpenBSD: acpiac.c,v 1.34 2021/10/30 23:24:47 deraadt Exp $ */
 /*
  * Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
  *
@@ -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, struct device *self, void *aux)
                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 notify_type, void *arg)
                dnprintf(10, "A/C status: %d\n", sc->sc_ac_stat);
                break;
        }
+       hw_power = (sc->sc_ac_stat == PSR_ONLINE);
        return (0);
 }
index 320ed09..aacba02 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_sysctl.c,v 1.395 2021/10/24 00:02:25 jsg Exp $   */
+/*     $OpenBSD: kern_sysctl.c,v 1.396 2021/10/30 23:24:48 deraadt Exp $       */
 /*     $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $     */
 
 /*-
@@ -654,6 +654,7 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
  */
 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 956ea24..4929548 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sched_bsd.c,v 1.69 2021/09/09 18:41:39 mpi Exp $      */
+/*     $OpenBSD: sched_bsd.c,v 1.70 2021/10/30 23:24:48 deraadt Exp $  */
 /*     $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
 
 /*-
@@ -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 *oldlenp, void *newp, size_t newlen)
        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 afdc068..bc6d79e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sysctl.h,v 1.218 2021/05/17 17:54:31 claudio Exp $    */
+/*     $OpenBSD: sysctl.h,v 1.219 2021/10/30 23:24:48 deraadt Exp $    */
 /*     $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $  */
 
 /*
@@ -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 }, \
 }
 
 /*