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_ */