Skip to content

fix: serialize concurrent GBM buffer allocation in dup_gst_memory_as_dmabuf to prevent SIGSEGV in libgallium with multiple concurrent video pipelines - #522

Open
Elgen69 wants to merge 1 commit into
ardera:masterfrom
Elgen69:master
Open

Conversation

@Elgen69

@Elgen69 Elgen69 commented Jul 24, 2026

Copy link
Copy Markdown

Bug

flutter-pi segfaults intermittently when running multiple concurrent
flutterpi_gstreamer_video_player instances on software-decoded
(non-DMA-BUF) video sources — e.g. 3 zones each playing their own H.264
clip via avdec_h264 on a Raspberry Pi 5. Crash timing is wildly
inconsistent across otherwise-identical runs (observed anywhere from ~5s
to ~60s+ before crashing).

Root cause

dup_gst_memory_as_dmabuf() in src/plugins/gstreamer_video_player/frame.c
runs on a per-pipeline GStreamer worker thread (one thread per zone/pipeline,
e.g. multiqueue0:src, multiqueue1:src, multiqueue2:src). When the
decoded GstMemory isn't already a DMA-BUF, this function calls
gbm_bo_create() / gbm_bo_map() / gbm_bo_get_fd() to manually copy the
frame into a new GBM buffer.

With multiple concurrent zones, multiple threads can call into this
function — and therefore into Mesa's GBM/Gallium3D driver — concurrently,
on the same shared gbm_device, with no synchronization
. Mesa's Gallium
driver is not safe against unsynchronized concurrent calls into the same
GBM device from multiple threads, and this reliably segfaults inside
libgallium.so.

Confirmed via gdb (built with -DCMAKE_BUILD_TYPE=Debug):
"Thread 16 "multiqueue0:src" received signal SIGSEGV, Segmentation fault.
0x00007ffff5a6881c in ??? () from /lib/aarch64-linux-gnu/libgallium-25.0.7-2+rpt4.so
#0 ??? () from libgallium-25.0.7-2+rpt4.so
#1 ??? () from /usr/lib/aarch64-linux-gnu/gbm/dri_gbm.so
#2 dup_gst_memory_as_dmabuf (gbm_device=0x5265b0, memory=0x7fff4cf24010)
at src/plugins/gstreamer_video_player/frame.c:433
#3 get_plane_infos (buffer=0x7fffa801e610, info=0x7ac048, gbm_device=0x5265b0, plane_infos=0x7fffb67cc9a8)
at src/plugins/gstreamer_video_player/frame.c:652
#4 frame_new (interface=0xb03b70, sample=0x7fffa00c9f20, info=0x7ac048)
at src/plugins/gstreamer_video_player/frame.c:896
#5 on_appsink_new_sample (appsink=0xaab640 [GstAppSink|sink], userdata=0x7abe60)
at src/plugins/gstreamer_video_player/player.c:806"

I checked whether any existing lock in the file covers this path
(grep -n "mutex\|lock\|pthread" frame.c) — the only existing lock
(context_lock in struct frame_interface) guards a different, unrelated
section of code (EGL context state), not the GBM allocation calls.

This also explains other symptoms I saw during testing: crashes following
closely-timed loop-restarts across zones (loop restart = fresh
decode/frame-callback burst on that zone's thread = higher collision odds
with another zone's simultaneous frame callback), and unreliable
simultaneous zone startup (same race, triggering during initial frame
delivery instead of a loop restart).

Fix

Added a dedicated pthread_mutex_t gbm_lock, serializing access to the
gbm_bo_create() / gbm_bo_map() / gbm_bo_get_fd() sequence inside
dup_gst_memory_as_dmabuf(). Locked right after the (safe, non-GBM)
gst_memory_map() call, unlocked on every exit path (success and both
failure paths), following the same locking pattern already used elsewhere
in this file (context_lock via DEFINE_LOCK_OPS).

Scope is deliberately minimal — this only touches dup_gst_memory_as_dmabuf();
the sibling function dup_gst_buffer_range_as_dmabuf() (used for a
different code path) is untouched, since it wasn't the one that crashed in
my reproduction, though it likely has the same class of issue and may be
worth locking too in a follow-up if confirmed.

Testing

Reproduced reliably on:

  • Raspberry Pi 5 (BCM2712), Raspberry Pi OS Lite 64-bit (Trixie)
  • 3 concurrent flutterpi_gstreamer_video_player zones, each playing a
    separate H.264 file via software decode (avdec_h264)
  • --videomode 1920x1080@60

Before fix: segfault within 5–60s, every run, reproducible across many
attempts.

After fix: ran stably well past the ~60s ceiling every prior attempt
had hit, no crashes observed across multiple retest runs (including under
sustained load, ~50°C).

…dmabuf to prevent SIGSEGV in libgallium with multiple concurrent video pipelines
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant