From 06551c5b621aefb7262618cf22cae0567494d23a Mon Sep 17 00:00:00 2001 From: erpalma Date: Tue, 12 Jun 2018 19:08:46 +0200 Subject: [PATCH] add experimental HWP override on high load --- etc/lenovo_fix.conf | 4 +++- lenovo_fix.py | 24 ++++++++++++++++++++++-- requirements.txt | 5 +++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/etc/lenovo_fix.conf b/etc/lenovo_fix.conf index f3c5375..8077db8 100644 --- a/etc/lenovo_fix.conf +++ b/etc/lenovo_fix.conf @@ -29,7 +29,9 @@ PL2_Tdp_W: 44 # Time window #2 duration PL2_Duration_S: 0.002 # Max allowed temperature before throttling -Trip_Temp_C: 97 +Trip_Temp_C: 95 +# Set HWP energy performance hints to 'performance' on high load (EXPERIMENTAL) +HWP_Mode: False [UNDERVOLT] # CPU core voltage offset (mV) diff --git a/lenovo_fix.py b/lenovo_fix.py index e7a5bfc..be94454 100755 --- a/lenovo_fix.py +++ b/lenovo_fix.py @@ -4,11 +4,13 @@ import configparser import dbus import glob import os +import psutil import struct import subprocess from collections import defaultdict from dbus.mainloop.glib import DBusGMainLoop +from multiprocessing import cpu_count from periphery import MMIO from threading import Event, Thread @@ -109,6 +111,15 @@ def calc_reg_values(config): return regs +def set_hwp(pref): + # set HWP energy performance hints + assert pref in ('performance', 'balance_performance', 'default', 'balance_power', 'power') + n = glob.glob('/sys/devices/system/cpu/cpu[0-9]*/cpufreq/energy_performance_preference') + for c in n: + with open(c, 'wb') as f: + f.write(pref.encode()) + + def power_thread(config, regs, exit_event): mchbar_mmio = MMIO(0xfed159a0, 8) @@ -124,7 +135,15 @@ def power_thread(config, regs, exit_event): mchbar_mmio.write32(0, regs[power_source]['MSR_PKG_POWER_LIMIT'] & 0xffffffff) mchbar_mmio.write32(4, regs[power_source]['MSR_PKG_POWER_LIMIT'] >> 32) - exit_event.wait(config.getfloat(power_source, 'Update_Rate_s')) + wait_t = config.getfloat(power_source, 'Update_Rate_s') + enable_hwp_mode = config.getboolean('AC', 'HWP_Mode', fallback=False) + if power_source == 'AC' and enable_hwp_mode: + cpu_usage = float(psutil.cpu_percent(interval=wait_t)) + # set the full performance mode only when load is greater than this threshold (~ at least 1 core full speed) + performance_mode = cpu_usage > 100. / (cpu_count() * 1.25) + set_hwp('performance' if performance_mode else 'balance_performance') + else: + exit_event.wait(wait_t) def main(): @@ -136,6 +155,7 @@ def main(): exit_event = Event() t = Thread(target=power_thread, args=(config, regs, exit_event)) + t.daemon = True t.start() undervolt(config) @@ -162,7 +182,7 @@ def main(): exit_event.set() loop.quit() - t.join() + t.join(timeout=1) if __name__ == '__main__': diff --git a/requirements.txt b/requirements.txt index 18a101f..4a604f6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ configparser==3.5.0 -dbus-python==1.2.4 -PyGObject==3.28.2 +dbus-python==1.2.8 +psutil==5.4.6 +PyGObject==3.28.3 python-periphery==1.1.1