Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee2f8133 authored by Hans Verkuil's avatar Hans Verkuil Committed by Greg Kroah-Hartman
Browse files

media: videobuf2-core: dequeue if start_streaming fails



[ Upstream commit c592b46907adbeb81243f7eb7a468c36692658b8 ]

If a vb2_queue sets q->min_buffers_needed then when the number of
queued buffers reaches q->min_buffers_needed, vb2_core_qbuf() will call
the start_streaming() callback. If start_streaming() returns an error,
then that error was just returned by vb2_core_qbuf(), but the buffer
was still queued. However, userspace expects that if VIDIOC_QBUF fails,
the buffer is returned dequeued.

So if start_streaming() fails, then remove the buffer from the queue,
thus avoiding this unwanted side-effect.

Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: default avatarKieran Bingham <kieran.bingham@ideasonboard.com>
Fixes: b3379c62 ("[media] vb2: only call start_streaming if sufficient buffers are queued")
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 3377f2f8
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -1512,6 +1512,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb,
		  struct media_request *req)
{
	struct vb2_buffer *vb;
	enum vb2_buffer_state orig_state;
	int ret;

	if (q->error) {
@@ -1611,6 +1612,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb,
	 * Add to the queued buffers list, a buffer will stay on it until
	 * dequeued in dqbuf.
	 */
	orig_state = vb->state;
	list_add_tail(&vb->queued_entry, &q->queued_list);
	q->queued_count++;
	q->waiting_for_buffers = false;
@@ -1641,9 +1643,18 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb,
	if (q->streaming && !q->start_streaming_called &&
	    q->queued_count >= q->min_buffers_needed) {
		ret = vb2_start_streaming(q);
		if (ret)
		if (ret) {
			/*
			 * Since vb2_core_qbuf will return with an error,
			 * we should return it to state DEQUEUED since
			 * the error indicates that the buffer wasn't queued.
			 */
			list_del(&vb->queued_entry);
			q->queued_count--;
			vb->state = orig_state;
			return ret;
		}
	}

	dprintk(2, "qbuf of buffer %d succeeded\n", vb->index);
	return 0;