Tối ưu hóa quản lý điện năng trên Fedora Workstation với power-profiles-daemon và tuned

Fedora tutorial - IT technology blog
Fedora tutorial - IT technology blog

Pin cạn lúc 3 giờ chiều — vấn đề thật với laptop developer

Mình dùng Fedora làm máy development chính đã 2 năm và khá hài lòng với tốc độ cập nhật package, nhưng có một thứ mất khá nhiều thời gian để tune đúng: quản lý điện năng. Máy ThinkPad X1 Carbon của mình ban đầu chỉ trụ được 4-5 tiếng khi compile code liên tục. Sau khi hiểu rõ cách power-profiles-daemontuned phối hợp với nhau, mình đẩy được lên 7-8 tiếng trong điều kiện làm việc thực tế.

Fedora 39+ đã tích hợp sẵn power-profiles-daemon theo mặc định — đây là daemon của GNOME/freedesktop, khác hoàn toàn với TLP mà Ubuntu hay dùng. Còn tuned là công cụ tuning cấp thấp hơn, do Red Hat phát triển, kiểm soát trực tiếp từ CPU governor đến disk scheduler. Hai thứ này không thay thế nhau — cấu hình đúng thì chúng bổ sung cho nhau rất tốt.

Tại sao cần cả hai thay vì chỉ một?

power-profiles-daemon hoạt động ở tầng cao: nó expose 3 profile (power-saver, balanced, performance) qua D-Bus, GNOME Shell đọc và hiển thị trong system tray. Khi bạn chọn profile, daemon này gọi xuống các driver như amd-pstate hoặc intel_pstate để điều chỉnh EPP (Energy Performance Preference).

tuned thì sâu hơn: nó kiểm soát CPU governor, IRQ affinity, disk I/O scheduler, network latency, thậm chí cả kernel parameters qua sysctl. Profile balanced của tuned và profile balanced của power-profiles-daemon là hai thứ khác nhau hoàn toàn.

Rắc rối mình gặp là tuned mặc định hay override CPU governor, xung đột trực tiếp với power-profiles-daemon. Mất khoảng 3 buổi tối ngồi đọc source code và thử từng option, nhưng cuối cùng mình tìm được cách để hai cái này sống chung hòa bình.

Cài đặt và kiểm tra trạng thái ban đầu

Trên Fedora 39+, power-profiles-daemon đã cài sẵn. Kiểm tra nhanh:

# Kiểm tra daemon đang chạy không
systemctl status power-profiles-daemon

# Xem profile hiện tại
powerprofilesctl

# Output mẫu:
# * balanced:
#     Driver:     amd-pstate-epp (hoặc intel_pstate)
#     Degraded:   no
#
#   power-saver:
#     ...
#   performance:
#     ...

Cài tuned nếu chưa có:

sudo dnf install tuned tuned-utils tuned-gtk -y
sudo systemctl enable --now tuned

# Kiểm tra profile đang active
tuned-adm active

# Xem toàn bộ profile available
tuned-adm list

Trước khi làm gì tiếp, xem hai thứ này có đang xung đột nhau không:

# Xem CPU governor hiện tại
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

# Nếu ra "powersave" — power-profiles-daemon đang kiểm soát (đúng)
# Nếu ra "schedutil" hoặc "ondemand" — có thể tuned đang override

Cấu hình chi tiết để tránh conflict

Bước 1: Chọn tuned profile phù hợp không override CPU governor

Nguyên nhân gốc rễ: một số tuned profile mặc định set CPU governor, đụng thẳng vào power-profiles-daemon. Cách xử lý là dùng profile balanced của tuned nhưng tạo custom sub-profile để tắt phần CPU governor:

sudo mkdir -p /etc/tuned/fedora-dev
sudo nano /etc/tuned/fedora-dev/tuned.conf

Nội dung file:

[main]
summary=Fedora Developer Profile — no CPU governor override
include=balanced

[cpu]
# Không set governor — để power-profiles-daemon quản lý
# governor=
energy_perf_bias=normal
min_perf_pct=10

[disk]
apm=128
spindown=0
alpm=min_power

[sysctl]
vm.swappiness=10
vm.dirty_ratio=15
vm.dirty_background_ratio=5
kernel.nmi_watchdog=0

[usb]
autosuspend=1


timeout=10

Kích hoạt profile mới:

sudo tuned-adm profile fedora-dev

# Verify không có warning
tuned-adm verify

Bước 2: Tạo udev rule để tự động switch power profile khi cắm/rút sạc

