Skip to content

VRAM leak: orphaned DMA-BUFs sized to physical monitor accumulate while streaming a virtual headless output (wlr capture, NVENC) #5810

Description

@dWacing

Describe the Bug

Streaming from a virtual headless output leaks VRAM as orphaned DMA-BUFs that
are visible in neither nvidia-smi's process list nor any process's fd table.
The leak accumulates continuously (~1.3 GB/h) while a stream is active, and
survives client disconnect — only restarting Sunshine frees it.

Measured on an RTX 5090 32GB over two sessions:

  • ~30 GB VRAM unaccounted for after ~2 days of intermittent streaming
  • 24.9 GB leaked after one overnight session; freed instantly by
    systemctl --user restart sunshine (24893 → 2723 MiB)
  • 1-hour instrumented run: unattributed VRAM grows 1819 → 2570 MiB while
    streaming, stays flat after client disconnect, grows again on reconnect

Key observation: leaked buffers match the physical monitor, not the streamed one

/sys/kernel/debug/dma_buf/bufinfo (as root) shows thousands of leaked
buffers with refcount 2 and no attached devices:

size       flags      mode       count    exp_name  ino       name
39321600   00000002   02080007   00000002 drm       00974892  <none>
  Attached Devices:
  Total 0 devices attached
... (repeated ~800x, plus a second size class)
20971520   00000002   02080007   00000002 drm       00974746  <none>
  • 39321600 bytes = exactly 3840×2560×4 → the physical monitor (BenQ RD280U)
  • 20971520 bytes = 2048×2560×4 (aligned variant)
  • The streamed output is a virtual headless monitor "SUNSHINE" at 1512×982
    (output_name = SUNSHINE), i.e. the leaked buffers are the wrong size for
    the capture target — they appear to be allocated per capture cycle against
    the physical display and never released.

Config

capture = wlr
output_name = SUNSHINE

Hyprland (Wayland). Sunshine uses the zwlr_screencopy_manager_v1 path
("Screencasting with Wayland's protocol" in the log), NVENC encoder.

Environment

Reproduction

  1. Hyprland with one physical 4K monitor + one headless output (e.g.
    hyprctl output create headless SUNSHINE), Sunshine output_name = the
    headless output, capture = wlr
  2. Stream for ~1 hour; periodically measure unattributed VRAM =
    nvidia-smi --query-gpu=memory.used minus the process sum
  3. Disconnect the client — leak does not drop
  4. systemctl --user restart sunshine — leak drops to baseline instantly

Expected behavior

DMA-BUFs used for capture should be released when the frame is consumed; VRAM
usage should stay flat (minus normal encoder buffers) for the session
lifetime and drop on client disconnect.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    aiPR has signs of heavy ai usage (either indicated by user or assumed)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions