Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start from existing X server (and without sudo) #147

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.PHONY: all clean permission

all: ${CURDIR}/nvidia-xrun-util

$(CURDIR)/nvidia-xrun-util: $(CURDIR)/nvidia-xrun-util.c
gcc -g -O0 ${CURDIR}/nvidia-xrun-util.c -lm -o ${CURDIR}/nvidia-xrun-util

permission: $(CURDIR)/nvidia-xrun-util
sudo chown root:root ${CURDIR}/nvidia-xrun-util && sudo chmod gu+s ${CURDIR}/nvidia-xrun-util

clean:
-rm ${CURDIR}/nvidia-xrun-util
69 changes: 52 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
**IMPORTANT: Please do not use anymore. Nvida has released for some years new proprietary drivers that works well. So this project is not usefull anymore.**
That's why it has been archived.

# nvidia-xrun
These utility scripts aim to make the life easier for nvidia cards users.
It started with a revelation that bumblebee in current state offers very poor performance. This solution offers a bit more complicated procedure but offers a full GPU utilization(in terms of linux drivers)

## Usage:
1. switch to free tty
1. login
1. run `nvidia-xrun [app]`
1. enjoy
2. login
3. run `nvidia-xrun [return tty] [app]`
4. enjoy

Currently sudo is required as the script needs to wake up GPU, modprobe the nvidia driver and perform cleanup afterwards.
## Usage from existing X session:
1. open a terminal emulator (as Xterm)
2. run `nvidia-xrun-util start_from_X` you can specify an app with `--exec="[app]"` or the tty number to switch before the nvidia X session finished with `--actualVt=[return tty]` (by default, it switch back to the actual tty, before the script was run)
3. enjoy

**This version needs no sudo right for the current user**

The systemd service can be used to completely remove the card from the kernel
device tree (so that it won't even show in `lspci` output), and this will
Expand All @@ -25,17 +33,24 @@ When the nvidia-xrun command is used, the device is added again to the tree so t

## Structure
* **nvidia-xrun** - uses following dir structure:
* **/usr/bin/nvidia-xrun** - the executable script
* **/usr/bin/nvidia-xrun** - the executable bash script
* **/usr/bin/nvidia-xrun-util** - the executable binary contains all admin commands
* **/etc/X11/nvidia-xorg.conf** - the main X confing file
* **/etc/X11/xinit/nvidia-xinitrc** - xinitrc config file. Contains the setting of provider output source
* **/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] /usr/share/xsession/nvidia-gnome.desktop** - gnome-session entry using nvidia-xrun in the gdm login manager
* **[OPTIONAL] $XDG_CONFIG_HOME/X11/nvidia-xinitrc** - user-level custom xinit script file. You can put here your favourite window manager for example

## Modifications in this repository
(I'm sorry for my bad english, I'm a french student)
This repository is a fork of the tangxinfa repository (branch "fix-no-sudo") who permit to use nvidia-xrun without sudo rights by separating all sudo commands in the binary "nidia-xrun-util" (run with setuid root).
I've modified the binary to start "nvidia-xrun" in a new user session in a new tty using **systemd-run** (https://unix.stackexchange.com/questions/554592/how-to-manually-run-init-start-a-xorg-server-on-a-different-vt-tty/554603#554603).
When the `nvidia-xrun-util start_from_X` command start, it wait one second before switch to the tty8 (to prevent swithing back to the tty1 at first session ending in gdm). After, it will run the nvidia-xrun command in the tty8 as user. When the session finished, it switch back to the previous tty or the tty specified by the user (`--actualVt=[tty number]`).
For the time, you cannot modify the tty opened by the `nvidia-xrun-util start_from_X` because it is hard coded. That means if you run the command twice, it will wait before the first nvidia X ending before starting a new one. (the classic `nvidia-xrun` command is no affected because it run in the current tty)
**To make possible switching back to the previous tty, the nvidia-xrun command has been changed! You must specify the tty number before the app to execute like this `nvidia-xrun 1 xterm`**

## Setting the right bus id
Usually the 1:0:0 bus is correct. If this is not your case(you can find out through lspci or bbswitch output mesages) you can create
Expand Down Expand Up @@ -88,18 +103,20 @@ With this you do not need to specify the app and you can simply run:

nvidia-xrun

