Nvidia
Table of Contents
1. Arch Linux Current Setup
- Install `nvidia' and `nvidia-lts'
- Install `nvidia-prime'
- Mkinitcpio
- /etc/X11/xorg.conf
- Done
< Collapse code block
Section "Device" Identifier "iGPU" Driver "intel" EndSection Section "Screen" Identifier "iGPU" Device "iGPU" EndSection Section "Device" Identifier "dGPU" Driver "nvidia" EndSection
This allows me to use CUDA and PRIME (e.g. prime-run unigine-heaven) but has the following cons:
- laptop battery is used more
- resuming from suspend doesn't work
So, I blacklist the nvidia
drivers and comment out nvidia device from xorg config. Then only when needed remove the comments and , restart xorg (systemctl restart display-manager).
/etc/X11/xorg.conf
< Collapse code block
Section "Device" Identifier "iGPU" Driver "intel" EndSection Section "Screen" Identifier "iGPU" Device "iGPU" EndSection #Section "Device" # Identifier "dGPU" # Driver "nvidia" #EndSection
/etc/modprobe.d/blacklist.conf
< Collapse code block
# nvidia uses a lot of cpu blacklist nvidia blacklist nvidia-drm blacklist nvidia-modeset blacklist nvidia-uvm blacklist nouveau
1.1. nvidia-xrun
< Collapse code block
#!/usr/bin/env bash DRY_RUN=0 function printHelp { echo "Utility to run games and applications in separate X on discrete Nvidia graphic card" echo "Usage: " echo "nvidia-xrun [<options>] [<app>]" echo "Options: " echo " -d Dry run - prints the final command but does not execute it" } function execute { if [[ ${DRY_RUN} -eq 1 ]] then echo ">>Dry run. Command: $*" else eval $* fi } function turn_off_gpu { if [[ "$REMOVE_DEVICE" == '1' ]]; then echo 'Removing Nvidia bus from the kernel' execute "sudo tee /sys/bus/pci/devices/${DEVICE_BUS_ID}/remove <<<1" execute "sudo tee /sys/bus/pci/devices/0000:01:00.1/remove <<<1" else echo 'Enabling powersave for the graphic card' execute "sudo tee /sys/bus/pci/devices/${DEVICE_BUS_ID}/power/control <<<auto" fi echo 'Enabling powersave for the PCIe controller' execute "sudo tee /sys/bus/pci/devices/${CONTROLLER_BUS_ID}/power/control <<<auto" } function turn_on_gpu { echo 'Turning the PCIe controller on to allow card rescan' execute "sudo tee /sys/bus/pci/devices/${CONTROLLER_BUS_ID}/power/control <<<on" echo 'Waiting 1 second' execute "sleep 1" if [[ ! -d /sys/bus/pci/devices/${DEVICE_BUS_ID} ]]; then echo 'Rescanning PCI devices' execute "sudo tee /sys/bus/pci/rescan <<<1" echo "Waiting ${BUS_RESCAN_WAIT_SEC} second for rescan" execute "sleep ${BUS_RESCAN_WAIT_SEC}" fi echo 'Turning the card on' execute "sudo tee /sys/bus/pci/devices/${DEVICE_BUS_ID}/power/control <<<on" } function load_modules { for module in "${MODULES_LOAD[@]}" do echo "Loading module ${module}" execute "sudo modprobe ${module}" done } function unload_modules { for module in "${MODULES_UNLOAD[@]}" do echo "Unloading module ${module}" execute "sudo modprobe -r ${module}" done } if [[ "$1" == "-d" ]] then DRY_RUN=1 shift 1 fi # load config file . /etc/default/nvidia-xrun # this is used by the systemd service to turn off the gpu at boot if [[ "$TURN_OFF_GPU_ONLY" == '1' ]]; then turn_off_gpu && exit 0 fi if [[ $EUID -eq 0 ]]; then echo "This script must not be run as root unless TURN_OFF_GPU_ONLY=1 is set" >&2 exit 1 fi # calculate current VT LVT=`fgconsole` # calculate first usable display XNUM="-1" SOCK="something" while [[ ! -z "$SOCK" ]] do XNUM=$(( $XNUM + 1 )) SOCK=$(ls -A -1 /tmp/.X11-unix | grep "X$XNUM" ) done NEWDISP=":$XNUM" if [[ ! -z "$*" ]] # generate exec line if arguments are given then # test if executable exists in path if [[ -x "$(which $1 2> /dev/null)" ]] then # generate exec line EXECL="$(which $1)" # test if executable exists on disk elif [[ -e "$(realpath "$1")" ]] then # generate exec line EXECL="$(realpath "$1")" else echo "$1: No such executable!" exit 1 fi shift 1 EXECL="$EXECL $*" else # prepare to start new X sessions if no arguments passed EXECL="" fi EXECL="/etc/X11/xinit/nvidia-xinitrc \"$EXECL\"" COMMAND="xinit $EXECL -- $NEWDISP vt$LVT -nolisten tcp -br -config nvidia-xorg.conf -configdir nvidia-xorg.conf.d" # --------- TURNING ON GPU ----------- if [[ "$ENABLE_PM" == '1' ]]; then turn_on_gpu fi # ---------- LOADING MODULES ---------- load_modules # ---------- EXECUTING COMMAND -------- execute ${COMMAND} # ---------- UNLOADING MODULES -------- unload_modules # --------- TURNING OFF GPU ---------- if [[ "$ENABLE_PM" == '1' ]]; then turn_off_gpu fi
1.2. DRM kernel mode setting
nvidia 364.16 adds support for DRM (Direct Rendering Manager) kernel mode setting. To enable this feature, add the nvidia-drm.modeset=1 to Kernel Parameter. For basic functionality that should suffice, if you want to ensure it's loaded at the earliest possible occasion, or are noticing startup issues you can add nvidia, nvidiamodeset, nvidiauvm and nvidiadrm to the initramfs according to Mkinitcpio#MODULES.
2. What I had done
This is a good setup. It uses nouveau
as the nvidia driver and uses modesetting
intel driver. With the DRI_PRIME=1
, option I can use nvidia as the renderer. But this setup has some cons:
- the rendering in
nouveau
is slow CUDA
is not available. For CUDA, it is necessary to installnvidia
drivers.
but the good thing is, its very energy efficient. i.e. nvidia graphics card is not used when not required which is good for laptop battery.
no `nvidia` or `nvidia-lts` no `xf86-video-intel`
pacman -Qi xf86- xf86-input-libinput xf86-video-nouveau
just the modesetting intel driver and nouveau driver
xrandr --listproviders Providers: number : 2 Provider 0: id: 0x45 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 3 outputs: 3 associated providers: 1 name:modesetting Provider 1: id: 0xec cap: 0x7, Source Output, Sink Output, Source Offload crtcs: 4 outputs: 1 associated providers: 1 name:nouveau
and nothing inside the /etc/X11/xorg.conf.d/
directory
and
ls /usr/share/X11/xorg.conf.d 10-quirks.conf 40-libinput.conf