After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 740645 - race condition in decoder locking
race condition in decoder locking
Status: RESOLVED FIXED
Product: gstreamer-vaapi
Classification: Other
Component: general
git master
Other Linux
: Normal normal
: ---
Assigned To: gstreamer-vaapi maintainer(s)
gstreamer-vaapi maintainer(s)
Depends on:
Blocks: 743569
 
 
Reported: 2014-11-24 17:34 UTC by Olivier Crête
Modified: 2015-03-06 17:36 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
vaapidecode: Check the condition after taking the lock (2.61 KB, patch)
2014-11-24 17:34 UTC, Olivier Crête
none Details | Review

Description Olivier Crête 2014-11-24 17:34:45 UTC
Created attachment 291383 [details] [review]
vaapidecode: Check the condition after taking the lock

In the decoder you have the pattern:

while (check condition)  {
lock;
wait;
unlock;
}

You can get into the case wher the condition is changed between checking it and taking the clock, resulting in the GCond never being awoken. Attach patch makes the condition checking function accessible and checks it while holding the lock, preventing the race from hapenning.
Comment 1 Faham Negini 2014-11-24 18:36:01 UTC
adding the attached patch, I still get into a spinlock with the following backtrace:

  • #0 pthread_cond_timedwait
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S line 238
  • #1 g_cond_wait_until
    from /lib/x86_64-linux-gnu/libglib-2.0.so.0
  • #2 ??
    from /lib/x86_64-linux-gnu/libglib-2.0.so.0
  • #3 g_async_queue_timeout_pop
    from /lib/x86_64-linux-gnu/libglib-2.0.so.0
  • #4 pop_frame
    at gstvaapidecoder.c line 390
  • #5 gst_vaapi_decoder_get_frame_with_timeout
    at gstvaapidecoder.c line 815
  • #6 gst_vaapidecode_decode_loop
    at gstvaapidecode.c line 408
  • #7 gst_task_func
    at gsttask.c line 316
  • #8 default_func
    at gsttaskpool.c line 68
  • #9 ??
    from /lib/x86_64-linux-gnu/libglib-2.0.so.0
  • #10 ??
    from /lib/x86_64-linux-gnu/libglib-2.0.so.0
  • #11 start_thread
    at pthread_create.c line 312
  • #12 clone
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S line 111


I should add, it usually happens when there is a lot of frame drops happening, for example when I run 15 mpeg2 hd streams as the following, I usually find 2 one of them getting blocked at the above backtrace.

gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
gst-launch udpsrc address=239.4.4.1 port=4000 ! tsdemux ! mpegvideoparse ! queue max-size-bytes=0 max-size-buffers=0 max-size-time=0 ! vaapidecode ! vaapisink &
Comment 2 sreerenj 2015-02-04 16:29:49 UTC
(In reply to comment #0)
> Created an attachment (id=291383) [details] [review]
> vaapidecode: Check the condition after taking the lock
> 
> In the decoder you have the pattern:
> 
> while (check condition)  {
> lock;
> wait;
> unlock;
> }
> 
> You can get into the case wher the condition is changed between checking it and
> taking the clock, resulting in the GCond never being awoken. Attach patch makes
> the condition checking function accessible and checks it while holding the
> lock, preventing the race from hapenning.

Sorry for the delay.
I didn't reproduce the issue. But what you have explained make sense :)
Will push it..
Comment 3 sreerenj 2015-02-05 07:56:52 UTC
commit fc7e6b19fd8f8b2bf4be2a69099482e051c14f2b
Author: Olivier Crete <olivier.crete@collabora.com>
Date:   Wed Feb 4 18:34:59 2015 +0200

    vaapidecode: Check the condition after taking the lock
    
    Otherwise the condition could become true before the lock
    is taken and the g_cond_signal() could be called
    before the g_cond_wait(), so the g_cond_wait() is never
    awoken.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=740645
Comment 4 sreerenj 2015-02-05 07:58:05 UTC
(In reply to comment #1)
> adding the attached patch, I still get into a spinlock with the following
> backtrace:
> 
> 

Do you still have issues with git master?
If so, could you please create another bug for the same?
Comment 5 sreerenj 2015-03-06 17:36:03 UTC
The vaapidecode has a single thread implementation now. And also there is a new vaapidecodebin  element to provide the parallelism.

I am closing this now, please reopen if issue persists.