[Bug 762177] New: v4l2src: Potential race condition with pool release on renegotiation

GStreamer (GNOME Bugzilla) bugzilla at gnome.org
Wed Feb 17 11:04:00 UTC 2016


https://bugzilla.gnome.org/show_bug.cgi?id=762177

            Bug ID: 762177
           Summary: v4l2src: Potential race condition with pool release on
                    renegotiation
    Classification: Platform
           Product: GStreamer
           Version: unspecified
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: Normal
         Component: gst-plugins-good
          Assignee: gstreamer-bugs at lists.freedesktop.org
          Reporter: patcherwork at gmail.com
        QA Contact: gstreamer-bugs at lists.freedesktop.org
     GNOME version: ---

Created attachment 321474
  --> https://bugzilla.gnome.org/attachment.cgi?id=321474&action=edit
A simple demo showing how the race condition causes the v4l2src to crash

Hello,

I have stumbled upon a potential race condition with v4l2bufferpool
reconstruction when trying to renegotiate a pipeline containing v4l2src. 

If a pipeline fires a renegotiation, the way it is currently being handled is:
- gst_v4l2_object_stop is called. the pool is deactivated, unreffed and
released.
- renegotiation is performed. gst_v4l2src_set_format_full is called, setting
the new format with V4L2_S_FMT.
- a new pool is setup using gst_v4l2_object_setup_pool after V4L2_S_FMT.

The problem is that before a V4L2_S_FMT is run, all buffers need to be returned
to the driver via VIDIOC_REQBUFS. This is performed by v4l2allocator in
gst_v4l2_allocator_stop, which is called by gst_v4l2_buffer_pool_stop when it
is done releasing all the buffers that have been allocated previously. This
works fine on simpler pipelines. However, if the v4l2src is running on a
processing pipeline that holds the buffers for prolonged periods, the following
happens:

- gst_v4l2_object_stop deactivates the pool, the pool starts releasing the
buffers.
- renegotiation begins.
- after renegotiation, the target format is set using V4L2_S_FMT. An
implementation of the driver call can be seen in vivid at:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/media/platform/vivid/vivid-vid-cap.c#n633
- The v4l2 driver checks if the device is busy. The function in v4l2-core,
vb2_is_busy is called, checking if the number of buffers that the driver has
are > 0. You can verify that at:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/media/videobuf2-core.h#n621
- Because of the increased processing, the previous pool has not released all
the buffers. gst_v4l2_allocator_stop has not yet been called. The buffers are
still set. Thus, V4L2_S_FMT fails with an EBUSY signal, causing the pipeline to
stop running.

I have also attached a simple demo of how to replicate the issue using the
vivid driver. This example is not perfect since it obviously refs indefinitely
the buffers, but it is simple enough to illustrate the problem.

I am a bit over my head in trying to find an easy way to fix this so any help
would be much appreciated.

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list