System slow on battery power

I’ve used my laptop with Fedora 39/40 for almost a year, and I’ve been experiencing a very slow system on battery power since 2 or 3 months ago.

The issue seems somewhat confirmed by observing the CPU frequency reported by btop while running sysbench --threads=12 cpu run. When plugged in, the reported frequency is 3.8 GHz, whilst on battery power it seems capped at 2.2 GHz.

Plugged in Battery power
btop-plugged-in btop-battery-power

Additional info

  • I tried booting into a live Fedora running from a USB stick, and I don’t see the CPU frequency being capped at 2.2 GHz in btop when running the same sysbench command as above.
  • I only experience this problem on this laptop — I have another Fedora laptop and things run just fine on battery power.

Configuration

  • I’m running Fedora 40 Workstation now, with vanilla GNOME.
  • The power-profiles-daemon service is enabled, and the “Power Mode” in GNOME is normally set to “Balanced”.
  • I might have installed TLP at some point in the past, but now it’s not installed.

System specs

  • Lenovo ThinkPad X1 Carbon Gen 11
  • CPU: 12-core Intel i7-1355U
  • No discrete GPU
  • Memory: 16 GiB

This looks like a configuration issue, since the live Fedora runs just fine, right? How can I further debug the problem? Many thanks in advance.

Added f40 and removed f39

What is the profile used for “Battery”?

Added power-management

What profile do you mean? You can set a “Power mode” in GNOME, but I don’t think I see any mention of a “profile”.

What you can do is check if the CPU frequency profile switches between being on battery and on cord, and perhaps also the maximum frequency. A handy tool for this is cpupower.

For example on my system:

$ sudo dnf install kernel-tools
$ cpupower frequency-info

analyzing CPU 4:
  driver: amd-pstate-epp
  CPUs which run at the same hardware frequency: 4
  CPUs which need to have their frequency coordinated by software: 4
  maximum transition latency:  Cannot determine or is not supported.
  hardware limits: 400 MHz - 4.58 GHz
  available cpufreq governors: performance powersave
  current policy: frequency should be within 400 MHz and 4.58 GHz.
                  The governor "powersave" may decide which speed to use
                  within this range.
  current CPU frequency: Unable to call hardware
  current CPU frequency: 2.31 GHz (asserted by call to kernel)
  boost state support:
    Supported: yes
    Active: yes
    AMD PSTATE Highest Performance: 166. Maximum Frequency: 4.58 GHz.
    AMD PSTATE Nominal Performance: 105. Nominal Frequency: 2.90 GHz.
    AMD PSTATE Lowest Non-linear Performance: 40. Lowest Non-linear Frequency: 1.10 GHz.
    AMD PSTATE Lowest Performance: 15. Lowest Frequency: 400 MHz.

You can also use this tool to manually set a CPU profile or frequency using these parameters:

$ cpupower frequency-set -
-d          -f          --freq      -g          --governor  --max       --min       -r          --related   -u  

The output of cpupower frequency-info is basically the same when I’m on battery and when I’m plugged in (except for the current frequency, which is dynamic). This is what it looks like both on battery and when plugged in:

analyzing CPU 4:
  driver: intel_pstate
  CPUs which run at the same hardware frequency: 4
  CPUs which need to have their frequency coordinated by software: 4
  maximum transition latency:  Cannot determine or is not supported.
  hardware limits: 400 MHz - 3.70 GHz
  available cpufreq governors: performance powersave
  current policy: frequency should be within 400 MHz and 3.70 GHz.
                  The governor "powersave" may decide which speed to use
                  within this range.
  current CPU frequency: Unable to call hardware
  current CPU frequency: 1.10 GHz (asserted by call to kernel)
  boost state support:
    Supported: yes
    Active: yes

I also see that /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor shows powersave for all cores, again both on battery and when plugged in. As I understand from this ArchWiki page, this is a profile where the CPU autonomously decides its frequency from the allowed range.

I understand that I can manually set the CPU profile via cpupower, but I guess that’s not the issue here, since I see the same profile on battery and when plugged in, right?

It could be interesting to test if you can raise the frequency above 2.2 Ghz manually on battery? Perhaps you need to use the Performance governor for that, i’m not sure.

Sorry I do not use Gnome so do not know what they call it.
In power management there are seperate settings for

  1. AC Power Connected
  2. Battery
  3. Low Battery

Make sure that you have all 3 set the way you want.

When switching the governor to performance, I do see the CPU frequency reported by btop going up to 4.7 GHz. I also observe this behavior if I set the GNOME “Power mode” to "Performance. When I set the governor back to powersave, things are like before: 3.8 GHz when plugged in, and 2.2 GHz on battery.

Right, it could be buggy behaviour from the intel_pstate kernel driver in that case.

It might be interesting to check if there is perhaps an existing upstream bug report at bugzilla.kernel.org for this issue.

Hmm right. I do see a report on Bugzilla that looks related: 218492 – poor CPU performance due to wrong frequency scaling. Disabling intel_pstate via a kernel command line option seems to remove any CPU frequency restrictions, but I imagine at the expense of battery duration. I’ll post a comment on that bug report.

Thanks for your help!

intel_pstate is a newer driver, the equivalent is amd_pstate for AMD cpus. What these drivers do is dynamically change the cpu profile based on a specified performance target and the current circumstances (power draw, sysload etc). This is the ideal approach but since it’s still relatively new they can sometimes make the wrong decisions.

When you disable pstate the system should fall back to the ‘old’ cpu driver which is acpi_cpufreq. This uses a simpler approach based on a single frequency curve, e.g. performance or ondemand. So you will still have frequency scaling in this scenario, but a bit more simple and not auto-adaptive like with the pstate approach.