Skip to content

nvidia: defer NVPCF notifications until runtime resume - #1299

Open
lars76 wants to merge 2 commits into
NVIDIA:mainfrom
lars76:fix-nvpcf-defer-v2
Open

nvidia: defer NVPCF notifications until runtime resume#1299
lars76 wants to merge 2 commits into
NVIDIA:mainfrom
lars76:fix-nvpcf-defer-v2

Conversation

@lars76

@lars76 lars76 commented Aug 16, 2026

Copy link
Copy Markdown

TL;DR

On hybrid laptops, the NVIDIA GPU is powered down while idle. However, the firmware can still send NVPCF notifications:

  • once per 1% of battery discharge on the tested laptop;
  • after a platform-profile change, such as:
sudo sh -c 'echo balanced > /sys/firmware/acpi/platform_profile'
  1. The current driver wakes the NVIDIA GPU for approximately 20–22 seconds just to deliver each notification.
  2. This patch remembers that the power policy changed without waking the GPU. If more notifications arrive, one reminder is enough because the latest policy will be read later.
  3. When the GPU next wakes for actual use, the saved notification is delivered and nvidia-powerd reads the latest power limits.

Projected onto typical one-hour scenarios (derived from the measured per-wake cost, not from separate runtime A/B tests):

Scenario (1 h on battery) Stock driver With this patch
Light use, screen off 93% 94%
Browsing / light work 90% 92%
Video playback 78% 82%
Heavier work 70% 75%

Roughly 20% longer projected battery runtime during normal iGPU-only use.

Problem

On an ASUS GA403UI with an RTX 4070 Laptop GPU, the EC sends Notify(NPCF, 0xC0) for every 1% of battery discharge.

rm_acpi_nvpcf_notify() takes a dynamic-power reference for every notification, waking the GPU even when it is already runtime-suspended.

Each wake keeps the GPU in D0 for approximately 20–22 seconds while the deferred-idle checks complete.

Measured with driver 610.57.04 and Linux 7.1.6:

  • 12 notification-induced wakes during a 90-minute discharge;
  • 5.65% dGPU D0 duty while otherwise idle;
  • 110.4 ± 19.1 mWh consumed per wake;
  • approximately 1.1 W of average overhead in the measured discharge arm.

See also: #860 (same root cause), #905 (NVPCF subset), #1201 (same symptom on two other Zephyrus laptops).

Why the notification must not be dropped

The notification contains no policy data. It tells subscribers such as nvidia-powerd to retrieve the latest policy from the NVPCF _DSM.

With notifications discarded while the GPU was suspended, nvidia-powerd was not told to retrieve a changed profile. After the GPU resumed, it continued using the old 75/55 W limits instead of the new 90/65 W limits. The limits remained stale until another notification arrived.

This is an alternative to the NVPCF portion of #1181. Both approaches prevent the notification-induced wake, but this change preserves delivery of the notification after the GPU resumes.

Scope

This change handles NVPCF only.

A platform-profile change also updates the GPU's temperature target, and the firmware announces that with a second, independent notification on the GPU's ACPI device (ACPI_NOTIFY_GPS_STATUS_CHANGE, handled by RmHandleGPSStatusChange()).

Unlike NVPCF, that notification is consumed by the driver itself rather than by nvidia-powerd, and nothing re-reads the value later if it is missed.

This patch leaves it untouched, so on the tested laptop a profile change still wakes the GPU once. Since it only fires on user actions, the cost is negligible.

#1181 suppresses this notification as well.

How to test (Arch Linux)

git clone --depth 1 --branch fix-nvpcf-defer-v2 https://github.com/lars76/open-gpu-kernel-modules.git
cd open-gpu-kernel-modules
make modules -j$(nproc)
sudo install -Dm644 kernel-open/*.ko -t "/usr/lib/modules/$(uname -r)/updates/nvidia/"
sudo depmod
sudo mkinitcpio -P
reboot

After reboot, verify the patched modules are actually running:

modinfo -F filename nvidia            # expect .../updates/nvidia/nvidia.ko
cat /sys/module/nvidia/srcversion     # must match:
modinfo kernel-open/nvidia.ko | grep srcversion

Then test on battery: unplug at 98% or lower (at 99–100% the battery gauge stalls and the notification does not fire), wait a minute for the unplug wake to settle, and watch

cat /sys/bus/pci/drivers/nvidia/*/power/runtime_active_time

across 2–3% of discharge. Patched: the value stays flat. Stock: it grows by roughly 20,000 ms per 1%. Do not run nvidia-smi or lspci during the window, as both wake the GPU themselves.

Uninstall:

sudo rm -r "/usr/lib/modules/$(uname -r)/updates/nvidia"
sudo depmod && sudo mkinitcpio -P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant