Add gpuperf patch

This commit is contained in:
h3artbl33d 2024-05-10 13:31:11 +02:00
parent be3c479ad3
commit 9105d96954

330
patches/gpuperf.diff Normal file
View File

@ -0,0 +1,330 @@
This will throttle down your intel graphic card for
better thermal management.
It is bound to CPU performance settings via
hw.setperf sysctl.
Main Test Machine
cpu0: Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz, 2492.32 MHz, 06-2a-07
inteldrm0 at pci0 dev 2 function 0 "Intel HD Graphics 3000" rev 0x09
CPU 800MHz to 2500MHz
GPU 650MHz to 1300MHz
Secondary Test Machine
cpu0: Intel(R) Core(TM) i3-9100 CPU @ 3.60GHz, 3593.36 MHz, 06-9e-0b
inteldrm0 at pci0 dev 2 function 0 "Intel UHD Graphics 630" rev 0x00
CPU autothrottle -> GPU autothrottle (i.e 650MHz - 1300MHz)
CPU perf = 100 -> GPU throttle to max. frequency (i.e. 1300MHz)
CPU perf < 100 -> GPU throttle to base frequency (i.e. 650MHz)
Patch Version 8
Adapt for new DRM code (OpenBSD 6.7-current)
Patch Version 7
Header shuffling
Cleanup
Patch Version 6
Don't include in SMALL_KERNEL
Copyright update
Disable DEBUG output
Patch apply directions have changed
Patch Version 5
Cleanup
Patch Version 4
Switch from percentage to performance groups (LOW, HIGH, AUTO)
Cleanup
Patch Version 3
No longer implements a own sysctl
Patch apply directions have changed
Patch Version 2
Patch apply directions have changed
Includes man page change
Header cleanup
Patch Version 1
Throttle down to base freq on haswell & broadwell
Remove sensors, use debug printf
Patch Version 0
Initial POC
Using sensors framework only for debug
Only implemented for intel graphic
To apply:
cd /usr/src/sys && patch < gpuperf.diff
Rebuild and install a new kernel:
KK=`sysctl -n kern.osversion | cut -d# -f1`
cd /usr/src/sys/arch/`machine`/compile/$KK
make obj
make config
make
make install
Feedback and questions: programmer@netzbasis.de
Index: conf/files
===================================================================
RCS file: /var/cvs/src/sys/conf/files,v
retrieving revision 1.690
diff -u -p -r1.690 files
--- conf/files 6 Jul 2020 04:09:46 -0000 1.690
+++ conf/files 18 Jul 2020 19:43:06 -0000
@@ -717,6 +717,7 @@ file kern/subr_autoconf.c
file kern/subr_disk.c
file kern/subr_evcount.c
file kern/subr_extent.c
+file kern/subr_gpuperf.c !small_kernel
file kern/subr_hibernate.c hibernate
file kern/subr_kubsan.c kubsan
file kern/subr_log.c
Index: dev/pci/drm/i915/i915_drv.c
===================================================================
RCS file: /var/cvs/src/sys/dev/pci/drm/i915/i915_drv.c,v
retrieving revision 1.132
diff -u -p -r1.132 i915_drv.c
--- dev/pci/drm/i915/i915_drv.c 28 Jun 2020 02:29:19 -0000 1.132
+++ dev/pci/drm/i915/i915_drv.c 18 Jul 2020 19:46:36 -0000
@@ -2605,12 +2605,70 @@ inteldrm_attachhook(struct device *self)
config_found_sm(self, &aa, wsemuldisplaydevprint,
wsemuldisplaydevsubmatch);
+
+#ifdef __OpenBSD__
+ gpuperf_register(dev_priv->sc_dev.dv_xname,
+ inteldrm_set_gpuperf, dev_priv);
+#endif /* __OpenBSD__ */
+
return;
fail:
inteldrm_fatal_error = 1;
inteldrm_forcedetach(dev_priv);
}
+
+#ifdef __OpenBSD__
+#ifdef GPUPERF_DEBUG
+#define GPRINTF(x...) do { printf(x); } while(0)
+#else
+#define GPRINTF(x...)
+#endif /* GPUPERF_DEBUG */
+
+int
+inteldrm_set_gpuperf(gpuperf_level level, void *arg)
+{
+ struct inteldrm_softc *dev_priv = arg;
+ struct intel_rps *rps = &dev_priv->gt.rps;
+ u_int32_t min = rps->min_freq;
+ u_int32_t max = rps->max_freq;
+
+ GPRINTF("inteldrm: min %u, max %u, min_s %u, max_s %u, b %u, act %d MHz\n",
+ min, max, rps->min_freq_softlimit, rps->max_freq_softlimit,
+ rps->boost_freq, intel_gpu_freq(dev_priv, rps->cur_freq));
+
+ /*
+ * On haswell & broadwell min_freq_softlimit is higher than min_freq
+ * by default. Allow those devices to clock down further by ignoring
+ * this special case.
+ */
+ switch (level) {
+ case GPU_AUTO:
+ rps->max_freq_softlimit = max;
+ rps->boost_freq = max;
+ rps->min_freq_softlimit = min;
+ break;
+ case GPU_LOW:
+ rps->max_freq_softlimit = min;
+ rps->boost_freq = min;
+ rps->min_freq_softlimit = min;
+ break;
+ case GPU_HIGH:
+ rps->max_freq_softlimit = max;
+ rps->boost_freq = max;
+ rps->min_freq_softlimit = max;
+ break;
+ default:
+ return 1;
+ }
+
+ GPRINTF("inteldrm: min %u, max %u, min_s %u, max_s %u, b %u, act %d MHz\n",
+ min, max, rps->min_freq_softlimit, rps->max_freq_softlimit,
+ rps->boost_freq, intel_gpu_freq(dev_priv, rps->cur_freq));
+
+ return 0;
+}
+#endif /* __OpenBSD__ */
int
inteldrm_detach(struct device *self, int flags)
Index: dev/pci/drm/i915/i915_drv.h
===================================================================
RCS file: /var/cvs/src/sys/dev/pci/drm/i915/i915_drv.h,v
retrieving revision 1.92
diff -u -p -r1.92 i915_drv.h
--- dev/pci/drm/i915/i915_drv.h 29 Jun 2020 04:13:30 -0000 1.92
+++ dev/pci/drm/i915/i915_drv.h 18 Jul 2020 19:43:06 -0000
@@ -2000,3 +2000,8 @@ i915_coherent_map_type(struct drm_i915_p
}
#endif
+
+#ifdef __OpenBSD__
+#include <sys/gpuperf.h>
+int inteldrm_set_gpuperf(gpuperf_level level, void *arg);
+#endif /* __OpenBSD__ */
Index: kern/sched_bsd.c
===================================================================
RCS file: /var/cvs/src/sys/kern/sched_bsd.c,v
retrieving revision 1.63
diff -u -p -r1.63 sched_bsd.c
--- kern/sched_bsd.c 30 May 2020 14:42:59 -0000 1.63
+++ kern/sched_bsd.c 18 Jul 2020 19:43:06 -0000
@@ -540,6 +540,7 @@ int perfpolicy = PERFPOL_MANUAL;
/*
* The code below handles CPU throttling.
*/
+#include <sys/gpuperf.h>
#include <sys/sysctl.h>
void setperf_auto(void *);
@@ -630,6 +631,11 @@ sysctl_hwsetperf(void *oldp, size_t *old
perflevel = newperf;
cpu_setperf(perflevel);
+ if (perflevel == 100)
+ gpuperf_set(GPU_HIGH);
+ else
+ gpuperf_set(GPU_LOW);
+
return 0;
}
@@ -674,9 +680,11 @@ sysctl_hwperfpolicy(void *oldp, size_t *
if (perfpolicy == PERFPOL_AUTO) {
timeout_add_msec(&setperf_to, 200);
+ gpuperf_set(GPU_AUTO);
} else if (perfpolicy == PERFPOL_HIGH) {
perflevel = 100;
cpu_setperf(perflevel);
+ gpuperf_set(GPU_HIGH);
}
return 0;
}
Index: kern/subr_gpuperf.c
===================================================================
RCS file: kern/subr_gpuperf.c
diff -N kern/subr_gpuperf.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ kern/subr_gpuperf.c 18 Jul 2020 19:43:06 -0000
@@ -0,0 +1,79 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2019, 2020 Benjamin Baier <ben@netzbasis.de>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/gpuperf.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+
+#ifdef GPUPERF_DEBUG
+#define DPRINTF(x...) do { printf(x); } while(0)
+#else
+#define DPRINTF(x...)
+#endif /* GPUPERF_DEBUG */
+
+struct gpuperf_dev {
+ char name[16]; /* device name */
+ void *arg; /* arg passthrough */
+ int (*callback)(gpuperf_level, void *);
+ LIST_ENTRY(gpuperf_dev) next;
+};
+
+LIST_HEAD(, gpuperf_dev) gpuperf_list =
+ LIST_HEAD_INITIALIZER(gpuperf_list);
+
+int
+gpuperf_register(const char *name, int (*callback)(gpuperf_level, void *),
+ void *arg)
+{
+ struct gpuperf_dev *dev;
+ int status = 0;
+
+ if ((dev = malloc(sizeof(*dev), M_DEVBUF, M_NOWAIT)) == NULL)
+ return -1;
+
+ strlcpy(dev->name, name, sizeof(dev->name));
+ dev->callback = callback;
+ dev->arg = arg;
+
+ LIST_INSERT_HEAD(&gpuperf_list, dev, next);
+ status = dev->callback(GPU_AUTO, dev->arg);
+
+ DPRINTF("gpuperf: %s registered, status %d\n", dev->name, status);
+
+ return status;
+}
+
+int
+gpuperf_set(gpuperf_level level)
+{
+ struct gpuperf_dev *dev;
+ int status = 0;
+
+ if ((level < GPU_AUTO) || (level > GPU_HIGH))
+ return -1;
+
+ LIST_FOREACH(dev, &gpuperf_list, next) {
+ status += dev->callback(level, dev->arg);
+
+ DPRINTF("gpuperf: requesting %d from %s, status %d\n",
+ level, dev->name, status);
+ }
+
+ return status;
+}
Index: sys/gpuperf.h
===================================================================
RCS file: sys/gpuperf.h
diff -N sys/gpuperf.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/gpuperf.h 18 Jul 2020 19:43:06 -0000
@@ -0,0 +1,31 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2019, 2020 Benjamin Baier <ben@netzbasis.de>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SYS_GPUPERF_H_
+#define _SYS_GPUPERF_H_
+
+typedef enum {
+ GPU_AUTO,
+ GPU_LOW,
+ GPU_HIGH
+} gpuperf_level;
+
+int gpuperf_set(gpuperf_level);
+int gpuperf_register(const char *, int (*)(gpuperf_level, void *), void *);
+
+#endif /* _SYS_GPUPERF_H_ */