Skip to content

Instantly share code, notes, and snippets.

@m-bartlett
Last active February 12, 2026 20:03
Show Gist options
  • Select an option

  • Save m-bartlett/3a374f42afd504ed67d87cff5124aba4 to your computer and use it in GitHub Desktop.

Select an option

Save m-bartlett/3a374f42afd504ed67d87cff5124aba4 to your computer and use it in GitHub Desktop.
Toggle NVIDIA kernel module entirely without requiring logout. Completely prevent NVIDIA GPU from being used to save power on a laptop.

Hard-toggle NVIDIA kernel module and PCI visibility to enforce dGPU is powered off for power-saving.

Prevent auto-loading of NVIDIA kernel modules at boot

Note

I use this setup on Arch and the instructions are catered for Arch, but this should apply generally to any distro. This also assumes you're using the NVIDIA open kernel modules, on Arch this is the nvidia-open-dkms pacman package.

  1. Add the modprobe config in this gist to /etc/modprobe.d/, you can name it whatever but it's purpose is to prevent NVIDIA modules from being loaded at boot automatically.

Important

Check if you have any files in /usr/lib/modules-load.d/ as these are vendor-provided default configurations. If there are any files here that list nvidia modules, copy the .conf file to /etc/modules-load.d/ and make sure the copy lacks the nvidia module listed. For example, I have a file /usr/lib/modules-load.d/nvidia-utils.conf that lists nvidia-uvm. I created an empty file at /etc/modules-load.d/nvidia-utils.conf to override that default in /usr/lib and further ensure that nvidia-uvm is not loaded at boot.

  1. After adding these system files, run sudo mkinitcpio -P to generate new initramfs images that don't load the nvidia modules.

Dynamically load NVIDIA modules during OS runtime without rebooting

Easiest method is use the included nvpowctl script in this gist, as it handles the proper module load order and extra flags.

The main bit is you'll need to add --ignore-install to your modprobe calls to avoid the module install just running /bin/true. e.g. sudo modprobe --ignore-install nvidia. The modules need to be loaded in a certain order, hence the the nvpowctl script below. This script will also invoke the sysfs endpoints to detach/re-attach the card from the PCI bus visibility, just as further enforcement mechanism to prevent unintended usage.

nvpowctl Usage:

nvpowctl on      # attach NVIDIA PCI binding, load kernel module, load systemd services
nvpowctl off     # detach NVIDIA PCI binding, unload kernel modules, disable systemd services
nvpowctl         # get state of whether enabled or disabled
nvpowctl status  # get detailed information on kernel modules and systemd services
blacklist nouveau
blacklist nvidia
blacklist nvidia-drm
blacklist nvidia-uvm
blacklist nvidia-modeset
blacklist nvidia-wmi-ec-backlight
# Making the install scripts be a no-op prevents auto-loading
install nvidia /bin/true
install nvidia-uvm /bin/true
install nvidia-drm /bin/true
install nvidia-modeset /bin/true
#!/usr/bin/env sh
__prog="$(basename "$0")"
if [ $EUID != 0 ]; then
echo "ERROR: $__prog must be run as root" >&2
exit 1
fi
nvidia_pci_bus_addr=$(lspci -nn | grep NVIDIA | cut -d' ' -f 1)
sysfs_path="/sys/bus/pci/devices/0000:$nvidia_pci_bus_addr"
systemd_units=(
nvidia-powerd
nvidia-persistenced
)
kernel_modules=(
nvidia
nvidia-uvm
nvidia-modeset
nvidia-drm
nvidia-wmi-ec-backlight
)
case $1 in
off)
systemctl disable --now ${systemd_units[@]}
modules_reversed=$(
for ((i=${#kernel_modules[@]}-1; i>=0; i--)); do
echo -n "${kernel_modules[i]} "
done
)
modprobe -rf $modules_reversed
if [[ -n "$nvidia_pci_bus_addr" ]] && [[ -d "$sysfs_path" ]]; then
<<<0 cat > "$sysfs_path/enable"
<<<1 cat > "$sysfs_path/remove"
fi
;;
on)
modprobe --ignore-install ${kernel_modules[@]}
systemctl enable --now ${systemd_units[@]}
<<<1 cat > /sys/bus/pci/rescan
;;
status)
[[ -d "$sysfs_path" ]] && cat "$sysfs_path/power_state"
systemctl status ${systemd_units[@]}
lsmod | grep -i nvidia
;;
'')
if [[ -d "$sysfs_path" ]] && lsmod | grep -qi nvidia
then
echo "enabled"
else
echo "disabled"
fi
;;
*)
echo "Unrecognized option $1" >&2
exit 1
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment