Skip to content
This repository has been archived by the owner on Jun 19, 2023. It is now read-only.

Commit

Permalink
Merge pull request #2 from michelesr/merge-upstream
Browse files Browse the repository at this point in the history
Merge upstream changes
  • Loading branch information
michelesr authored Apr 5, 2019
2 parents 70cde84 + dacecb6 commit 1d1b8f7
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 56 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Created by .ignore support plugin (hsz.mobi)
nvidia-xrun.iml
.idea
test-install.sh
test-cleanup.sh
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ When the nvidia-xrun command is used, the device is added again to the tree so t
* **/etc/X11/xinit/nvidia-xinitrc.d** - custom xinitrc scripts directory
* **/etc/X11/nvidia-xorg.conf.d** - custom X config directory
* **/etc/systemd/system/nvidia-xrun-pm.service** systemd service
* **/etc/default/nvidia-xrun** - nvidia-xrun config file
* **/usr/share/xsessions/nvidia-xrun-openbox.desktop** - xsession file for openbox
* **/usr/share/xsessions/nvidia-xrun-plasma.desktop** - xsession file for plasma
* **[OPTIONAL] ~/.nvidia-xinitrc** - user-level custom xinit script file. You can put here your favourite window manager for example
Expand Down Expand Up @@ -59,6 +60,12 @@ Also this way you can adjust some nvidia settings if you encounter issues:
# Option "UseDisplayDevice" "none"
EndSection

In order to make power management features work properly, you need to make sure
that bus ids in `/etc/default/nvidia-xrun` are correctly set for both the
NVIDIA graphic card and the PCI express controller that hosts it. You should be
able to find both the ids in the output of `lshw`: the PCIe controller is
usually displayed right before the graphic card.

## Automatically run window manager
For convenience you can create `nano ~/.nvidia-xinitrc` and put there your favourite window manager:

Expand Down
5 changes: 5 additions & 0 deletions config/nvidia-xrun
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CONTROLLER_BUS_ID=0000:00:01.0
DEVICE_BUS_ID=0000:01:00.0
BUS_RESCAN_WAIT_SEC=1
MODULES_LOAD=(nvidia nvidia_uvm nvidia_modeset "nvidia_drm modeset=1")
MODULES_UNLOAD=(nvidia_drm nvidia_modeset nvidia_uvm nvidia)
21 changes: 11 additions & 10 deletions nvidia-xinitrc
Original file line number Diff line number Diff line change
@@ -1,44 +1,45 @@
#!/bin/bash
#!/usr/bin/env bash

userresources=$HOME/.Xresources
usermodmap=$HOME/.Xmodmap
sysresources=/etc/X11/xinit/.Xresources
sysmodmap=/etc/X11/xinit/.Xmodmap
userxinitrc=$HOME/.nvidia-xinitrc

# merge in defaults and keymaps
if [ -f ${sysresources} ]; then
if [[ -f ${sysresources} ]]; then
xrdb -merge ${sysresources}
fi

if [ -f ${sysmodmap} ]; then
if [[ -f ${sysmodmap} ]]; then
xmodmap ${sysmodmap}
fi

if [ -f "$userresources" ]; then
if [[ -f "$userresources" ]]; then
xrdb -merge "$userresources"
fi

if [ -f "$usermodmap" ]; then
if [[ -f "$usermodmap" ]]; then
xmodmap "$usermodmap"
fi

export LD_LIBRARY_PATH=/usr/lib64/nvidia/:/usr/lib32/nvidia:/usr/lib:${LD_LIBRARY_PATH}

# load additional configs
if [ -d /etc/X11/xinit/nvidia-xinitrc.d ] ; then
if [[ -d /etc/X11/xinit/nvidia-xinitrc.d ]] ; then
for f in /etc/X11/xinit/nvidia-xinitrc.d/?*.sh ; do
[ -x "$f" ] && . "$f"
[[ -x "$f" ]] && . "$f"
done
unset f
fi

xrandr --setprovideroutputsource modesetting NVIDIA-0
xrandr --auto

