From 9105d969542dd92af157cb98fa322e9432f9821e Mon Sep 17 00:00:00 2001 From: h3artbl33d Date: Fri, 10 May 2024 13:31:11 +0200 Subject: [PATCH] Add gpuperf patch --- patches/gpuperf.diff | 330 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 patches/gpuperf.diff diff --git a/patches/gpuperf.diff b/patches/gpuperf.diff new file mode 100644 index 0000000..5e5440a --- /dev/null +++ b/patches/gpuperf.diff @@ -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 ++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 + #include + + 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 ++ * ++ * 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 ++#include ++#include ++#include ++ ++#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 ++ * ++ * 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_ */