Skip to content

Commit

Permalink
Merge pull request #616 from superm1/superm1/battery-detection
Browse files Browse the repository at this point in the history
tuned-ppd: Detect battery change events
  • Loading branch information
yarda authored May 23, 2024
2 parents 40f1507 + 6ef5b58 commit d4399b8
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 1 deletion.
10 changes: 10 additions & 0 deletions profiles/balanced-battery/tuned.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#
# tuned configuration
#

[main]
summary=Balanced profile biased towards power savings changes for battery
include=balanced

[cpu]
energy_performance_preference=balance_power
24 changes: 24 additions & 0 deletions tuned/ppd/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@

MAIN_SECTION = "main"
PROFILES_SECTION = "profiles"
BATTERY_SECTION = "battery"
DEFAULT_PROFILE_OPTION = "default"
BATTERY_DETECTION_OPTION = "battery_detection"


class PPDConfig:
def __init__(self, config_file):
self.load_from_file(config_file)

@property
def battery_detection(self):
return self._battery_detection

@property
def default_profile(self):
return self._default_profile
Expand All @@ -26,6 +32,10 @@ def ppd_to_tuned(self):
def tuned_to_ppd(self):
return self._tuned_to_ppd

@property
def ppd_to_tuned_battery(self):
return self._ppd_to_tuned_battery

def load_from_file(self, config_file):
cfg = ConfigParser()

Expand Down Expand Up @@ -59,3 +69,17 @@ def load_from_file(self, config_file):
self._default_profile = cfg[MAIN_SECTION][DEFAULT_PROFILE_OPTION]
if self._default_profile not in self._ppd_to_tuned:
raise TunedException("Unknown default profile '%s'" % self._default_profile)

if BATTERY_DETECTION_OPTION not in cfg[MAIN_SECTION]:
raise TunedException("Missing battery detection option in the configuration file '%s'" % config_file)
self._ppd_to_tuned_battery = self._ppd_to_tuned
self._battery_detection = cfg.getboolean(MAIN_SECTION, BATTERY_DETECTION_OPTION)
if self._battery_detection:
if BATTERY_SECTION not in cfg:
raise TunedException("Missing battery section in the configuration file '%s'" % config_file)
for k, _v in dict(cfg[PROFILES_SECTION]).items():
if k in cfg[BATTERY_SECTION].keys():
self._tuned_to_ppd = self._tuned_to_ppd | {cfg[BATTERY_SECTION][k]:k}
for k, v in dict(cfg[BATTERY_SECTION]).items():
if k in cfg[PROFILES_SECTION].keys():
self._ppd_to_tuned_battery = self._ppd_to_tuned_battery | {k:v}
24 changes: 23 additions & 1 deletion tuned/ppd/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
NO_TURBO_PATH = "/sys/devices/system/cpu/intel_pstate/no_turbo"
LAP_MODE_PATH = "/sys/bus/platform/devices/thinkpad_acpi/dytc_lapmode"

UPOWER_DBUS_NAME = "org.freedesktop.UPower"
UPOWER_DBUS_PATH = "/org/freedesktop/UPower"
UPOWER_DBUS_INTERFACE = "org.freedesktop.UPower"

class PerformanceDegraded(StrEnum):
NONE = ""
Expand Down Expand Up @@ -101,8 +104,25 @@ def __init__(self, bus, tuned_interface):
self._performance_degraded = PerformanceDegraded.NONE
self._cmd = commands()
self._terminate = threading.Event()
self._on_battery = False
self.load_config()

def upower_changed(self, interface, changed, invalidated):
properties = dbus.Interface(self.proxy, dbus.PROPERTIES_IFACE)
self._on_battery = bool(properties.Get(UPOWER_DBUS_INTERFACE, "OnBattery"))
tuned_profile = self._config.ppd_to_tuned_battery[self._base_profile] if self._on_battery else self._config.ppd_to_tuned[self._base_profile]
log.info("Switching to profile '%s' due to battery %s" % (tuned_profile, self._on_battery))
self._tuned_interface.switch_profile(tuned_profile)

def setup_battery_signaling(self):
try:
bus = dbus.SystemBus()
self.proxy = bus.get_object(UPOWER_DBUS_NAME, UPOWER_DBUS_PATH)
self.proxy.connect_to_signal("PropertiesChanged", self.upower_changed)
self.upower_changed(None, None, None)
except dbus.exceptions.DBusException as error:
log.debug(error)

def _check_performance_degraded(self):
performance_degraded = PerformanceDegraded.NONE
if os.path.exists(NO_TURBO_PATH):
Expand Down Expand Up @@ -137,11 +157,13 @@ def load_config(self):
self._config = PPDConfig(PPD_CONFIG_FILE)
self._base_profile = self._config.default_profile
self.switch_profile(self._config.default_profile)
if self._config.battery_detection:
self.setup_battery_signaling()

def switch_profile(self, profile):
if self.active_profile() == profile:
return
tuned_profile = self._config.ppd_to_tuned[profile]
tuned_profile = self._config.ppd_to_tuned_battery[profile] if self._on_battery else self._config.ppd_to_tuned[profile]
log.info("Switching to profile '%s'" % tuned_profile)
self._tuned_interface.switch_profile(tuned_profile)
exports.property_changed("ActiveProfile", profile)
Expand Down
5 changes: 5 additions & 0 deletions tuned/ppd/ppd.conf
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
[main]
# The default PPD profile
default=balanced
battery_detection=true

[profiles]
# PPD = TuneD
power-saver=powersave
balanced=balanced
performance=throughput-performance

[battery]
# PPD = TuneD
balanced=balanced-battery

0 comments on commit d4399b8

Please sign in to comment.