Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package power-profiles-daemon for
openSUSE:Factory checked in at 2023-04-28 16:22:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/power-profiles-daemon (Old)
and /work/SRC/openSUSE:Factory/.power-profiles-daemon.new.1533 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "power-profiles-daemon"
Fri Apr 28 16:22:25 2023 rev:7 rq:1083162 version:0.13
Changes:
--------
---
/work/SRC/openSUSE:Factory/power-profiles-daemon/power-profiles-daemon.changes
2022-07-08 14:01:32.530422942 +0200
+++
/work/SRC/openSUSE:Factory/.power-profiles-daemon.new.1533/power-profiles-daemon.changes
2023-04-28 16:22:36.261742676 +0200
@@ -1,0 +2,9 @@
+Wed Apr 26 15:19:01 UTC 2023 - Enrico Belleri <[email protected]>
+
+- Update to version 0.13:
+ * Add support for the AMD P-State driver included in Linux 6.3
+ * Fix mismatched profiles on some HP laptops and some
+ miscellaneous bug fixes.
+
+
+-------------------------------------------------------------------
Old:
----
power-profiles-daemon-0.12.tar.bz2
New:
----
power-profiles-daemon-0.13.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ power-profiles-daemon.spec ++++++
--- /var/tmp/diff_new_pack.wzVs3f/_old 2023-04-28 16:22:37.461749680 +0200
+++ /var/tmp/diff_new_pack.wzVs3f/_new 2023-04-28 16:22:37.465749704 +0200
@@ -1,7 +1,7 @@
#
# spec file for package power-profiles-daemon
#
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
Name: power-profiles-daemon
-Version: 0.12
+Version: 0.13
Release: 0
Summary: Power profiles handling over D-Bus
License: GPL-3.0-or-later
@@ -28,16 +28,16 @@
BuildRequires: c_compiler
BuildRequires: gtk-doc
-BuildRequires: meson
+BuildRequires: meson >= 0.54.0
BuildRequires: pkgconfig
BuildRequires: python3-dbusmock
BuildRequires: pkgconfig(gio-2.0)
-BuildRequires: pkgconfig(gudev-1.0)
+BuildRequires: pkgconfig(gudev-1.0) >= 234
BuildRequires: pkgconfig(polkit-gobject-1) >= 0.114
BuildRequires: pkgconfig(systemd)
+BuildRequires: pkgconfig(upower-glib)
BuildRequires: pkgconfig(udev)
BuildRequires: pkgconfig(umockdev-1.0)
-BuildRequires: pkgconfig(upower-glib)
Requires: polkit
%description
@@ -59,6 +59,7 @@
%meson \
-Dsystemdsystemunitdir=%{_unitdir} \
-Dgtk_doc=true \
+ -Dtests=true \
%{nil}
%meson_build
++++++ power-profiles-daemon-0.12.tar.bz2 -> power-profiles-daemon-0.13.tar.bz2
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/power-profiles-daemon-0.12/.gitlab-ci.yml
new/power-profiles-daemon-0.13/.gitlab-ci.yml
--- old/power-profiles-daemon-0.12/.gitlab-ci.yml 2022-06-28
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/.gitlab-ci.yml 2023-04-26
14:53:07.000000000 +0200
@@ -18,6 +18,11 @@
umockdev
e2fsprogs
+workflow:
+ rules:
+ - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+ - if: $CI_PIPELINE_SOURCE == 'push'
+
build_stable:
before_script:
- dnf upgrade -y --nogpgcheck fedora-release fedora-repos*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/power-profiles-daemon-0.12/NEWS
new/power-profiles-daemon-0.13/NEWS
--- old/power-profiles-daemon-0.12/NEWS 2022-06-28 15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/NEWS 2023-04-26 14:53:07.000000000 +0200
@@ -1,3 +1,10 @@
+0.13
+----
+
+This release adds support for the AMD P-State driver that's been added to the
+6.3 Linux kernel. This release also fixes mismatched profiles on some HP
+laptops and some miscellaneous bug fixes.
+
0.12
----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/power-profiles-daemon-0.12/README.md
new/power-profiles-daemon-0.13/README.md
--- old/power-profiles-daemon-0.12/README.md 2022-06-28 15:58:14.000000000
+0200
+++ new/power-profiles-daemon-0.13/README.md 2023-04-26 14:53:07.000000000
+0200
@@ -134,6 +134,35 @@
For more information, please refer to the [Intel P-State scaling driver
documentation](https://www.kernel.org/doc/html/v5.17/admin-guide/pm/intel_pstate.html)
and the [Intel Performance and Energy Bias
Hint](https://www.kernel.org/doc/html/v5.17/admin-guide/pm/intel_epb.html).
+Operations on AMD-based machines
+----------------------------------
+
+The "driver" for making the hardware act on the user-selected power profile on
AMD CPU-based
+machines is based on the [AMD P-State scaling
driver](https://www.kernel.org/doc/html/v6.3/admin-guide/pm/amd-pstate.html)
+if available.
+
+It is only used if a `platform_profile` driver isn't available for the system,
the
+CPU supports Collaborative Processor Performance Control (CPPC), and the AMD
P-State
+scaling driver is in `active` mode.
+
+Example of a system without `platform_profile` support but with `active`
P-State
+operation mode:
+```
+$ cat /sys/firmware/acpi/platform_profile_choices
+cat: /sys/firmware/acpi/platform_profile_choices: No such file or directory
+$ cat /sys/devices/system/cpu/amd_pstate/status
+active
+```
+
+If the AMD P-State scaling driver is not loaded or is not in `active` mode,
then
+the placeholder driver will be used, and there won't be a performance mode.
+
+Finally, if the AMD P-State scaling driver is used in `active` mode, the
P-State
+scaling governor will be changed to `powersave` as it is the only P-State
scaling
+governor that allows for the "Energy vs Performance Hints" to be taken into
consideration.
+
+For more information, please refer to the [AMD P-State scaling driver
documentation](https://www.kernel.org/doc/html/v6.3/admin-guide/pm/amd-pstate.html).
+
Testing
-------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/power-profiles-daemon-0.12/docs/meson.build
new/power-profiles-daemon-0.13/docs/meson.build
--- old/power-profiles-daemon-0.12/docs/meson.build 2022-06-28
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/docs/meson.build 2023-04-26
14:53:07.000000000 +0200
@@ -24,6 +24,7 @@
'ppd-driver-balanced.h',
'ppd-driver-fake.h',
'ppd-driver-intel-pstate.h',
+ 'ppd-driver-amd-pstate.h',
'ppd-driver-placeholder.h',
'ppd-driver-platform-profile.h',
'ppd-driver-power-saver.h',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/power-profiles-daemon-0.12/meson.build
new/power-profiles-daemon-0.13/meson.build
--- old/power-profiles-daemon-0.12/meson.build 2022-06-28 15:58:14.000000000
+0200
+++ new/power-profiles-daemon-0.13/meson.build 2023-04-26 14:53:07.000000000
+0200
@@ -1,5 +1,5 @@
project('power-profiles-daemon', [ 'c' ],
- version: '0.12',
+ version: '0.13',
license: 'GPLv3+',
default_options: [
'buildtype=debugoptimized',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/power-profiles-daemon-0.12/src/meson.build
new/power-profiles-daemon-0.13/src/meson.build
--- old/power-profiles-daemon-0.12/src/meson.build 2022-06-28
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/src/meson.build 2023-04-26
14:53:07.000000000 +0200
@@ -46,6 +46,7 @@
'power-profiles-daemon.c',
'ppd-action-trickle-charge.c',
'ppd-driver-intel-pstate.c',
+ 'ppd-driver-amd-pstate.c',
'ppd-driver-platform-profile.c',
'ppd-driver-placeholder.c',
'ppd-driver-fake.c',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/power-profiles-daemon-0.12/src/power-profiles-daemon.c
new/power-profiles-daemon-0.13/src/power-profiles-daemon.c
--- old/power-profiles-daemon-0.12/src/power-profiles-daemon.c 2022-06-28
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/src/power-profiles-daemon.c 2023-04-26
14:53:07.000000000 +0200
@@ -75,6 +75,7 @@
#include "ppd-driver-placeholder.h"
#include "ppd-driver-platform-profile.h"
#include "ppd-driver-intel-pstate.h"
+#include "ppd-driver-amd-pstate.h"
#include "ppd-driver-fake.h"
typedef GType (*GTypeGetFunc) (void);
@@ -84,6 +85,7 @@
ppd_driver_fake_get_type,
ppd_driver_platform_profile_get_type,
ppd_driver_intel_pstate_get_type,
+ ppd_driver_amd_pstate_get_type,
/* Generic profile driver */
ppd_driver_placeholder_get_type,
@@ -103,6 +105,16 @@
#define PROP_ALL (PROP_ACTIVE_PROFILE | PROP_INHIBITED | PROP_PROFILES |
PROP_ACTIONS | PROP_DEGRADED | PROP_ACTIVE_PROFILE_HOLDS)
+static gboolean
+get_profile_available (PpdApp *data,
+ PpdProfile profile)
+{
+ PpdDriver *driver;
+
+ driver = GET_DRIVER(profile);
+ return driver != NULL;
+}
+
static const char *
get_active_profile (PpdApp *data)
{
@@ -386,6 +398,11 @@
"Invalid profile name '%s'", profile);
return FALSE;
}
+ if (!get_profile_available (data, target_profile)) {
+ g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Cannot switch to unavailable profile '%s'", profile);
+ return FALSE;
+ }
if (target_profile == data->active_profile)
return TRUE;
@@ -554,8 +571,14 @@
profile = ppd_profile_from_str (profile_name);
if (profile != PPD_PROFILE_PERFORMANCE &&
profile != PPD_PROFILE_POWER_SAVER) {
+ g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
+ "Only profiles
'performance' and 'power-saver' can be a hold profile");
+ return;
+ }
+ if (!get_profile_available (data, profile)) {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
- "Only profiles 'performance' and
'power-saver' can be a hold profile");
+ "Cannot hold profile '%s' as it is
not available",
+ profile_name);
return;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/power-profiles-daemon-0.12/src/powerprofilesctl.in
new/power-profiles-daemon-0.13/src/powerprofilesctl.in
--- old/power-profiles-daemon-0.12/src/powerprofilesctl.in 2022-06-28
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/src/powerprofilesctl.in 2023-04-26
14:53:07.000000000 +0200
@@ -127,44 +127,43 @@
profiles = proxy.Get('(ss)', 'net.hadess.PowerProfiles', prop)
except:
raise
- else:
- return profiles
+ return profiles
def _list():
try:
profiles = get_profiles_property('Profiles')
reason = get_proxy().Get('(ss)', 'net.hadess.PowerProfiles',
'PerformanceDegraded')
- degraded = (reason != '')
+ degraded = reason != ''
active = get_proxy().Get('(ss)', 'net.hadess.PowerProfiles',
'ActiveProfile')
except:
raise
- else:
- index = 0
- for profile in reversed(profiles):
- if index > 0:
- print('')
- marker = '*' if profile['Profile'] == active else ' '
- print(f'{marker} {profile["Profile"]}:')
- print(' Driver: ', profile['Driver'])
- if profile['Profile'] == 'performance':
- print(' Degraded: ', f'yes ({reason})' if degraded else
'no')
- index += 1
+
+ index = 0
+ for profile in reversed(profiles):
+ if index > 0:
+ print('')
+ marker = '*' if profile['Profile'] == active else ' '
+ print(f'{marker} {profile["Profile"]}:')
+ print(' Driver: ', profile['Driver'])
+ if profile['Profile'] == 'performance':
+ print(' Degraded: ', f'yes ({reason})' if degraded else 'no')
+ index += 1
def _list_holds():
try:
holds = get_profiles_property('ActiveProfileHolds')
except:
raise
- else:
- index = 0
- for hold in holds:
- if index > 0:
- print('')
- print('Hold:')
- print(' Profile: ', hold['Profile'])
- print(' Application ID: ', hold['ApplicationId'])
- print(' Reason: ', hold['Reason'])
- index += 1
+
+ index = 0
+ for hold in holds:
+ if index > 0:
+ print('')
+ print('Hold:')
+ print(' Profile: ', hold['Profile'])
+ print(' Application ID: ', hold['ApplicationId'])
+ print(' Reason: ', hold['Reason'])
+ index += 1
def _launch(args, profile, appid, reason):
try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/power-profiles-daemon-0.12/src/ppd-driver-amd-pstate.c
new/power-profiles-daemon-0.13/src/ppd-driver-amd-pstate.c
--- old/power-profiles-daemon-0.12/src/ppd-driver-amd-pstate.c 1970-01-01
01:00:00.000000000 +0100
+++ new/power-profiles-daemon-0.13/src/ppd-driver-amd-pstate.c 2023-04-26
14:53:07.000000000 +0200
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2020 Bastien Nocera <[email protected]>
+ * Copyright (c) 2022 Prajna Sariputra <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published by
+ * the Free Software Foundation.
+ *
+ */
+
+#include <upower.h>
+
+#include "ppd-utils.h"
+#include "ppd-driver-amd-pstate.h"
+
+#define CPUFREQ_POLICY_DIR "/sys/devices/system/cpu/cpufreq/"
+#define DEFAULT_CPU_FREQ_SCALING_GOV "powersave"
+#define PSTATE_STATUS_PATH "/sys/devices/system/cpu/amd_pstate/status"
+
+struct _PpdDriverAmdPstate
+{
+ PpdDriver parent_instance;
+
+ PpdProfile activated_profile;
+ GList *epp_devices; /* GList of paths */
+};
+
+G_DEFINE_TYPE (PpdDriverAmdPstate, ppd_driver_amd_pstate, PPD_TYPE_DRIVER)
+
+static gboolean ppd_driver_amd_pstate_activate_profile (PpdDriver
*driver,
+ PpdProfile
profile,
+
PpdProfileActivationReason reason,
+ GError
**error);
+
+static GObject*
+ppd_driver_amd_pstate_constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+
+ object = G_OBJECT_CLASS (ppd_driver_amd_pstate_parent_class)->constructor
(type,
+
n_construct_params,
+
construct_params);
+ g_object_set (object,
+ "driver-name", "amd_pstate",
+ "profiles", PPD_PROFILE_PERFORMANCE | PPD_PROFILE_BALANCED |
PPD_PROFILE_POWER_SAVER,
+ NULL);
+
+ return object;
+}
+
+static PpdProbeResult
+probe_epp (PpdDriverAmdPstate *pstate)
+{
+ g_autoptr(GDir) dir = NULL;
+ g_autofree char *policy_dir = NULL;
+ g_autofree char *pstate_status_path = NULL;
+ g_autofree char *status = NULL;
+ const char *dirname;
+ PpdProbeResult ret = PPD_PROBE_RESULT_FAIL;
+
+ /* Verify that AMD P-State is running in active mode */
+ pstate_status_path = ppd_utils_get_sysfs_path (PSTATE_STATUS_PATH);
+ if (!g_file_get_contents (pstate_status_path, &status, NULL, NULL))
+ return ret;
+ status = g_strchomp (status);
+ if (g_strcmp0 (status, "active") != 0) {
+ g_debug ("AMD P-State is not running in active mode");
+ return ret;
+ }
+
+ policy_dir = ppd_utils_get_sysfs_path (CPUFREQ_POLICY_DIR);
+ dir = g_dir_open (policy_dir, 0, NULL);
+ if (!dir) {
+ g_debug ("Could not open %s", policy_dir);
+ return ret;
+ }
+
+ while ((dirname = g_dir_read_name (dir)) != NULL) {
+ g_autofree char *path = NULL;
+ g_autofree char *gov_path = NULL;
+ g_autoptr(GError) error = NULL;
+
+ path = g_build_filename (policy_dir,
+ dirname,
+ "energy_performance_preference",
+ NULL);
+ if (!g_file_test (path, G_FILE_TEST_EXISTS))
+ continue;
+
+ /* Force a scaling_governor where the preference can be written */
+ gov_path = g_build_filename (policy_dir,
+ dirname,
+ "scaling_governor",
+ NULL);
+ if (!ppd_utils_write (gov_path, DEFAULT_CPU_FREQ_SCALING_GOV, &error)) {
+ g_warning ("Could not change scaling governor %s to '%s'", dirname,
DEFAULT_CPU_FREQ_SCALING_GOV);
+ continue;
+ }
+
+ pstate->epp_devices = g_list_prepend (pstate->epp_devices, g_steal_pointer
(&path));
+ ret = PPD_PROBE_RESULT_SUCCESS;
+ }
+
+ return ret;
+}
+
+static PpdProbeResult
+ppd_driver_amd_pstate_probe (PpdDriver *driver)
+{
+ PpdDriverAmdPstate *pstate = PPD_DRIVER_AMD_PSTATE (driver);
+ PpdProbeResult ret = PPD_PROBE_RESULT_FAIL;
+
+ ret = probe_epp (pstate);
+
+ if (ret != PPD_PROBE_RESULT_SUCCESS)
+ goto out;
+
+out:
+ g_debug ("%s p-state settings",
+ ret == PPD_PROBE_RESULT_SUCCESS ? "Found" : "Didn't find");
+ return ret;
+}
+
+static const char *
+profile_to_epp_pref (PpdProfile profile)
+{
+ /* Note that we don't check "energy_performance_available_preferences"
+ * as all the values are always available */
+ switch (profile) {
+ case PPD_PROFILE_POWER_SAVER:
+ return "power";
+ case PPD_PROFILE_BALANCED:
+ return "balance_performance";
+ case PPD_PROFILE_PERFORMANCE:
+ return "performance";
+ }
+
+ g_assert_not_reached ();
+}
+
+static gboolean
+apply_pref_to_devices (GList *devices,
+ const char *pref,
+ GError **error)
+{
+ gboolean ret = TRUE;
+ GList *l;
+
+ for (l = devices; l != NULL; l = l->next) {
+ const char *path = l->data;
+
+ ret = ppd_utils_write (path, pref, error);
+ if (!ret)
+ break;
+ }
+
+ return ret;
+}
+
+static gboolean
+ppd_driver_amd_pstate_activate_profile (PpdDriver *driver,
+ PpdProfile profile,
+ PpdProfileActivationReason reason,
+ GError **error)
+{
+ PpdDriverAmdPstate *pstate = PPD_DRIVER_AMD_PSTATE (driver);
+ gboolean ret = FALSE;
+ const char *pref;
+
+ g_return_val_if_fail (pstate->epp_devices != NULL, FALSE);
+
+ if (pstate->epp_devices) {
+ pref = profile_to_epp_pref (profile);
+ ret = apply_pref_to_devices (pstate->epp_devices, pref, error);
+ if (!ret)
+ return ret;
+ }
+
+ if (ret)
+ pstate->activated_profile = profile;
+
+ return ret;
+}
+
+static void
+ppd_driver_amd_pstate_finalize (GObject *object)
+{
+ PpdDriverAmdPstate *driver;
+
+ driver = PPD_DRIVER_AMD_PSTATE (object);
+ g_clear_list (&driver->epp_devices, g_free);
+ G_OBJECT_CLASS (ppd_driver_amd_pstate_parent_class)->finalize (object);
+}
+
+static void
+ppd_driver_amd_pstate_class_init (PpdDriverAmdPstateClass *klass)
+{
+ GObjectClass *object_class;
+ PpdDriverClass *driver_class;
+
+ object_class = G_OBJECT_CLASS(klass);
+ object_class->constructor = ppd_driver_amd_pstate_constructor;
+ object_class->finalize = ppd_driver_amd_pstate_finalize;
+
+ driver_class = PPD_DRIVER_CLASS(klass);
+ driver_class->probe = ppd_driver_amd_pstate_probe;
+ driver_class->activate_profile = ppd_driver_amd_pstate_activate_profile;
+}
+
+static void
+ppd_driver_amd_pstate_init (PpdDriverAmdPstate *self)
+{
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/power-profiles-daemon-0.12/src/ppd-driver-amd-pstate.h
new/power-profiles-daemon-0.13/src/ppd-driver-amd-pstate.h
--- old/power-profiles-daemon-0.12/src/ppd-driver-amd-pstate.h 1970-01-01
01:00:00.000000000 +0100
+++ new/power-profiles-daemon-0.13/src/ppd-driver-amd-pstate.h 2023-04-26
14:53:07.000000000 +0200
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2020 Bastien Nocera <[email protected]>
+ * Copyright (c) 2022 Prajna Sariputra <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published by
+ * the Free Software Foundation.
+ *
+ */
+
+#pragma once
+
+#include "ppd-driver.h"
+
+#define PPD_TYPE_DRIVER_AMD_PSTATE (ppd_driver_amd_pstate_get_type())
+G_DECLARE_FINAL_TYPE(PpdDriverAmdPstate, ppd_driver_amd_pstate, PPD,
DRIVER_AMD_PSTATE, PpdDriver)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/power-profiles-daemon-0.12/src/ppd-driver-intel-pstate.c
new/power-profiles-daemon-0.13/src/ppd-driver-intel-pstate.c
--- old/power-profiles-daemon-0.12/src/ppd-driver-intel-pstate.c
2022-06-28 15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/src/ppd-driver-intel-pstate.c
2023-04-26 14:53:07.000000000 +0200
@@ -171,7 +171,6 @@
while ((dirname = g_dir_read_name (dir)) != NULL) {
g_autofree char *path = NULL;
- g_autofree char *gov_path = NULL;
path = g_build_filename (policy_dir,
dirname,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/power-profiles-daemon-0.12/src/ppd-driver-platform-profile.c
new/power-profiles-daemon-0.13/src/ppd-driver-platform-profile.c
--- old/power-profiles-daemon-0.12/src/ppd-driver-platform-profile.c
2022-06-28 15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/src/ppd-driver-platform-profile.c
2023-04-26 14:53:07.000000000 +0200
@@ -26,6 +26,7 @@
int lapmode;
PpdProfile acpi_platform_profile;
char **profile_choices;
+ gboolean has_low_power;
GFileMonitor *lapmode_mon;
GFileMonitor *acpi_platform_profile_mon;
guint acpi_platform_profile_changed_id;
@@ -57,10 +58,10 @@
{
switch (profile) {
case PPD_PROFILE_POWER_SAVER:
+ if (!self->has_low_power)
+ return "balanced";
if (g_strv_contains ((const char * const*) self->profile_choices,
"low-power"))
return "low-power";
- if (g_strv_contains ((const char * const*) self->profile_choices, "cool"))
- return "cool";
return "quiet";
case PPD_PROFILE_BALANCED:
return "balanced";
@@ -79,9 +80,9 @@
switch (str[0]) {
case 'l': /* low-power */
- case 'c': /* cool */
case 'q': /* quiet */
return PPD_PROFILE_POWER_SAVER;
+ case 'c': /* cool */
case 'b':
return PPD_PROFILE_BALANCED;
case 'p':
@@ -142,12 +143,15 @@
{
const char * const *choices = (const char * const*) self->profile_choices;
- if ((g_strv_contains (choices, "low-power") ||
- g_strv_contains (choices, "cool") ||
- g_strv_contains (choices, "quiet")) &&
- g_strv_contains (choices, "balanced") &&
- g_strv_contains (choices, "performance"))
+ if (g_strv_contains (choices, "balanced") &&
+ g_strv_contains (choices, "performance")) {
+ if (g_strv_contains (choices, "low-power") ||
+ g_strv_contains (choices, "quiet"))
+ self->has_low_power = TRUE;
+ else
+ g_debug ("No \"low-power\" profile for device, will be emulated");
return PPD_PROBE_RESULT_SUCCESS;
+ }
return PPD_PROBE_RESULT_DEFER;
}
@@ -203,7 +207,7 @@
gpointer user_data)
{
PpdDriverPlatformProfile *self = user_data;
- g_debug (ACPI_PLATFORM_PROFILE_PATH " changed");
+ g_debug (ACPI_PLATFORM_PROFILE_PATH " changed (%d)", event_type);
if (self->probe_result == PPD_PROBE_RESULT_DEFER) {
g_signal_emit_by_name (G_OBJECT (self), "probe-request", 0);
return;
@@ -219,6 +223,7 @@
{
PpdDriverPlatformProfile *self = PPD_DRIVER_PLATFORM_PROFILE (driver);
g_autofree char *platform_profile_path = NULL;
+ const char *platform_profile_value;
g_return_val_if_fail (self->acpi_platform_profile_mon, FALSE);
@@ -227,6 +232,14 @@
ppd_profile_to_str (profile));
return TRUE;
}
+
+ platform_profile_value = profile_to_acpi_platform_profile_value (self,
profile);
+ if (self->acpi_platform_profile == acpi_platform_profile_value_to_profile
(platform_profile_value)) {
+ g_debug ("Not switching to platform_profile %s, emulating for %s, already
there",
+ platform_profile_value,
+ ppd_profile_to_str (profile));
+ return TRUE;
+ }
g_signal_handler_block (G_OBJECT (self->acpi_platform_profile_mon),
self->acpi_platform_profile_changed_id);
platform_profile_path = ppd_utils_get_sysfs_path
(ACPI_PLATFORM_PROFILE_PATH);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/power-profiles-daemon-0.12/src/ppd-utils.c
new/power-profiles-daemon-0.13/src/ppd-utils.c
--- old/power-profiles-daemon-0.12/src/ppd-utils.c 2022-06-28
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/src/ppd-utils.c 2023-04-26
14:53:07.000000000 +0200
@@ -85,6 +85,7 @@
path = g_build_filename (g_udev_device_get_sysfs_path (device), attribute,
NULL);
file = g_file_new_for_path (path);
+ g_debug ("Monitoring file %s for changes", path);
return g_file_monitor_file (file,
G_FILE_MONITOR_NONE,
NULL,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/power-profiles-daemon-0.12/tests/integration-test.py
new/power-profiles-daemon-0.13/tests/integration-test.py
--- old/power-profiles-daemon-0.12/tests/integration-test.py 2022-06-28
15:58:14.000000000 +0200
+++ new/power-profiles-daemon-0.13/tests/integration-test.py 2023-04-26
14:53:07.000000000 +0200
@@ -320,6 +320,13 @@
self.set_dbus_property('ActiveProfile',
GLib.Variant.new_string('power-saver'))
self.assertEqual(self.get_dbus_property('ActiveProfile'), 'power-saver')
+ with self.assertRaises(gi.repository.GLib.GError):
+ self.set_dbus_property('ActiveProfile',
GLib.Variant.new_string('performance'))
+ self.assertEqual(self.get_dbus_property('ActiveProfile'), 'power-saver')
+
+ with self.assertRaises(gi.repository.GLib.GError):
+ cookie = self.call_dbus_method('HoldProfile', GLib.Variant("(sss)",
('performance', 'testReason', 'testApplication')))
+
# process = subprocess.Popen(['gdbus', 'introspect', '--system',
'--dest', 'net.hadess.PowerProfiles', '--object-path',
'/net/hadess/PowerProfiles'])
# print (self.get_dbus_property('GPUs'))
@@ -598,6 +605,183 @@
self.stop_daemon()
+ def test_amd_pstate(self):
+ '''AMD P-State driver (no UPower)'''
+
+ # Create 2 CPUs with preferences
+ dir1 = os.path.join(self.testbed.get_root_dir(),
"sys/devices/system/cpu/cpufreq/policy0/")
+ os.makedirs(dir1)
+ with open(os.path.join(dir1, 'scaling_governor'), 'w') as gov:
+ gov.write('powersave\n')
+ with open(os.path.join(dir1, "energy_performance_preference"),'w') as
prefs:
+ prefs.write("performance\n")
+ dir2 = os.path.join(self.testbed.get_root_dir(),
"sys/devices/system/cpu/cpufreq/policy1/")
+ os.makedirs(dir2)
+ with open(os.path.join(dir2, 'scaling_governor'), 'w') as gov:
+ gov.write('powersave\n')
+ with open(os.path.join(dir2, "energy_performance_preference"),'w') as
prefs:
+ prefs.write("performance\n")
+
+ # Create AMD P-State configuration
+ pstate_dir = os.path.join(self.testbed.get_root_dir(),
"sys/devices/system/cpu/amd_pstate")
+ os.makedirs(pstate_dir)
+ with open(os.path.join(pstate_dir, "status"),'w') as status:
+ status.write("active\n")
+
+ self.start_daemon()
+
+ profiles = self.get_dbus_property('Profiles')
+ self.assertEqual(len(profiles), 3)
+ self.assertEqual(profiles[0]['Driver'], 'amd_pstate')
+ self.assertEqual(profiles[0]['Profile'], 'power-saver')
+
+ contents = None
+ with open(os.path.join(dir2, "energy_performance_preference"), 'rb') as
f:
+ contents = f.read()
+ self.assertEqual(contents, b'balance_performance')
+
+ # Set performance mode
+ self.set_dbus_property('ActiveProfile',
GLib.Variant.new_string('performance'))
+ self.assertEqual(self.get_dbus_property('ActiveProfile'), 'performance')
+
+ contents = None
+ with open(os.path.join(dir2, "energy_performance_preference"), 'rb') as
f:
+ contents = f.read()
+ self.assertEqual(contents, b'performance')
+
+ self.stop_daemon()
+
+ # Verify that the Lenovo DYTC driver still gets preferred
+ self.create_platform_profile()
+ self.start_daemon()
+
+ profiles = self.get_dbus_property('Profiles')
+ self.assertEqual(len(profiles), 3)
+ self.assertEqual(profiles[0]['Driver'], 'platform_profile')
+
+ def test_amd_pstate_balance(self):
+ '''AMD P-State driver (balance)'''
+
+ # Create CPU with preference
+ dir1 = os.path.join(self.testbed.get_root_dir(),
"sys/devices/system/cpu/cpufreq/policy0/")
+ os.makedirs(dir1)
+ gov_path = os.path.join(dir1, 'scaling_governor')
+ with open(gov_path, 'w') as gov:
+ gov.write('performance\n')
+ with open(os.path.join(dir1, "energy_performance_preference"),'w') as
prefs:
+ prefs.write("performance\n")
+ pstate_dir = os.path.join(self.testbed.get_root_dir(),
"sys/devices/system/cpu/amd_pstate")
+ os.makedirs(pstate_dir)
+ with open(os.path.join(pstate_dir, "status"),'w') as status:
+ status.write("active\n")
+
+ upowerd, obj_upower = self.spawn_server_template(
+ 'upower', {'DaemonVersion': '0.99', 'OnBattery': False},
stdout=subprocess.PIPE)
+
+ self.start_daemon()
+
+ with open(gov_path, 'rb') as f:
+ contents = f.read()
+ self.assertEqual(contents, b'powersave')
+
+ profiles = self.get_dbus_property('Profiles')
+ self.assertEqual(len(profiles), 3)
+ self.assertEqual(profiles[0]['Driver'], 'amd_pstate')
+ self.assertEqual(profiles[0]['Profile'], 'power-saver')
+
+ contents = None
+ with open(os.path.join(dir1, "energy_performance_preference"), 'rb') as
f:
+ contents = f.read()
+ # This matches what's written by ppd-driver-amd-pstate.c
+ self.assertEqual(contents, b'balance_performance')
+
+ self.stop_daemon()
+
+ upowerd.terminate()
+ upowerd.wait()
+ upowerd.stdout.close()
+
+ def test_amd_pstate_error(self):
+ '''AMD P-State driver in error state'''
+
+ pstate_dir = os.path.join(self.testbed.get_root_dir(),
"sys/devices/system/cpu/amd_pstate")
+ os.makedirs(pstate_dir)
+ with open(os.path.join(pstate_dir, "status"),'w') as status:
+ status.write("active\n")
+
+ dir1 = os.path.join(self.testbed.get_root_dir(),
"sys/devices/system/cpu/cpufreq/policy0/")
+ os.makedirs(dir1)
+ with open(os.path.join(dir1, 'scaling_governor'), 'w') as gov:
+ gov.write('powersave\n')
+ pref_path = os.path.join(dir1, "energy_performance_preference")
+ old_umask = os.umask(0o333)
+ with open(pref_path,'w') as prefs:
+ prefs.write("balance_performance\n")
+ os.umask(old_umask)
+ # Make file non-writable to root
+ if os.geteuid() == 0:
+ if not GLib.find_program_in_path('chattr'):
+ os._exit(77)
+ subprocess.check_output(['chattr', '+i', pref_path])
+
+ self.start_daemon()
+
+ self.assertEqual(self.get_dbus_property('ActiveProfile'), 'balanced')
+
+ # Error when setting performance mode
+ with self.assertRaises(gi.repository.GLib.GError):
+ self.set_dbus_property('ActiveProfile',
GLib.Variant.new_string('performance'))
+ self.assertEqual(self.get_dbus_property('ActiveProfile'), 'balanced')
+
+ contents = None
+ with open(os.path.join(dir1, "energy_performance_preference"), 'rb') as
f:
+ contents = f.read()
+ self.assertEqual(contents, b'balance_performance\n')
+
+ self.stop_daemon()
+
+ if os.geteuid() == 0:
+ subprocess.check_output(['chattr', '-i', pref_path])
+
+ def test_amd_pstate_passive(self):
+ '''AMD P-State in passive mode -> placeholder'''
+
+ dir1 = os.path.join(self.testbed.get_root_dir(),
"sys/devices/system/cpu/cpufreq/policy0/")
+ os.makedirs(dir1)
+ with open(os.path.join(dir1, 'scaling_governor'), 'w') as gov:
+ gov.write('powersave\n')
+ with open(os.path.join(dir1, "energy_performance_preference"),'w') as
prefs:
+ prefs.write("performance\n")
+
+ # Create AMD P-State configuration
+ pstate_dir = os.path.join(self.testbed.get_root_dir(),
"sys/devices/system/cpu/amd_pstate")
+ os.makedirs(pstate_dir)
+ with open(os.path.join(pstate_dir, "status"),'w') as status:
+ status.write("passive\n")
+
+ self.start_daemon()
+
+ profiles = self.get_dbus_property('Profiles')
+ self.assertEqual(len(profiles), 2)
+ self.assertEqual(profiles[0]['Driver'], 'placeholder')
+ self.assertEqual(self.get_dbus_property('ActiveProfile'), 'balanced')
+
+ contents = None
+ with open(os.path.join(dir1, "energy_performance_preference"), 'rb') as
f:
+ contents = f.read()
+ self.assertEqual(contents, b'performance\n')
+
+ # Set performance mode
+ self.set_dbus_property('ActiveProfile',
GLib.Variant.new_string('power-saver'))
+ self.assertEqual(self.get_dbus_property('ActiveProfile'), 'power-saver')
+
+ contents = None
+ with open(os.path.join(dir1, "energy_performance_preference"), 'rb') as
f:
+ contents = f.read()
+ self.assertEqual(contents, b'performance\n')
+
+ self.stop_daemon()
+
def test_dytc_performance_driver(self):
'''Lenovo DYTC performance driver'''
@@ -753,19 +937,23 @@
self.assertEqual(profiles[0]['Driver'], 'platform_profile')
self.assertEqual(profiles[0]['Profile'], 'power-saver')
self.assertEqual(self.get_dbus_property('ActiveProfile'), 'balanced')
-
self.assertEqual(self.read_sysfs_file("sys/firmware/acpi/platform_profile"),
b'balanced')
+
self.assertEqual(self.read_sysfs_file("sys/firmware/acpi/platform_profile"),
b'cool')
self.set_dbus_property('ActiveProfile',
GLib.Variant.new_string('power-saver'))
self.assertEqual(self.get_dbus_property('ActiveProfile'), 'power-saver')
self.assertEqual(self.read_sysfs_file("sys/firmware/acpi/platform_profile"),
b'cool')
+ self.set_dbus_property('ActiveProfile',
GLib.Variant.new_string('performance'))
+ self.set_dbus_property('ActiveProfile',
GLib.Variant.new_string('balanced'))
+
self.assertEqual(self.read_sysfs_file("sys/firmware/acpi/platform_profile"),
b'balanced')
+
self.stop_daemon()
def test_quiet(self):
- # Uses cool instead of low-power
+ # Uses quiet instead of low-power
acpi_dir = os.path.join(self.testbed.get_root_dir(),
"sys/firmware/acpi/")
os.makedirs(acpi_dir)
with open(os.path.join(acpi_dir, "platform_profile"),'w') as profile:
- profile.write("cool\n")
+ profile.write("quiet\n")
with open(os.path.join(acpi_dir, "platform_profile_choices"),'w') as
choices:
choices.write("quiet balanced balanced-performance performance\n")