diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2015-02-16 05:49:07 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-03-02 09:59:36 -0500 |
commit | 0e661006370b7e7fb9ac9d94f9c3500a62cd559b (patch) | |
tree | c5e67eea4c6ff8c86c8316a71b738f7d7c73f2b8 /drivers/media | |
parent | c517d838eb7d07bbe9507871fab3931deccff539 (diff) |
[media] vb2: fix 'UNBALANCED' warnings when calling vb2_thread_stop()
Stopping the vb2 thread (as used by several DVB devices) can result
in an 'UNBALANCED' warning such as this:
vb2: counters for queue ffff880407ee9828: UNBALANCED!
vb2: setup: 1 start_streaming: 1 stop_streaming: 1
vb2: wait_prepare: 249333 wait_finish: 249334
This is due to a race condition between stopping the thread and
calling vb2_internal_streamoff(). While I have not been able to deduce
the exact mechanism how this race condition can produce this warning,
I can see that the way the stream is stopped is likely to lead to a
race somewhere.
This patch simplifies how this is done by first ensuring that the
thread is completely stopped before cleaning up the vb2 queue. It
does that by setting threadio->stop to true, followed by a call to
vb2_queue_error() which will wake up the thread. The thread sees that
'stop' is true and it will exit.
The call to kthread_stop() waits until the thread has exited, and only
then is the queue cleaned up by calling __vb2_cleanup_fileio().
This is a much cleaner sequence and the warning has now disappeared.
Reported-by: Jurgen Kramer <gtmkramer@xs4all.nl>
Tested-by: Jurgen Kramer <gtmkramer@xs4all.nl>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: <stable@vger.kernel.org> # for v3.18 and up
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/v4l2-core/videobuf2-core.c | 11 |
1 files changed, 3 insertions, 8 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index bc08a829bc13..cc16e76a2493 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c | |||
@@ -3230,18 +3230,13 @@ int vb2_thread_stop(struct vb2_queue *q) | |||
3230 | 3230 | ||
3231 | if (threadio == NULL) | 3231 | if (threadio == NULL) |
3232 | return 0; | 3232 | return 0; |
3233 | call_void_qop(q, wait_finish, q); | ||
3234 | threadio->stop = true; | 3233 | threadio->stop = true; |
3235 | vb2_internal_streamoff(q, q->type); | 3234 | /* Wake up all pending sleeps in the thread */ |
3236 | call_void_qop(q, wait_prepare, q); | 3235 | vb2_queue_error(q); |
3237 | err = kthread_stop(threadio->thread); | 3236 | err = kthread_stop(threadio->thread); |
3238 | q->fileio = NULL; | 3237 | __vb2_cleanup_fileio(q); |
3239 | fileio->req.count = 0; | ||
3240 | vb2_reqbufs(q, &fileio->req); | ||
3241 | kfree(fileio); | ||
3242 | threadio->thread = NULL; | 3238 | threadio->thread = NULL; |
3243 | kfree(threadio); | 3239 | kfree(threadio); |
3244 | q->fileio = NULL; | ||
3245 | q->threadio = NULL; | 3240 | q->threadio = NULL; |
3246 | return err; | 3241 | return err; |
3247 | } | 3242 | } |