Đây là phần mình thấy hữu dụng nhất. GNOME tự switch profile khi AC/battery thay đổi, nhưng nếu bạn dùng môi trường desktop khác hoặc muốn kiểm soát rõ hơn:

sudo nano /etc/udev/rules.d/81-power-profile.rules
# Switch sang power-saver khi rút sạc
SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="/usr/bin/powerprofilesctl set power-saver"

# Switch về balanced khi cắm sạc
SUBSYSTEM=="power_supply", ATTR{online}=="1", RUN+="/usr/bin/powerprofilesctl set balanced"
sudo udevadm control --reload-rules

Bước 3: Cấu hình profile performance cho lúc compile nặng

Mình hay cần build Docker image hoặc compile Rust project tốn 15-20 phút. Tạo alias để switch nhanh:

# Thêm vào ~/.bashrc hoặc ~/.zshrc
alias perf-on="powerprofilesctl set performance && echo 'Performance mode ON'"
alias perf-off="powerprofilesctl set balanced && echo 'Balanced mode restored'"
alias bat-mode="powerprofilesctl set power-saver && echo 'Battery saver ON'"

# Hoặc dùng script kết hợp với lệnh build
build-heavy() {
    powerprofilesctl set performance
    "$@"
    powerprofilesctl set balanced
}

Trong thực tế mình hay dùng thế này:

# Build xong tự switch về balanced
build-heavy cargo build --release
build-heavy docker build -t myapp .

Kiểm tra và theo dõi mức tiêu thụ điện

Xem mức tiêu thụ điện real-time

# Cài powertop nếu chưa có
sudo dnf install powertop -y

# Chạy với quyền root để xem đủ thông tin
sudo powertop

# Export HTML report để xem chi tiết
sudo powertop --html=/tmp/power-report.html

Trong output của powertop, cột quan trọng nhất là Power est. — mình thường nhắm dưới 8W khi idle ở power-saver mode, và dưới 12W khi balanced với một số tab Chrome mở.

Theo dõi CPU frequency và EPP

# Xem tần số CPU hiện tại của tất cả core
watch -n1 'cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq | sort -n'

# Xem EPP (Energy Performance Preference) — chỉ có với amd-pstate/intel_pstate
cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference

# power-saver → "power"
# balanced    → "balance_power"
# performance → "performance"

Script monitor tổng hợp

#!/bin/bash
# ~/bin/power-status.sh

echo "=== Power Profile ==="
powerprofilesctl | grep -A1 '\*'

echo ""
echo "=== tuned Profile ==="
tuned-adm active

echo ""
echo "=== CPU Governor ==="
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

echo ""
echo "=== EPP ==="
cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference 2>/dev/null || echo "Not supported"

echo ""
echo "=== Battery Status ==="
upower -i /org/freedesktop/UPower/devices/battery_BAT0 2>/dev/null | grep -E 'state|percentage|energy-rate'

echo ""
echo "=== Current Power Draw ==="
cat /sys/class/power_supply/BAT0/power_now 2>/dev/null | awk '{printf "%.2f W\n", $1/1000000}' || echo "Check /sys/class/power_supply/"
chmod +x ~/bin/power-status.sh
power-status.sh

Điều chỉnh nếu vẫn tốn điện

Sau khi cấu hình xong mà pin vẫn cạn nhanh, chạy powertop --auto-tune một lần để xem có thiết bị nào chưa enable autosuspend không:

# Chỉ nên chạy để xem gợi ý, không nên để permanent vì một số setting có thể gây issue
sudo powertop --auto-tune

# Xem tab "Tunables" trong powertop interactive mode
# Các item "Bad" là những thứ có thể tối ưu thêm

Một điều mình học được sau 6 tháng dùng setup này: đừng enable tất cả auto-tune cùng lúc. Mình từng bị USB mouse lag vì autosuspend quá aggressive. Enable từng cái, test 1-2 ngày, rồi mới tiếp tục cái kế tiếp — chậm nhưng chắc.

Kết quả thực tế sau 6 tháng

Với setup trên (tuned profile fedora-dev + udev rule tự switch + alias cho performance mode), máy ThinkPad X1 Carbon Gen 11 của mình đạt được:

  • Idle với vài terminal + browser: ~5W, pin trụ 9-10 tiếng
  • Làm việc bình thường (code, Slack, email): ~8-10W, trụ 6-7 tiếng
  • Compile nặng ở performance mode: ~25-30W nhưng xong nhanh hơn 40% so với balanced

So với lúc chưa cấu hình gì, pin tăng thêm khoảng 2-3 tiếng — đủ để mình không cần mang theo sạc khi ra ngoài làm cả ngày.

Share: