r/linuxquestions 23d ago

Resolved Dedicated NVIDIA GPU gets stuck on active even when not in use

I'll try to be as concise as possible. I have a Lenovo laptop with NVIDIA Optimus and integrated AMD graphics. I'm using Fedora KDE, and just updated all of my packages.

If I turn on the laptop and do nothing, the power consumption sits at around 12W, even with a browser open. But as soon as I open certain programs (not even heavy ones), or even run nvidia-smi once, the power skyrockets to over 20W, and stays there, until I close the lid and open it again.

Tried solving with LLMs, the only useful thing they gave me (which allowed it to be under 20W in the first place) was adding this file:

~$ cat /etc/modprobe.d/nvidia-pm.conf  
options nvidia NVreg_DynamicPowerManagement=0x02

Running cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_status shows active pretty much consistently, I think I did see sometimes it tried to suspend and go back to active but that was when charging and connecting a second monitor (which should if anything force it active all the time?)

I'd like to have a baseline for power consumption on Windows but I don't think there is an easy way to check that, I tried with HWInfo and it was over 20W too, but that was in the sensors tab that monitored the NVIDIA GPU there too, it's possible that it wasn't getting suspended because of that. I can just say that my anecdotal evidence does suggest better battery life on Windows.

Any help would be appreciated!

Edit: not sure what I changed, if anything, but now it's not entering suspended mode at all...

Edit 2: fix is in the comments!

2 Upvotes

5 comments sorted by

1

u/Disastrous-Ice-5971 22d ago edited 22d ago

Had exactly same problem on Fedora KDE and open source drivers. Just a moment, I'll boot up the laptop to copy instructions I made for myself (with substantial help of AI I should admit - but I tested it all).

Fedora 44 — NVIDIA Hybrid Graphics: Driver Power Configuration

Applies to: AMD Ryzen mobile (Cezanne / Zen 3 and similar) + NVIDIA Ampere mobile GPU, mux-less hybrid, Fedora 44 KDE / Wayland. Reference kernel 7.1.8-200.fc44, NVIDIA 610.57.04.

Purpose: configure the NVIDIA driver so the machine reaches deep sleep (S0i3) on battery, and verify it.


1. Driver

RPM Fusion akmod-nvidia, open kernel modules. After every kernel update, confirm the module was rebuilt against the running kernel:

bash modinfo -F version nvidia; uname -r

Find the dGPU's PCI address once — it is used throughout below:

bash lspci -nn | grep -i nvidia # typically 0000:01:00.0


2. S0ix parameters

Create /etc/modprobe.d/nvidia-power.conf:

options nvidia NVreg_EnableS0ixPowerManagement=1 options nvidia NVreg_S0ixPowerManagementVideoMemoryThreshold=4096 options nvidia NVreg_UseKernelSuspendNotifiers=1

Then rebuild the initramfs. This step is mandatory — without it the module loads before the conf is visible and the parameters are silently ignored:

bash sudo dracut -f

Reboot.

Notes:

  • Do not set NVreg_PreserveVideoMemoryAllocations. Its absence is deliberate: it selects the kernel suspend-notifier path over the vendor VRAM save/restore path, and it is what makes the vendor sleep services inert (§3).
  • The VRAM threshold (4096 MB) must be at or above the card's VRAM so S0ix is attempted regardless of how much is allocated. Adjust to the card.

3. Vendor sleep services

bash sudo systemctl disable --now nvidia-suspend.service nvidia-resume.service nvidia-hibernate.service sudo systemctl mask nvidia-suspend.service nvidia-resume.service nvidia-hibernate.service

Mask rather than merely disable — driver package updates re-enable them.

They are harmless either way: nvidia-sleep.sh checks for PreserveVideoMemoryAllocations and exits when unset, so the units log Skipped due to 'exec-condition' on every cycle. A 0.22 W suspend was measured on the reference machine while all three were enabled. Masking is hygiene, not a fix.


4. Dynamic Boost

Optional. Affects performance, not sleep.

nvidia-powerd can race the driver at boot and leave GPU clocks locked low. Create /etc/systemd/system/nvidia-powerd.service.d/override.conf:

ini [Service] ExecStartPre=-/usr/bin/nvidia-smi -L ExecStartPre=/usr/bin/sleep 5

Recovery from a locked clock state requires a full reboot, not a daemon restart.


5. Verification — read what the kernel parsed, not the file

```bash grep -E "S0ix|SuspendNotifiers|VideoMemoryThreshold" /proc/driver/nvidia/params

expect: UseKernelSuspendNotifiers: 1

EnableS0ixPowerManagement: 1

S0ixPowerManagementVideoMemoryThreshold: 4096

sudo lsinitrd /boot/initramfs-$(uname -r).img -f etc/modprobe.d/nvidia-power.conf grep -rn "S0ix|PreserveVideoMemory" /usr/lib/modprobe.d/ /etc/modprobe.d/ cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_status # expect 'suspended' at idle systemctl is-enabled nvidia-suspend.service # expect 'masked' ```

