mirror of
https://gitlab.freedesktop.org/upower/power-profiles-daemon.git
synced 2026-05-05 05:18:32 +02:00
intel-pstate: Inhibit perf mode when overheating
thermald can disable turbo altogether if needed to avoid reaching too high operating temperatures, so make the p-state driver monitor this, and mark the performance mode as inhibited if "no_turbo" is set. Closes: #14
This commit is contained in:
parent
82141045e3
commit
95a67713cf
2 changed files with 90 additions and 2 deletions
|
|
@ -13,6 +13,7 @@
|
|||
#include "ppd-driver-intel-pstate.h"
|
||||
|
||||
#define CPUFREQ_POLICY_DIR "/devices/system/cpu/cpufreq/"
|
||||
#define NO_TURBO_PATH "/devices/system/cpu/intel_pstate/no_turbo"
|
||||
|
||||
struct _PpdDriverIntelPstate
|
||||
{
|
||||
|
|
@ -22,6 +23,8 @@ struct _PpdDriverIntelPstate
|
|||
PpdProfile activated_profile;
|
||||
gboolean on_battery;
|
||||
GList *devices; /* GList of paths */
|
||||
GFileMonitor *no_turbo_mon;
|
||||
char *no_turbo_path;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (PpdDriverIntelPstate, ppd_driver_intel_pstate, PPD_TYPE_DRIVER)
|
||||
|
|
@ -70,6 +73,65 @@ on_battery_changed (GObject *gobject,
|
|||
pstate->on_battery ? "on battery" : "on mains");
|
||||
}
|
||||
|
||||
static void
|
||||
update_no_turbo (PpdDriverIntelPstate *pstate)
|
||||
{
|
||||
g_autofree char *contents = NULL;
|
||||
gboolean turbo_disabled = FALSE;
|
||||
|
||||
if (g_file_get_contents (pstate->no_turbo_path, &contents, NULL, NULL)) {
|
||||
if (g_strcmp0 (contents, "1") == 0)
|
||||
turbo_disabled = TRUE;
|
||||
}
|
||||
|
||||
g_object_set (G_OBJECT (pstate), "performance-inhibited",
|
||||
turbo_disabled ? "high-operating-temperature" : NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
no_turbo_changed (GFileMonitor *monitor,
|
||||
GFile *file,
|
||||
GFile *other_file,
|
||||
GFileMonitorEvent event_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
PpdDriverIntelPstate *pstate = user_data;
|
||||
g_autofree char *path = NULL;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
g_debug ("File monitor change happened for '%s'", path);
|
||||
update_no_turbo (pstate);
|
||||
}
|
||||
|
||||
static GFileMonitor *
|
||||
monitor_no_turbo_prop (const char *path)
|
||||
{
|
||||
g_autoptr(GFile) no_turbo = NULL;
|
||||
|
||||
if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
|
||||
g_debug ("Not monitoring '%s' as it does not exist", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_debug ("About to start monitoring '%s'", path);
|
||||
no_turbo = g_file_new_for_path (path);
|
||||
return g_file_monitor (no_turbo, G_FILE_MONITOR_NONE, NULL, NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_no_turbo_path (void)
|
||||
{
|
||||
const char *root;
|
||||
g_autofree char *dir = NULL;
|
||||
|
||||
root = g_getenv ("UMOCKDEV_DIR");
|
||||
if (!root || *root == '\0')
|
||||
root = "/sys";
|
||||
|
||||
return g_build_filename (root, NO_TURBO_PATH, NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_policy_dir (void)
|
||||
{
|
||||
|
|
@ -119,15 +181,25 @@ ppd_driver_intel_pstate_probe (PpdDriver *driver)
|
|||
ret = TRUE;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
pstate->client = up_client_new ();
|
||||
if (!ret)
|
||||
goto out;
|
||||
|
||||
pstate->client = up_client_new ();
|
||||
if (pstate->client) {
|
||||
g_signal_connect (G_OBJECT (pstate->client), "notify::on-battery",
|
||||
G_CALLBACK (on_battery_changed), pstate);
|
||||
pstate->on_battery = up_client_get_on_battery (pstate->client);
|
||||
}
|
||||
|
||||
/* Monitor the first "no_turbo" */
|
||||
pstate->no_turbo_path = get_no_turbo_path ();
|
||||
pstate->no_turbo_mon = monitor_no_turbo_prop (pstate->no_turbo_path);
|
||||
if (pstate->no_turbo_mon) {
|
||||
g_signal_connect (G_OBJECT (pstate->no_turbo_mon), "changed",
|
||||
G_CALLBACK (no_turbo_changed), pstate);
|
||||
}
|
||||
update_no_turbo (pstate);
|
||||
|
||||
out:
|
||||
g_debug ("%s p-state settings",
|
||||
ret ? "Found" : "Didn't find");
|
||||
|
|
@ -190,6 +262,8 @@ ppd_driver_intel_pstate_finalize (GObject *object)
|
|||
driver = PPD_DRIVER_INTEL_PSTATE (object);
|
||||
g_clear_list (&driver->devices, g_free);
|
||||
g_clear_object (&driver->client);
|
||||
g_clear_pointer (&driver->no_turbo_path, g_free);
|
||||
g_clear_object (&driver->no_turbo_mon);
|
||||
G_OBJECT_CLASS (ppd_driver_intel_pstate_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -292,6 +292,12 @@ class Tests(dbusmock.DBusTestCase):
|
|||
with open(os.path.join(dir2, "energy_performance_preference") ,'w') as prefs:
|
||||
prefs.write("performance")
|
||||
|
||||
# Create no_turbo pref
|
||||
pstate_dir = os.path.join(self.testbed.get_root_dir(), "devices/system/cpu/intel_pstate")
|
||||
os.makedirs(pstate_dir)
|
||||
with open(os.path.join(pstate_dir, "no_turbo") ,'w') as no_turbo:
|
||||
no_turbo.write("0")
|
||||
|
||||
self.start_daemon()
|
||||
|
||||
profiles = self.get_dbus_property('Profiles')
|
||||
|
|
@ -313,6 +319,14 @@ class Tests(dbusmock.DBusTestCase):
|
|||
contents = f.read()
|
||||
self.assertEqual(contents, b'performance')
|
||||
|
||||
# Disable turbo
|
||||
with open(os.path.join(pstate_dir, "no_turbo") ,'w') as no_turbo:
|
||||
no_turbo.write("1")
|
||||
|
||||
self.assertEventually(lambda: self.have_text_in_log('File monitor change happened for '))
|
||||
self.assertEqual(self.get_dbus_property('ActiveProfile'), 'balanced')
|
||||
self.assertEqual(self.get_dbus_property('PerformanceInhibited'), 'high-operating-temperature')
|
||||
|
||||
self.stop_daemon()
|
||||
|
||||
# Verify that the Lenovo DYTC driver still gets preferred
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue