ACPI configuration to handle AC adapter events in Slackware 14.2
Posted 09-13-2018 at 03:20 PM by gegechris99
Updated 11-13-2018 at 02:38 PM by gegechris99 (Scripts updated with commands cpufreq-info and cpufreq-set)
Updated 11-13-2018 at 02:38 PM by gegechris99 (Scripts updated with commands cpufreq-info and cpufreq-set)
Tags acpi, configuration, slackware
LQ thread Suggestion-use-performance-cpu-frequency-governor discusses which scaling governor would be most appropriate for Intel CPU using the intel_pstate scaling driver as those CPU only have the powersave and the performance governors.
Irrespective of the merit or not of changing the default scaling governor in Slackware for such CPU, at one point, the question of how to implement a change came up. In post #71, user abga made an implementation proposal that required changes to upstream scripts.
Building upon abga's proposal, I gave my own approach that had the benefit of not changing any upstream script (post #92). My proposal took advantage of the flexibility of the acpid2 daemon that is in charge of delivering ACPI events.
This blog entry documents my approach to manage the use case presented in post #71 and, in doing so, it showcases the flexibility of the acpid2 daemon.
Use case:
If CPU uses the intel_pstate scaling driver, then:
when AC adapter is plugged in, switch to performance governor
when AC adpater is unplugged, switch to powersave governor
My reference is this Arch wiki entry: ACPI Alternative configuration
In a nutshell, the acpid2 daemon catches an ACPI event and executes a program to handle this event.
The default handler file (/etc/acpi/acpi_handler.sh) doesn't do much but you can direct a specific event or set of events to its own handler program. You just need to create an event file and an associated handler script.
For my use case, I created (as root) the following files:
event file: /etc/acpi/events/ac_adapter_events
handler file: /etc/acpi/ac_adapter_handler.sh
Edit 13 Nov. 2018: script updated with commands cpufreq-info and cpufreq-set: OLD NEW
I then made /etc/acpi/ac_adapter_handler.sh executable and restarted the acpid2 daemon
This approach works when I unplug/plug in the AC adapter on a running Slackware64 14.2. However, at boot time, the default scaling governor is selected (powersave in case of a CPU using intel_pstate) as the acpid2 daemon is not started early enough.
To select the governor according to the AC adapter state at boot time, I suggest to add some code in script /etc/rc.d/rc.local
Edit 13 Nov. 2018: script updated with command cpufreq-info : OLD NEW
This bit of code in /etc/rc.d/rc.local is not part of the acpid2 configuration that I wanted to showcase but it enables me to fully cover my use case.
Hope this helps.
Irrespective of the merit or not of changing the default scaling governor in Slackware for such CPU, at one point, the question of how to implement a change came up. In post #71, user abga made an implementation proposal that required changes to upstream scripts.
Building upon abga's proposal, I gave my own approach that had the benefit of not changing any upstream script (post #92). My proposal took advantage of the flexibility of the acpid2 daemon that is in charge of delivering ACPI events.
This blog entry documents my approach to manage the use case presented in post #71 and, in doing so, it showcases the flexibility of the acpid2 daemon.
Use case:
If CPU uses the intel_pstate scaling driver, then:
when AC adapter is plugged in, switch to performance governor
when AC adpater is unplugged, switch to powersave governor
My reference is this Arch wiki entry: ACPI Alternative configuration
In a nutshell, the acpid2 daemon catches an ACPI event and executes a program to handle this event.
The default handler file (/etc/acpi/acpi_handler.sh) doesn't do much but you can direct a specific event or set of events to its own handler program. You just need to create an event file and an associated handler script.
For my use case, I created (as root) the following files:
event file: /etc/acpi/events/ac_adapter_events
Code:
# Pass all AC adapter events to a dedicated handler script event=ac_adapter* action=/etc/acpi/ac_adapter_handler.sh %e
Edit 13 Nov. 2018: script updated with commands cpufreq-info and cpufreq-set: OLD NEW
Code:
#!/bin/sh # acpi handler for AC adapter events # Set scaling governor set_scaling_governor() { MAX_CPU=$((`nproc --all` - 1)) for i in $(seq 0 $MAX_CPU); do cpufreq-set --cpu $i --governor $1 1> /dev/null 2> /dev/null done } IFS=${IFS}/ set $@ case "$2" in AC*|AD*) case "$4" in 00000000) #if [ -r /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ]; then #echo "powersave" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 1> /dev/null 2> /dev/null #logger "AC Power not available, setting CPU frequency scaling governor: $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)" #fi set_scaling_governor "powersave" logger "AC Power not available, setting CPU frequency scaling governor: $(cpufreq-info --policy | cut -d" " -f3)" ;; 00000001) #if [ -r /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ]; then #if grep -q "ondemand" /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors; then #echo "ondemand" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 1> /dev/null 2> /dev/null #else #echo "performance" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 1> /dev/null 2> /dev/null #fi #logger "AC Power available, setting CPU frequency scaling governor: $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)" #fi if cpufreq-info --governors | grep -q "ondemand"; then set_scaling_governor "ondemand" else set_scaling_governor "performance" fi logger "AC Power available, setting CPU frequency scaling governor: $(cpufreq-info --policy | cut -d" " -f3)" ;; esac ;; *) logger "ACPI action undefined: $2" ;; esac
Code:
chmod +x /etc/acpi/ac_adapter_handler.sh /etc/rc.d/rc.acpid restart
To select the governor according to the AC adapter state at boot time, I suggest to add some code in script /etc/rc.d/rc.local
Edit 13 Nov. 2018: script updated with command cpufreq-info : OLD NEW
Code:
# Manage scaling governor at boot time only for CPU that uses intel_pstate: # - if AC adapter is plugged in, select the performance governor # - if AC adapter is unplugged, we keep the default powersave governor # #if [ "$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver)" = "intel_pstate" ]; then if [ "$(cpufreq-info --driver)" = "intel_pstate" ]; then # Get AC adapter state at boot time AC_ADP_STATE=$(dmesg | \ grep -m 1 "AC Adapter" | \ awk -F "(" '{ print substr($2,1,length($2)-1) }') if [ "$AC_ADP_STATE" = "on-line" ]; then /etc/acpi/ac_adapter_handler.sh "ac_adapter ACPI0003:00 00000080 00000001" echo "Changing scaling governor to performance" # # No need to manage off-line status as script /etc/rc.d/rc.cpufreq defines # powersave as the default governor for CPU using intel_pstate # #else # /etc/acpi/ac_adapter_handler.sh "ac_adapter ACPI0003:00 00000080 00000000" fi fi
Hope this helps.
Total Comments 0