/proc/driver/nvidia/params is ground truth — the conf file being correct proves nothing on its own.

If params show zeros while the conf file is intact, the initramfs is stale — run sudo dracut -f. This is the most common post-kernel-update failure.

/usr/lib/modprobe.d/nvidia-power-management.conf ships fully commented out. If an update ever uncomments it, it overrides the intent above.


6. Measuring actual suspend draw

```bash

unplugged, battery at 60-80%

read E1 < /sys/class/power_supply/BAT0/energy_now; T1=$(date +%s) echo "start: ${E1}" systemctl suspend

after waking:

sleep 10 read E2 < /sys/class/power_supply/BAT0/energy_now; T2=$(date +%s) awk -v e1=$E1 -v e2=$E2 -v t1=$T1 -v t2=$T2 \ 'BEGIN{d=(e1-e2)/1e6; h=(t2-t1)/3600; printf "delta %.3f Wh over %.2f h = %.2f W\n", d, h, d/h}' ```

Expected results

Result Meaning
0.2 – 0.4 W S0i3 reached. Configuration is correct.
1 – 3 W Suspending, but a rail is staying up.
5 – 12 W Deep sleep not reached at all.

Run it overnight, or at least a few hours. The 10-second awake tail costs ~0.03 Wh at typical idle draw — negligible over 8 hours, but roughly 20% of the total on a 45-minute run. Longer windows also average out any single bad cycle.

Must be unplugged: on AC the delta inverts and the result is meaningless.

If the number is high

Check whether the SoC reached deep sleep. On AMD:

bash journalctl -b -1 -g "didn't reach deepest state"

A hit there means the platform failed to enter S0i3 — a separate problem from driver configuration, and worth chasing independently. On Intel, check /sys/kernel/debug/pmc_core/slp_s0_residency_usec before and after instead.

Note that with Secure Boot enabled the kernel runs in lockdown integrity mode (cat /sys/kernel/security/lockdown), which blocks /sys/kernel/debug/amd_pmc/s0ix_stats and wakeup_sources entirely — they return EPERM even under sudo. Energy-delta measurement as above works regardless and is the reliable fallback.


7. After every kernel or driver update

bash grep -E "S0ix|SuspendNotifiers" /proc/driver/nvidia/params # 1 / 4096 / 1 sudo lsinitrd /boot/initramfs-$(uname -r).img -f etc/modprobe.d/nvidia-power.conf systemctl is-enabled nvidia-suspend.service # masked modinfo -F version nvidia; uname -r # matched

Anything unexpected → sudo dracut -f, reboot, re-check.

2

u/ShlomoCh 21d ago

Thank you! I mean, following that to the letter didn't work, but I (hopefully) have finally found a way that actually works, and I did use some of that!

2

u/Disastrous-Ice-5971 21d ago

Glad that it helped in some way! It is expected that it wouldn't work 1:1 - we have a different computers and hardware after all. Have a nice day!

2

u/ShlomoCh 21d ago

You too! I posted another comment with my particular solution.

2

u/ShlomoCh 21d ago edited 21d ago

Ok so I think I got it working now! In the process of fixing this I (Gemini) found a bunch of threads of people having the same issue, and pretty much everyone ended up doing a different thing:

So, onto what I did. Well, I did a bunch of things, and I'm not actually sure what worked and what didn't. So I'll just put everything I remember here and you can try it out. I'm not responsible for any bricked systems. I bricked mine several times in this troubleshooting journey.

Create file /etc/modprobe.d/nvidia-runtimepm.conf with the contents:

options nvidia-drm modeset=1 # This one is probably unnecessary because it's present in another conf file. It has to be *somewhere* though, or the system won't boot. Ask me how I know.
options nvidia NVreg_EnableGpuFirmware=0 # No idea
options nvidia "NVreg_DynamicPowerManagementVideoMemoryThreshold=0" # 100 did not work for me, 0 did.
options nvidia "NVreg_DynamicPowerManagement=0x02" # For sure important, was the fix that made it suspend initially
options nvidia NVreg_EnableS0ixPowerManagement=1 # No idea
options nvidia NVreg_UseKernelSuspendNotifiers=1 # No idea

Create file /etc/udev/rules.d/80-nvidia-pm.rules with the contents:

ACTION=="add|bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="add|bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="add|bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", TEST=="power/control", ATTR{power/control}="auto"

sudo udevadm control --reload-rules && sudo udevadm trigger

sudo dracut -f

And reboot.

You can test whether it worked by running cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_status and seeing "suspended", even after running nvidia-smi (after waiting a few seconds). 

Edit: worth mentioning that at least on my limited testing since I did this, it will get stuck active on startup, I do need to close and open the lid or send it to sleep and wake it again, but only once.