Skip to content

Commit b3379c6

Browse files
Hans Verkuilmchehab
Hans Verkuil
authored andcommitted
[media] vb2: only call start_streaming if sufficient buffers are queued
In commit 02f142e support was added to start_streaming to return -ENOBUFS if insufficient buffers were queued for the DMA engine to start. The vb2 core would attempt calling start_streaming again if another buffer would be queued up. Later analysis uncovered problems with the queue management if start_streaming would return an error: the buffers are enqueued to the driver before the start_streaming op is called, so after an error they are never returned to the vb2 core. The solution for this is to let the driver return them to the vb2 core in case of an error while starting the DMA engine. However, in the case of -ENOBUFS that would be weird: it is not a real error, it just says that more buffers are needed. Requiring start_streaming to give them back only to have them requeued again the next time the application calls QBUF is inefficient. This patch changes this mechanism: it adds a 'min_buffers_needed' field to vb2_queue that drivers can set with the minimum number of buffers required to start the DMA engine. The start_streaming op is only called if enough buffers are queued. The -ENOBUFS handling has been dropped in favor of this new method. Drivers are expected to return buffers back to vb2 core with state QUEUED if start_streaming would return an error. The vb2 core checks for this and produces a warning if that didn't happen and it will forcefully reclaim such buffers to ensure that the internal vb2 core state remains consistent and all buffer-related resources have been correctly freed and all op calls have been balanced. __reqbufs() has been updated to check that at least min_buffers_needed buffers could be allocated. If fewer buffers were allocated then __reqbufs will free what was allocated and return -ENOMEM. Based on a suggestion from Pawel Osciak. __create_bufs() doesn't do that check, since the use of __create_bufs assumes some advance scenario where the user might want more control. Instead streamon will check if enough buffers were allocated to prevent streaming with fewer than the minimum required number of buffers. Signed-off-by: Hans Verkuil <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent a7afcac commit b3379c6

File tree

7 files changed

+116
-73
lines changed

7 files changed

+116
-73
lines changed

drivers/media/platform/davinci/vpbe_display.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -344,11 +344,6 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
344344
struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
345345
int ret;
346346

