[Bug]: iHD retains one 16 KiB i915 dmabuf FD per VA decoder recreate cycle
- Dominant language
- C
- Stars
- 1.2k
- Forks
- 383
- Avg merge
- 8d 18h
- Merged PRs (30d)
- 4
Description
## Which component is impacted?
Decode
## Is this a regression?
No known good version. The same behavior reproduces with media-driver 24.1.0, 25.2.3, and 26.1.6.
## What happened?
Recreating a VA H.264 decoder leaves one additional 16 KiB dmabuf FD open after each warm decoder create/destroy cycle. The retained buffers report `exp_name: i915` in `/proc/self/fdinfo`.
The reproducer uses GStreamer `playbin3` with a `fakesink`. Negotiated output is `video/x-raw(memory:VAMemory)`, so no dmabuf is passed to GTK, a Wayland sink, or another downstream importer.
Expected: after the pipeline returns to `NULL`, decoder-internal dmabuf FDs from the destroyed decoder are closed and the count returns to a stable baseline.
Actual: the first decoder initialization creates 427 internal dmabufs, then every subsequent `NULL -> PLAYING` recreation retains one extra 16 KiB dmabuf. Returning the pipeline to final `NULL` does not release them.
Minimal reproducer (Python/GStreamer):
https://github.com/publifyjp/longrun-player-app/blob/bb4a59c287153b253ccc39f53b34112b5d29d5bc/linux/tools/repro236-fdleak.py
Run with any local H.264 MP4 file:
```console
python3 repro236-fdleak.py sample.mp4 --cycles 5
```
## Usage scenario
Playback: a 24/7 digital-signage renderer. Decoder recreation is required when changing resolution class or recovering a failed pipeline. The leak is dormant for same-resolution gapless playback, but mixed-resolution schedules can rebuild frequently enough to exhaust the process FD limit.
## Environment
- Ubuntu 24.04.4 LTS
- Kernel 7.0.0-28-generic
- GPU: Intel Alder Lake-N UHD Graphics `[8086:46d1]`
- GStreamer 1.24.2
- Installed stack: media-driver 24.1.0, libva 2.20.0, gmmlib 22.3.17
- Additional isolated test stacks (loaded with `LD_LIBRARY_PATH` and `LIBVA_DRIVERS_PATH`, without changing the installed packages):
- media-driver 25.2.3, libva 2.24.1, gmmlib 22.10.0
- media-driver 26.1.6, libva 2.24.1, gmmlib 22.10.0
`vainfo` successfully loads iHD in each stack. For 26.1.6 it reports VA-API 1.24 and `Intel iHD driver for Intel(R) Gen Graphics - 26.1.6`.
## Raw evidence
Installed media-driver 24.1.0, default settings:
```text
cycle 0 (before playing): no dmabuf
negotiated caps: video/x-raw(memory:VAMemory), format=(string)NV12, width=(int)1920, height=(int)1080, framerate=(fraction)24000/1001
cycle 1: total=427 by size: 12KB=7 16KB=242 24KB=40 32KB=115 48KB=23
cycle 2: total=428 by size: 12KB=7 16KB=243 24KB=40 32KB=115 48KB=23 | delta: 16KB+1
cycle 3: total=429 by size: 12KB=7 16KB=244 24KB=40 32KB=115 48KB=23 | delta: 16KB+1
cycle 4: total=430 by size: 12KB=7 16KB=245 24KB=40 32KB=115 48KB=23 | delta: 16KB+1
cycle 5: total=431 by size: 12KB=7 16KB=246 24KB=40 32KB=115 48KB=23 | delta: 16KB+1
after final NULL: total=431 by size: 12KB=7 16KB=246 24KB=40 32KB=115 48KB=23 exporters: {'i915': 431}
```
Isolated media-driver 25.2.3 and 26.1.6 test stacks both produced the same census:
```text
cycle 1: total=427 by size: 12KB=7 16KB=242 24KB=40 32KB=115 48KB=23
cycle 2: total=428 by size: 12KB=7 16KB=243 24KB=40 32KB=115 48KB=23 | delta: 16KB+1
cycle 3: total=429 by size: 12KB=7 16KB=244 24KB=40 32KB=115 48KB=23 | delta: 16KB+1
after final NULL: total=429 by size: 12KB=7 16KB=244 24KB=40 32KB=115 48KB=23 exporters: {'i915': 429}
```
Disabling media compression did not change the result on 24.1.0:
```text
INTEL_MEDIA_COMPRESSION=0
cycle 1: total=427 by size: 12KB=7 16KB=242 24KB=40 32KB=115 48KB=23
cycle 2: total=428 by size: 12KB=7 16KB=243 24KB=40 32KB=115 48KB=23 | delta: 16KB+1
cycle 3: total=429 by size: 12KB=7 16KB=244 24KB=40 32KB=115 48KB=23 | delta: 16KB+1
```
## Boundary already checked
- The leak reproduces with `fakesink`, without GTK or a display sink.
- Negotiated caps remain `memory:VAMemory`; no downstream dmabuf import is involved.
- `INTEL_MEDIA_COMPRESSION=0` has no effect, so this evidence does not support identifying CCS auxiliary planes as the cause.
- GStreamer's VA allocator converts every `vaExportSurfaceHandle` object in `desc.num_objects` into `GstMemory` and closes all exported FDs on its failure path.
The remaining ownership boundary appears to be inside media-driver/libva or i915, but we do not have enough evidence to assign the exact component. Please redirect this report if a libva or kernel issue is more appropriate.
## Patch contribution
No patch is available yet; help identifying the owning allocation would be appreciated.
Contributor guide
Research direction
Run linux/tools/repro236-fdleak.py with a local H.264 MP4 and compare dmabuf counts across decoder recreation cycles. Trace ownership from vaExportSurfaceHandle through the media-driver/libva boundary, using the reported fdinfo evidence and GStreamer allocator behavior as boundaries. Done means the retained 16 KiB i915 dmabuf no longer increases per cycle and final NULL returns to baseline.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, linux, python
- Domain
- operating-systems, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100