Share your knowledge at the LQ Wiki.
Go Back > Blogs > gegechris99
User Name


Rate this Entry

ACPI configuration to handle AC adapter events in Slackware 14.2

Posted 09-13-2018 at 04:20 PM by gegechris99
Updated 11-13-2018 at 03:38 PM by gegechris99 (Scripts updated with commands cpufreq-info and cpufreq-set)

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/ 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
# Pass all AC adapter events to a dedicated handler script
action=/etc/acpi/ %e
handler file: /etc/acpi/

Edit 13 Nov. 2018: script updated with commands cpufreq-info and cpufreq-set: OLD NEW
# acpi handler for AC adapter events

# 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

set $@

case "$2" in
     case "$4" in
         #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)"
         set_scaling_governor "powersave"
         logger "AC Power not available, setting CPU frequency scaling governor:  $(cpufreq-info --policy | cut -d" " -f3)"
         #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
             #echo "performance" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 1> /dev/null 2> /dev/null
           #logger "AC Power available, setting CPU frequency scaling governor:  $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)"
         if cpufreq-info --governors | grep -q "ondemand"; then
           set_scaling_governor "ondemand"
           set_scaling_governor "performance"
         logger "AC Power available, setting CPU frequency scaling governor:  $(cpufreq-info --policy | cut -d" " -f3)" 
  *) logger "ACPI action undefined: $2"
I then made /etc/acpi/ executable and restarted the acpid2 daemon
chmod +x /etc/acpi/
/etc/rc.d/rc.acpid restart
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
# 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 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
  #  /etc/acpi/ "ac_adapter ACPI0003:00 00000080 00000000"
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.
Posted in Uncategorized
Views 2271 Comments 0
« Prev     Main     Next »
Total Comments 0




All times are GMT -5. The time now is 11:20 PM.

Main Menu
Write for LQ is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration