[PR #139] [MERGED] fix(nvidia): derive GPU cgroup major from the live device node (dynamic nvidia-uvm) #138

Closed
opened 2026-10-15 12:52:18 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/games-on-whales/LXC2Docker/pull/139
Author: @JBailes
Created: 7/5/2026
Status: ✅ Merged
Merged: 7/5/2026
Merged by: @JBailes

Base: main ← Head: fix/nvidia-uvm-dynamic-major


📝 Commits (1)

  • 76f74ff fix(nvidia): derive GPU cgroup major from the live device node, not the CDI spec

📊 Changes

1 file changed (+20 additions, -2 deletions)

View changed files

📝 internal/lxc/nvidia.go (+20 -2)

📄 Description

Symptom

Hardware NVENC silently degrades to software x264 in GPU containers (Wolf: stuttery / torn game streaming), while nvidia-smi inside the container works fine.

Cause

nvidia-uvm / nvidia-uvm-tools get a dynamic device major that can change across reboots. The daemon reads /etc/cdi/nvidia.json once (generated by nvidia-ctk) and reuses it, so a spec from an earlier boot carries a stale major. nvidiaItemsFromSpec emitted the cgroup allow from the spec's stored major (c 507:0) but bind-mounted the real node (508:0) — so the node is visible but the device cgroup blocks its real major, CUDA fails with CUDA_ERROR_NO_DEVICE, and NVENC drops to software.

Fix

When emitting the cgroup allow for a CDI device node, stat() the actual node for its live major:minor; fall back to the spec value only when the node is absent (unit tests / missing devices). Fixed-major nodes (195 nvidia*, 226 dri) are unchanged; the dynamic nvidia-uvm nodes now track reality.

Verified live (pve .253, RTX 5080)

Before: c 507:0, Failed to init cuda ... CUDA_ERROR_NO_DEVICE, Using h264 encoder: x264 (software).
After: c 508:0, Using h264 encoder: nvcodec / h265: nvcodec (hardware NVENC). go test ./internal/lxc/ passes.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/games-on-whales/LXC2Docker/pull/139 **Author:** [@JBailes](https://github.com/JBailes) **Created:** 7/5/2026 **Status:** ✅ Merged **Merged:** 7/5/2026 **Merged by:** [@JBailes](https://github.com/JBailes) **Base:** `main` ← **Head:** `fix/nvidia-uvm-dynamic-major` --- ### 📝 Commits (1) - [`76f74ff`](https://github.com/games-on-whales/LXC2Docker/commit/76f74ff6a458c88ab6f17d20b928f20333232990) fix(nvidia): derive GPU cgroup major from the live device node, not the CDI spec ### 📊 Changes **1 file changed** (+20 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `internal/lxc/nvidia.go` (+20 -2) </details> ### 📄 Description ## Symptom Hardware NVENC silently degrades to software x264 in GPU containers (Wolf: stuttery / torn game streaming), while `nvidia-smi` inside the container works fine. ## Cause `nvidia-uvm` / `nvidia-uvm-tools` get a **dynamic** device major that can change across reboots. The daemon reads `/etc/cdi/nvidia.json` once (generated by `nvidia-ctk`) and reuses it, so a spec from an earlier boot carries a stale major. `nvidiaItemsFromSpec` emitted the cgroup allow from the spec's stored major (`c 507:0`) but bind-mounted the real node (`508:0`) — so the node is visible but the device cgroup **blocks its real major**, CUDA fails with `CUDA_ERROR_NO_DEVICE`, and NVENC drops to software. ## Fix When emitting the cgroup allow for a CDI device node, `stat()` the actual node for its live major:minor; fall back to the spec value only when the node is absent (unit tests / missing devices). Fixed-major nodes (195 `nvidia*`, 226 `dri`) are unchanged; the dynamic `nvidia-uvm` nodes now track reality. ## Verified live (pve .253, RTX 5080) Before: `c 507:0`, `Failed to init cuda ... CUDA_ERROR_NO_DEVICE`, `Using h264 encoder: x264 (software)`. After: `c 508:0`, `Using h264 encoder: nvcodec` / `h265: nvcodec` (hardware NVENC). `go test ./internal/lxc/` passes. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
games-on-whales/LXC2Docker#138
No description provided.