diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2014-08-04 06:14:14 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2014-09-21 19:46:10 -0400 |
commit | bf3593d939520559774cbfee03ba5f314d909620 (patch) | |
tree | a8c9fde479be353b28f458095cd1d3934e8b7b1c /drivers/media/v4l2-core/videobuf2-core.c | |
parent | 44e8e69d46db9928cd3b81cbea4ca24257412286 (diff) |
[media] vb2: fix vb2 state check when start_streaming fails
Commit bd994ddb2a12a3ff48cd549ec82cdceaea9614df (vb2: Fix stream start and
buffer completion race) broke the buffer state check in vb2_buffer_done.
So accept all three possible states there since I can no longer tell the
difference between vb2_buffer_done called from start_streaming or from
elsewhere.
Instead add a WARN_ON at the end of start_streaming that will check whether
any buffers were added to the done list, since that implies that the wrong
state was used as well.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: stable@vger.kernel.org # for v3.15 and up
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/v4l2-core/videobuf2-core.c')
-rw-r--r-- | drivers/media/v4l2-core/videobuf2-core.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index d3f2a221db62..7f70fd521ab1 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c | |||
@@ -1165,13 +1165,10 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) | |||
1165 | if (WARN_ON(vb->state != VB2_BUF_STATE_ACTIVE)) | 1165 | if (WARN_ON(vb->state != VB2_BUF_STATE_ACTIVE)) |
1166 | return; | 1166 | return; |
1167 | 1167 | ||
1168 | if (!q->start_streaming_called) { | 1168 | if (WARN_ON(state != VB2_BUF_STATE_DONE && |
1169 | if (WARN_ON(state != VB2_BUF_STATE_QUEUED)) | 1169 | state != VB2_BUF_STATE_ERROR && |
1170 | state = VB2_BUF_STATE_QUEUED; | 1170 | state != VB2_BUF_STATE_QUEUED)) |
1171 | } else if (WARN_ON(state != VB2_BUF_STATE_DONE && | 1171 | state = VB2_BUF_STATE_ERROR; |
1172 | state != VB2_BUF_STATE_ERROR)) { | ||
1173 | state = VB2_BUF_STATE_ERROR; | ||
1174 | } | ||
1175 | 1172 | ||
1176 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1173 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1177 | /* | 1174 | /* |
@@ -1783,6 +1780,12 @@ static int vb2_start_streaming(struct vb2_queue *q) | |||
1783 | /* Must be zero now */ | 1780 | /* Must be zero now */ |
1784 | WARN_ON(atomic_read(&q->owned_by_drv_count)); | 1781 | WARN_ON(atomic_read(&q->owned_by_drv_count)); |
1785 | } | 1782 | } |
1783 | /* | ||
1784 | * If done_list is not empty, then start_streaming() didn't call | ||
1785 | * vb2_buffer_done(vb, VB2_BUF_STATE_QUEUED) but STATE_ERROR or | ||
1786 | * STATE_DONE. | ||
1787 | */ | ||
1788 | WARN_ON(!list_empty(&q->done_list)); | ||
1786 | return ret; | 1789 | return ret; |
1787 | } | 1790 | } |
1788 | 1791 | ||