Message ID | 20200922113402.12442-2-dafna.hirschfeld@collabora.com |
---|---|
State | Accepted |
Commit | b1b2715e8d616bab68ed4e22b6617601105f2947 |
Headers | show |
Series | [v3,01/12] media: staging: rkisp1: params: upon stream stop, iterate a local list to return the buffers | expand |
Hi Dafna, On Tue, Sep 22, 2020 at 01:33:51PM +0200, Dafna Hirschfeld wrote: > The code in '.stop_streaming' callback releases and acquire the lock > at each iteration when returning the buffers. > Holding the lock disables interrupts so it should be minimized. > To make the code cleaner and still minimize holding the lock, > the buffer list is first moved to a local list and > then can be iterated without the lock. > > Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com> > Acked-by: Helen Koike <helen.koike@collabora.com> > --- > drivers/staging/media/rkisp1/rkisp1-params.c | 31 +++++++------------- > 1 file changed, 11 insertions(+), 20 deletions(-) > Thank you for the patch. Please see my comments inline. > diff --git a/drivers/staging/media/rkisp1/rkisp1-params.c b/drivers/staging/media/rkisp1/rkisp1-params.c > index 3ca2afc51ead..85f3b340c3bf 100644 > --- a/drivers/staging/media/rkisp1/rkisp1-params.c > +++ b/drivers/staging/media/rkisp1/rkisp1-params.c > @@ -1469,32 +1469,23 @@ static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq) > { > struct rkisp1_params *params = vq->drv_priv; > struct rkisp1_buffer *buf; > + struct list_head tmp_list; > unsigned long flags; > - unsigned int i; > > - /* stop params input firstly */ > + INIT_LIST_HEAD(&tmp_list); nit: This could be done at declaration time by using the LIST_HEAD() macro to declare the list head. > + > + /* > + * we first move the buffers into a local list 'tmp_list' > + * and then we can iterate it and call vb2_buffer_done > + * without holding the lock > + */ > spin_lock_irqsave(¶ms->config_lock, flags); > params->is_streaming = false; > + list_cut_position(&tmp_list, ¶ms->params, params->params.prev); nit: This is equivalent to list_splice_init(¶ms->params, &tmp_list); with a simpler interface and without the need to dereference params->params.prev manually. Best regards, Tomasz
diff --git a/drivers/staging/media/rkisp1/rkisp1-params.c b/drivers/staging/media/rkisp1/rkisp1-params.c index 3ca2afc51ead..85f3b340c3bf 100644 --- a/drivers/staging/media/rkisp1/rkisp1-params.c +++ b/drivers/staging/media/rkisp1/rkisp1-params.c @@ -1469,32 +1469,23 @@ static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq) { struct rkisp1_params *params = vq->drv_priv; struct rkisp1_buffer *buf; + struct list_head tmp_list; unsigned long flags; - unsigned int i; - /* stop params input firstly */ + INIT_LIST_HEAD(&tmp_list); + + /* + * we first move the buffers into a local list 'tmp_list' + * and then we can iterate it and call vb2_buffer_done + * without holding the lock + */ spin_lock_irqsave(¶ms->config_lock, flags); params->is_streaming = false; + list_cut_position(&tmp_list, ¶ms->params, params->params.prev); spin_unlock_irqrestore(¶ms->config_lock, flags); - for (i = 0; i < RKISP1_ISP_PARAMS_REQ_BUFS_MAX; i++) { - spin_lock_irqsave(¶ms->config_lock, flags); - if (!list_empty(¶ms->params)) { - buf = list_first_entry(¶ms->params, - struct rkisp1_buffer, queue); - list_del(&buf->queue); - spin_unlock_irqrestore(¶ms->config_lock, - flags); - } else { - spin_unlock_irqrestore(¶ms->config_lock, - flags); - break; - } - - if (buf) - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); - buf = NULL; - } + list_for_each_entry(buf, &tmp_list, queue) + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); } static int