347-
/* If buffer queue is empty, return error */
348-
if (list_empty(&layer->dma_queue)) {
349-
v4l2_err(&vpbe_dev->v4l2_dev, "buffer queue is empty\n");
350-
return -ENOBUFS;
351-
}
352347
/* Get the next frame from the buffer queue */
353348
layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
354349
struct vpbe_disp_buffer, list);
@@ -1416,6 +1411,7 @@ static int vpbe_display_reqbufs(struct file *file, void *priv,
14161411
q->mem_ops = &vb2_dma_contig_memops;
14171412
q->buf_struct_size = sizeof(struct vpbe_disp_buffer);
14181413
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1414+
q->min_buffers_needed = 1;
14191415

14201416
ret = vb2_queue_init(q);
14211417
if (ret) {

drivers/media/platform/davinci/vpif_capture.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -272,13 +272,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
272272
unsigned long flags;
273273
int ret;
274274

275-
/* If buffer queue is empty, return error */
276275
spin_lock_irqsave(&common->irqlock, flags);
277-
if (list_empty(&common->dma_queue)) {
278-
spin_unlock_irqrestore(&common->irqlock, flags);
279-
vpif_dbg(1, debug, "buffer queue is empty\n");
280-
return -ENOBUFS;
281-
}
282276

283277
/* Get the next frame from the buffer queue */
284278
common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
@@ -1024,6 +1018,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
10241018
q->mem_ops = &vb2_dma_contig_memops;
10251019
q->buf_struct_size = sizeof(struct vpif_cap_buffer);
10261020
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1021+
q->min_buffers_needed = 1;
10271022

10281023
ret = vb2_queue_init(q);
10291024
if (ret) {

drivers/media/platform/davinci/vpif_display.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
234234
unsigned long flags;
235235
int ret;
236236

237-
/* If buffer queue is empty, return error */
238237
spin_lock_irqsave(&common->irqlock, flags);
239-
if (list_empty(&common->dma_queue)) {
240-
spin_unlock_irqrestore(&common->irqlock, flags);
241-
vpif_err("buffer queue is empty\n");
242-
return -ENOBUFS;
243-
}
244238

245239
/* Get the next frame from the buffer queue */
246240
common->next_frm = common->cur_frm =
@@ -984,6 +978,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
984978
q->mem_ops = &vb2_dma_contig_memops;
985979
q->buf_struct_size = sizeof(struct vpif_disp_buffer);
986980
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
981+
q->min_buffers_needed = 1;
987982

988983
ret = vb2_queue_init(q);
989984
if (ret) {

drivers/media/platform/s5p-tv/mixer_video.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -946,11 +946,6 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
946946

947947
mxr_dbg(mdev, "%s\n", __func__);
948948

949-
if (count == 0) {
950-
mxr_dbg(mdev, "no output buffers queued\n");
951-
return -ENOBUFS;
952-
}
953-
954949
/* block any changes in output configuration */
955950
mxr_output_get(mdev);
956951

@@ -1124,6 +1119,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
11241119
.drv_priv = layer,
11251120
.buf_struct_size = sizeof(struct mxr_buffer),
11261121
.ops = &mxr_video_qops,
1122+
.min_buffers_needed = 1,
11271123
.mem_ops = &vb2_dma_contig_memops,
11281124
};
11291125

drivers/media/v4l2-core/videobuf2-core.c

Lines changed: 101 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
818818
* Make sure the requested values and current defaults are sane.
819819
*/
820820
num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME);
821+
num_buffers = max_t(unsigned int, req->count, q->min_buffers_needed);
821822
memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
822823
memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
823824
q->memory = req->memory;
@@ -840,10 +841,17 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
840841
return -ENOMEM;
841842
}
842843

844+
/*
845+
* There is no point in continuing if we can't allocate the minimum
846+
* number of buffers needed by this vb2_queue.
847+
*/
848+
if (allocated_buffers < q->min_buffers_needed)
849+
ret = -ENOMEM;
850+
843851
/*
844852
* Check if driver can handle the allocated number of buffers.
845853
*/
846-
if (allocated_buffers < num_buffers) {
854+
if (!ret && allocated_buffers < num_buffers) {
847855
num_buffers = allocated_buffers;
848856

849857
ret = call_qop(q, queue_setup, q, NULL, &num_buffers,
@@ -1051,25 +1059,38 @@ EXPORT_SYMBOL_GPL(vb2_plane_cookie);
10511059
* vb2_buffer_done() - inform videobuf that an operation on a buffer is finished
10521060
* @vb: vb2_buffer returned from the driver
10531061
* @state: either VB2_BUF_STATE_DONE if the operation finished successfully
1054-
* or VB2_BUF_STATE_ERROR if the operation finished with an error
1062+
* or VB2_BUF_STATE_ERROR if the operation finished with an error.
1063+
* If start_streaming fails then it should return buffers with state
1064+
* VB2_BUF_STATE_QUEUED to put them back into the queue.
10551065
*
10561066
* This function should be called by the driver after a hardware operation on
10571067
* a buffer is finished and the buffer may be returned to userspace. The driver
10581068
* cannot use this buffer anymore until it is queued back to it by videobuf
10591069
* by the means of buf_queue callback. Only buffers previously queued to the
10601070
* driver by buf_queue can be passed to this function.
1071+
*
1072+
* While streaming a buffer can only be returned in state DONE or ERROR.
1073+
* The start_streaming op can also return them in case the DMA engine cannot
1074+
* be started for some reason. In that case the buffers should be returned with
1075+
* state QUEUED.
10611076
*/
10621077
void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
10631078
{
10641079
struct vb2_queue *q = vb->vb2_queue;
10651080
unsigned long flags;
10661081
unsigned int plane;
10671082

1068-
if (vb->state != VB2_BUF_STATE_ACTIVE)
1083+
if (WARN_ON(vb->state != VB2_BUF_STATE_ACTIVE))
10691084
return;
10701085

1071-
if (state != VB2_BUF_STATE_DONE && state != VB2_BUF_STATE_ERROR)
1072-
return;
1086+
if (!q->start_streaming_called) {
1087+
if (WARN_ON(state != VB2_BUF_STATE_QUEUED))
1088+
state = VB2_BUF_STATE_QUEUED;
1089+
} else if (!WARN_ON(!q->start_streaming_called)) {
1090+
if (WARN_ON(state != VB2_BUF_STATE_DONE &&
1091+
state != VB2_BUF_STATE_ERROR))
1092+
state = VB2_BUF_STATE_ERROR;
1093+
}
10731094

10741095
#ifdef CONFIG_VIDEO_ADV_DEBUG
10751096
/*
@@ -1088,10 +1109,14 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
10881109
/* Add the buffer to the done buffers list */
10891110
spin_lock_irqsave(&q->done_lock, flags);
10901111
vb->state = state;
1091-
list_add_tail(&vb->done_entry, &q->done_list);
1112+
if (state != VB2_BUF_STATE_QUEUED)
1113+
list_add_tail(&vb->done_entry, &q->done_list);
10921114
atomic_dec(&q->owned_by_drv_count);
10931115
spin_unlock_irqrestore(&q->done_lock, flags);
10941116

1117+
if (state == VB2_BUF_STATE_QUEUED)
1118+
return;
1119+
10951120
/* Inform any processes that may be waiting for buffers */
10961121
wake_up(&q->done_wq);
10971122
}
@@ -1588,34 +1613,49 @@ EXPORT_SYMBOL_GPL(vb2_prepare_buf);
15881613
* vb2_start_streaming() - Attempt to start streaming.
15891614
* @q: videobuf2 queue
15901615
*
1591-
* If there are not enough buffers, then retry_start_streaming is set to
1592-
* 1 and 0 is returned. The next time a buffer is queued and
1593-
* retry_start_streaming is 1, this function will be called again to
1594-
* retry starting the DMA engine.
1616+
* Attempt to start streaming. When this function is called there must be
1617+
* at least q->min_buffers_needed buffers queued up (i.e. the minimum
1618+
* number of buffers required for the DMA engine to function). If the
1619+
* @start_streaming op fails it is supposed to return all the driver-owned
1620+
* buffers back to vb2 in state QUEUED. Check if that happened and if
1621+
* not warn and reclaim them forcefully.
15951622
*/
15961623
static int vb2_start_streaming(struct vb2_queue *q)
15971624
{
1625+
struct vb2_buffer *vb;
15981626
int ret;
15991627

1600-
/* Tell the driver to start streaming */
1601-
ret = call_qop(q, start_streaming, q, atomic_read(&q->owned_by_drv_count));
1602-
if (ret)
1603-
fail_qop(q, start_streaming);
1604-
16051628
/*
1606-
* If there are not enough buffers queued to start streaming, then
1607-
* the start_streaming operation will return -ENOBUFS and you have to
1608-
* retry when the next buffer is queued.
1629+
* If any buffers were queued before streamon,
1630+
* we can now pass them to driver for processing.
16091631
*/
1610-
if (ret == -ENOBUFS) {
1611-
dprintk(1, "qbuf: not enough buffers, retry when more buffers are queued.\n");
1612-
q->retry_start_streaming = 1;
1632+
list_for_each_entry(vb, &q->queued_list, queued_entry)
1633+
__enqueue_in_driver(vb);
1634+
1635+
/* Tell the driver to start streaming */
1636+
ret = call_qop(q, start_streaming, q,
1637+
atomic_read(&q->owned_by_drv_count));
1638+
q->start_streaming_called = ret == 0;
1639+
if (!ret)
16131640
return 0;
1641+
1642+
fail_qop(q, start_streaming);
1643+
dprintk(1, "qbuf: driver refused to start streaming\n");
1644+
if (WARN_ON(atomic_read(&q->owned_by_drv_count))) {
1645+
unsigned i;
1646+
1647+
/*
1648+
* Forcefully reclaim buffers if the driver did not
1649+
* correctly return them to vb2.
1650+
*/
1651+
for (i = 0; i < q->num_buffers; ++i) {
1652+
vb = q->bufs[i];
1653+
if (vb->state == VB2_BUF_STATE_ACTIVE)
1654+
vb2_buffer_done(vb, VB2_BUF_STATE_QUEUED);
1655+
}
1656+
/* Must be zero now */
1657+
WARN_ON(atomic_read(&q->owned_by_drv_count));
16141658
}
1615-
if (ret)
1616-
dprintk(1, "qbuf: driver refused to start streaming\n");
1617-
else
1618-
q->retry_start_streaming = 0;
16191659
return ret;
16201660
}
16211661

@@ -1651,6 +1691,7 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
16511691
* dequeued in dqbuf.
16521692
*/
16531693
list_add_tail(&vb->queued_entry, &q->queued_list);
1694+
q->queued_count++;
16541695
vb->state = VB2_BUF_STATE_QUEUED;
16551696
if (V4L2_TYPE_IS_OUTPUT(q->type)) {
16561697
/*
@@ -1669,13 +1710,20 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
16691710
* If already streaming, give the buffer to driver for processing.
16701711
* If not, the buffer will be given to driver on next streamon.
16711712
*/
1672-
if (q->streaming)
1713+
if (q->start_streaming_called)
16731714
__enqueue_in_driver(vb);
16741715

16751716
/* Fill buffer information for the userspace */
16761717
__fill_v4l2_buffer(vb, b);
16771718

1678-
if (q->retry_start_streaming) {
1719+
/*
1720+
* If streamon has been called, and we haven't yet called
1721+
* start_streaming() since not enough buffers were queued, and
1722+
* we now have reached the minimum number of queued buffers,
1723+
* then we can finally call start_streaming().
1724+
*/
1725+
if (q->streaming && !q->start_streaming_called &&
1726+
q->queued_count >= q->min_buffers_needed) {
16791727
ret = vb2_start_streaming(q);
16801728
if (ret)
16811729
return ret;
@@ -1830,7 +1878,7 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q)
18301878
return -EINVAL;
18311879
}
18321880

1833-
if (!q->retry_start_streaming)
1881+
if (q->start_streaming_called)
18341882
wait_event(q->done_wq, !atomic_read(&q->owned_by_drv_count));
18351883
return 0;
18361884
}
@@ -1891,6 +1939,7 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n
18911939
__fill_v4l2_buffer(vb, b);
18921940
/* Remove from videobuf queue */
18931941
list_del(&vb->queued_entry);
1942+
q->queued_count--;
18941943
/* go back to dequeued state */
18951944
__vb2_dqbuf(vb);
18961945

@@ -1941,18 +1990,23 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
19411990
{
19421991
unsigned int i;
19431992

1944-
if (q->retry_start_streaming) {
1945-
q->retry_start_streaming = 0;
1946-
q->streaming = 0;
1947-
}
1948-
19491993
/*
19501994
* Tell driver to stop all transactions and release all queued
19511995
* buffers.
19521996
*/
1953-
if (q->streaming)
1997+
if (q->start_streaming_called)
19541998
call_qop(q, stop_streaming, q);
19551999
q->streaming = 0;
2000+
q->start_streaming_called = 0;
2001+
q->queued_count = 0;
2002+
2003+
if (WARN_ON(atomic_read(&q->owned_by_drv_count))) {
2004+
for (i = 0; i < q->num_buffers; ++i)
2005+
if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE)
2006+
vb2_buffer_done(q->bufs[i], VB2_BUF_STATE_ERROR);
2007+
/* Must be zero now */
2008+
WARN_ON(atomic_read(&q->owned_by_drv_count));
2009+
}
19562010

19572011
/*
19582012
* Remove all buffers from videobuf's list...
@@ -1988,7 +2042,6 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
19882042

19892043
static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
19902044
{
1991-
struct vb2_buffer *vb;
19922045
int ret;
19932046

19942047
if (type != q->type) {
@@ -2010,19 +2063,22 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
20102063
dprintk(1, "streamon: no buffers have been allocated\n");
20112064
return -EINVAL;
20122065
}
2066+
if (q->num_buffers < q->min_buffers_needed) {
2067+
dprintk(1, "streamon: need at least %u allocated buffers\n",
2068+
q->min_buffers_needed);
2069+
return -EINVAL;
2070+
}
20132071

20142072
/*
2015-
* If any buffers were queued before streamon,
2016-
* we can now pass them to driver for processing.
2073+
* Tell driver to start streaming provided sufficient buffers
2074+
* are available.
20172075
*/
2018-
list_for_each_entry(vb, &q->queued_list, queued_entry)
2019-
__enqueue_in_driver(vb);
2020-
2021-
/* Tell driver to start streaming. */
2022-
ret = vb2_start_streaming(q);
2023-
if (ret) {
2024-
__vb2_queue_cancel(q);
2025-
return ret;
2076+
if (q->queued_count >= q->min_buffers_needed) {
2077+
ret = vb2_start_streaming(q);
2078+
if (ret) {
2079+
__vb2_queue_cancel(q);
2080+
return ret;
2081+
}
20262082
}
20272083

20282084
q->streaming = 1;

drivers/staging/media/davinci_vpfe/vpfe_video.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,8 +1201,6 @@ static int vpfe_start_streaming(struct vb2_queue *vq, unsigned int count)
12011201
unsigned long addr;
12021202
int ret;
12031203

1204-
if (count == 0)
1205-
return -ENOBUFS;
12061204
ret = mutex_lock_interruptible(&video->lock);
12071205
if (ret)
12081206
goto streamoff;
@@ -1327,6 +1325,7 @@ static int vpfe_reqbufs(struct file *file, void *priv,
13271325
q->type = req_buf->type;
13281326
q->io_modes = VB2_MMAP | VB2_USERPTR;
13291327
q->drv_priv = fh;
1328+
q->min_buffers_needed = 1;
13301329
q->ops = &video_qops;
13311330
q->mem_ops = &vb2_dma_contig_memops;
13321331
q->buf_struct_size = sizeof(struct vpfe_cap_buffer);

0 commit comments

Comments
 (0)