## AUR Package
The Arch Linux User Repository package can be found [here](https://aur.archlinux.org/packages/nvidia-xrun/).

## COPR Repository for Enterprise Linux, Fedora, Mageia, and openSUSE
The RPM packages and repository details for all supported distributions can be found on the [ekultails/nvidia-xrun](https://copr.fedorainfracloud.org/coprs/ekultails/nvidia-xrun/) COPR overview page.

### Install (Enterprise Linux and Fedora)

## Run graphically from gdm
1. For convenience you can create `sudo nano /usr/share/xsession/[your session].desktop` and put there your favourite window manager:
```
sudo dnf copr enable ekultails/nvidia-xrun
sudo dnf install nvidia-xrun
[Desktop Entry]
Encoding=UTF-8
Name=[the name in the gdm session list]
Comment=[comment in the gdm session list]
Type=Application
Exec=/usr/bin/nvidia-xrun-util start_from_X --actualVt=1 --exec="[put it your session script]"
```
2. Restart gdm `sudo systemctl restart gdm`
3. Now, you will be able to select your new nvidia-xrun session in the gdm list when the computer start.

In fact, gdm will spawn a new X server who run the `nvidia-xrun-util start_from_X` command and stop. (that make computer switch back to tty1, however, because the nvidia-xrun-util process wait 1 second before starting, the computer will just after switch to the tty8). The argument `--actualVt=1` make the script switch back the tty1 (who contains the gdm session manager) instead of the tty where the script was started.

## Troubleshooting
### Steam issues
Expand Down Expand Up @@ -127,3 +144,21 @@ In that case, you should add `--ignore-install` to `modprobe` calls in `nvidia-x
Check https://wiki.archlinux.org/index.php/Vulkan
* remove package vulkan-intel
* set VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json

### Xorg cannot start in Debian
You should comment all "files" section in /etc/X11/nvidia-xorg.conf like this:
```
#Section "Files"
# ModulePath "/usr/lib/nvidia"
# ModulePath "/usr/lib32/nvidia"
# ModulePath "/usr/lib32/nvidia/xorg/modules"
# ModulePath "/usr/lib32/xorg/modules"
# ModulePath "/usr/lib64/nvidia/xorg/modules"
# ModulePath "/usr/lib64/nvidia/xorg"
# ModulePath "/usr/lib64/xorg/modules"
#EndSection
```

### cannot unload "nvidia-drm" before nvidia-xrun
I don't know why, in my debian loading "nvidia_drm modeset=1" cause nvidia_drm cannot be unloaded without kill all X server (even intel graphic X server). More if the script try to remove the nvidia card at this moment, it cause a kernel bug who cause shutdown infinite loop (you must make a forced outage) and you will not be able to kill the "nvidia-xrun-util turn_off_gpu" process.
I must replace **"nvidia_drm modeset=1"** by **nvidia_drm** in /etc/default/nvidia-xrun
6 changes: 6 additions & 0 deletions launchers/nvidia-gnome.desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[Desktop Entry]
Encoding=UTF-8
Name=GNOME (nvidia-xrun)
Comment=Log in Gnome X11 (running with nvidia-xrun)
Type=Application
Exec=/usr/bin/nvidia-xrun-util start_from_X --actualVt=1 --exec=gnome-session
62 changes: 19 additions & 43 deletions nvidia-xrun
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
CHVT=$1; shift

DRY_RUN=0
function printHelp {
Expand All @@ -18,51 +19,30 @@ function execute {
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"
else
echo 'Enabling powersave for the graphic card'
execute "sudo tee /sys/bus/pci/devices/${DEVICE_BUS_ID}/power/control <<<auto"
fi
CURDIR=$(dirname "$(realpath $0)")

echo 'Enabling powersave for the PCIe controller'
execute "sudo tee /sys/bus/pci/devices/${CONTROLLER_BUS_ID}/power/control <<<auto"
function turn_off_gpu {
${CURDIR}/nvidia-xrun-util turn_off_gpu ${DRY_RUN}
}

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"
${CURDIR}/nvidia-xrun-util turn_on_gpu ${DRY_RUN}
}

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
function force_turn_off_gpu {
${CURDIR}/nvidia-xrun-util force_turn_off_gpu ${DRY_RUN}
}

echo 'Turning the card on'
execute "sudo tee /sys/bus/pci/devices/${DEVICE_BUS_ID}/power/control <<<on"
function force_turn_on_gpu {
${CURDIR}/nvidia-xrun-util force_turn_on_gpu ${DRY_RUN}
}

function load_modules {
for module in "${MODULES_LOAD[@]}"
do
echo "Loading module ${module}"
execute "sudo modprobe ${module}"
done
${CURDIR}/nvidia-xrun-util load_modules ${DRY_RUN}
}

function unload_modules {
for module in "${MODULES_UNLOAD[@]}"
do
echo "Unloading module ${module}"
execute "sudo modprobe -r ${module}"
done
${CURDIR}/nvidia-xrun-util unload_modules ${DRY_RUN}
}

if [[ "$1" == "-d" ]]
Expand All @@ -71,12 +51,10 @@ if [[ "$1" == "-d" ]]
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
force_turn_off_gpu
exit 0
fi

if [[ $EUID -eq 0 ]]; then
Expand Down Expand Up @@ -125,9 +103,7 @@ 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
turn_on_gpu

# ---------- LOADING MODULES ----------
load_modules
Expand All @@ -139,6 +115,6 @@ execute ${COMMAND}
unload_modules

# --------- TURNING OFF GPU ----------
if [[ "$ENABLE_PM" == '1' ]]; then
turn_off_gpu
fi
turn_off_gpu

chvt $CHVT
Loading