Discussion of improving battery life on AMD Ryzen

I currently run Qubes on a Ryzen 5600u machine. The laptop has a 60Wh battery, which serves around 15 hours of battery life on windows, when I only do slight browsing and moderate text editing.

With QubesOS, if I don’t limit its performance and do the same things as on Windows, it will eat around 15% to 20% of the battery per hour. That’s bearable, but not perfect. I well know that I have to pay the price for advanced security, but more battery life is always better, isn’t it?

So I want to discuss how to extend the battery life, with less impact on performance.

CPU tuning:

For myself, I’m running ryzenadj to control the CPU’s power. I found that limiting it to 2w will make it “just run”, 3w is usable but everything is quite slow, 5w is good enough for smooth typing in Firefox and Onlyoffice, and 7w can provide an experience similar to that of an old machine (x230?).

A low long-term power consumption and high enough peak performance are preferable. I set fast-limit to 7w, slow-limit to 2.5w, slow-time to 30 seconds. So I can run at 7w for around 10 seconds before it hits the boundary and drop to 2.5w (2.5 * 30 / 7=10 + 5/7). That is enough for things like VM starting, or website finishing loading.

Question 1: How about the power requirements of Intel Alder Lake-P/U and AMD 6000u series?

Question 2: Can we increase the scaling speed, for example using xenpm, to make power consumption drop faster when load has been finished? If I don’t set fast-limit, ACPI reported power will go up to ~15w, and decrease slowly after it’s below 8w. If I set fast-limit, it will go up to ~8w, and decrease slowly after it’s below 6w.

Whole system tuning

Through xfce sensor viewer, I find that the whole machine’s idle power consumption is around 5w. Typing in Firefox requires ~6w. Typing in gedit requires ~5.5w. This is good enough for daily usage.

Question 1: I found that battery power drops to around 3.8w for a few seconds after the AC power being removed. Then it gracefully increases to around 5w. Why is there a power valley? If the laptop can run at that power,
why is the idle power never able to reach that?

Edit: Closing keyboard backlight can save ~0.7w. So idle power with the screen on is ~4.2w, with the screen off is ~3.1w. This is definitely good enough, even for a regular linux install.

Question 2: Since Qubes assign different devices to Appvms, should I enable power-savng settings in those Appvms?

AMD recently released amd-pstate CPU Performance Scaling Driver, and Xen is still using the old powernow! driver.

According to #4604, Xen takes over CPU scaling affairs from dom0-kernel by default. I enabled CPPC in the BIOS, but lscpu still showed that my CPU didn’t support CPPC. And kernel-based CPU scaling is less efficient than Xen-based, which might results from the fact that there’s no amd-pstate driver in kernel-latest. Also, I cannot modprobe acpi-cpufreq driver.

In #4604, I saw that Xen had had intel-pstate driver support years ago. We should make our way to migrate amd-pstate into Xen.

Here with sched_smt_power_savings=true xen boot parameter, I indeed witnessed slight idle power saving. But this does have a visible impact on performance, more precisely, VM boot time.

I found that when using ryzenadj, the best setting for me is to only set fast-limit to 3000mW, which is enough for smooth typing and decent web browsing. The whole machine’s average power consumption is around 7000mW, so more than 7hr of screen time is expected.

The reason that I don’t tamper with slow-limit is that when the average power consumption exceeds slow-limit in the past slow-time seconds, restrictions are made to pull avg power down, and for Zen3 Ryzen mobile processors, based on my testing, less than 2500mW can lead to a significant performance decrease. So these restrictions can lead to unwanted sensitive “performance valley”.

1 Like

The title has been a little misleading for me after reading the posts.
Nevertheless, I believe someone might find this tip useful:

How to reduce the battery max charge capacity (and thus improve it’s life) without installing third-party tools such as TLP in Dom0:
Please run this in Dom0:

sudo bash -c "echo 90 > /sys/class/power_supply/BAT0/charge_stop_threshold"
sudo bash -c "echo 90 > /sys/class/power_supply/BAT1/charge_stop_threshold"

To make Xen utilize deeper C-states of my CPU to reduce power consumption, I tried to make Xen use acpi-cpufreq driver on my AMD cpu. No further modification of Xen source code is required to make it run well, but xenpm cannot get cpufreq para. However, cpufreq states are correctly reported.

The result is somewhat neutral: Subjectively, I think the performance response and power drainage are close to those using powernow. But just like powernow, acpi-cpufreq cannot detect and utilize C4-C6 states on my CPU. I’ll see why.

How do you set acpi-cpufreq instead of powernow?
xenpm get-cpufreq-states may be inaccurate. It shows a minimum frequency of 1.6GHz for my CPU and a max of 2.0GHz(the base frequency.) This lead me to believe that in addition to the lack of lower frequencies when idle, it also lacks turboboost in Qubes. However when I run xenpm start 1 it does report frequencies up to 4GHz under load. (Note that it does not report below 1.6GHz idle, so the lack of lower frequencies seems to be true.)

I compiled a custom Xen. At xen/arch/x86/acpi/cpufreq/cpufreq.c, there are lines of code that decide which driver to use based on your CPU manufacturer.

You are right. But in my case, it just failed to get cpufreq para for all of my cores.

You may want to check out my newly reported issue:

1 Like