if [ -f "$userxinitrc" ]; then
if [[ -f "$userxinitrc" ]]; then
sh ${userxinitrc} $*
else
if [ $# -gt 0 ]; then
"$*"
if [[ $# -gt 0 ]]; then
sh -c "exec $*"
fi
fi
93 changes: 49 additions & 44 deletions nvidia-xrun
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/bash
#!/usr/bin/env bash

DRY_RUN=0
function printHelp {
echo "Utility to run games and applications in separate X on discrete Nvidia graphic card"
Expand All @@ -9,49 +10,64 @@ function printHelp {
}

function execute {
if [ ${DRY_RUN} -eq 1 ]
if [[ ${DRY_RUN} -eq 1 ]]
then
echo ">>Dry run. Command: $*"
else
eval $*
fi
}

function turn_off_gpu {
echo 'Removing Nvidia bus from the kernel'
execute "sudo tee /sys/bus/pci/devices/${DEVICE_BUS_ID}/remove <<<1"

if [[ $EUID -eq 0 ]]; then
echo "This script must not be run as root" >&2
exit 1
fi
echo 'Enabling powersave for the PCIe controller'
execute "sudo tee /sys/bus/pci/devices/${CONTROLLER_BUS_ID}/power/control <<<auto"
}

if [ "$1" == "-d" ]
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" ]
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
if [[ ! -z "$*" ]] # generate exec line if arguments are given
then
# test if executable exists in path
if [ -x "$(which $1 2> /dev/null)" ]
if [[ -x "$(which $1 2> /dev/null)" ]]
then
# generate exec line
EXECL="$(which $1)"
# test if executable exists on disk
elif [ -e "$(realpath "$1")" ]
elif [[ -e "$(realpath "$1")" ]]
then
# generate exec line
EXECL="$(realpath "$1")"
Expand All @@ -65,54 +81,43 @@ else # prepare to start new X sessions if no arguments passed
EXECL=""
fi

EXECL="/etc/X11/xinit/nvidia-xinitrc $EXECL"
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 -----------
echo 'Turning the PCIe controller on to allow card rescan'
execute "sudo tee /sys/bus/pci/devices/0000:00:01.0/power/control <<<on"
execute "sudo tee /sys/bus/pci/devices/${CONTROLLER_BUS_ID}/power/control <<<on"

echo 'Waiting 1 second'
execute "sleep 1"

echo 'Rescanning PCI devices'
execute "sudo tee /sys/bus/pci/rescan <<<1"

# ---------- LOADING MODULES ----------
echo 'Loading nvidia module'
execute "sudo modprobe nvidia"

echo 'Loading nvidia_uvm module'
execute "sudo modprobe nvidia_uvm"
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 'Loading nvidia_modeset module'
execute "sudo modprobe nvidia_modeset"
echo 'Turning the card on'
execute "sudo tee /sys/bus/pci/devices/${DEVICE_BUS_ID}/power/control <<<on"

echo 'Loading nvidia_drm module'
execute "sudo modprobe nvidia_drm modeset=1"
# ---------- LOADING MODULES ----------
for module in "${MODULES_LOAD[@]}"
do
echo "Loading module ${module}"
execute "sudo modprobe ${module}"
done

# ---------- EXECUTING COMMAND --------
execute ${COMMAND}

# ---------- UNLOADING MODULES --------
echo 'Unloading nvidia_drm module'
execute "sudo rmmod nvidia_drm"

echo 'Unloading nvidia_modeset module'
execute "sudo rmmod nvidia_modeset"

echo 'Unloading nvidia_uvm module'
execute "sudo rmmod nvidia_uvm"

echo 'Unloading nvidia module'
execute "sudo rmmod nvidia"
for module in "${MODULES_UNLOAD[@]}"
do
echo "Unloading module ${module}"
execute "sudo modprobe -r ${module}"
done

# --------- TURNING OFF GPU ----------
if [ -f /sys/bus/pci/devices/0000:01:00.0/remove ]; then
echo 'Removing Nvidia bus from the kernel'
execute "sudo tee /sys/bus/pci/devices/0000:01:00.0/remove <<<1"
fi

echo 'Enabling powersave for the PCIe controller'
execute "sudo tee /sys/bus/pci/devices/0000:00:01.0/power/control <<<auto"
turn_off_gpu
4 changes: 2 additions & 2 deletions nvidia-xrun-pm.service
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ Description="Remove Nvidia GPU from kernel devices list and enable PM"

[Service]
Type=oneshot
ExecStartPre=/bin/bash -c 'echo 1 > /sys/bus/pci/devices/0000:01:00.0/remove'
ExecStart=/bin/bash -c 'echo auto > /sys/bus/pci/devices/0000:00:01.0/power/control'
Environment="TURN_OFF_GPU_ONLY=1"
ExecStart=/usr/bin/nvidia-xrun

[Install]
WantedBy=multi-user.target

0 comments on commit 1d1b8f7

Please sign in to comment.