On 4/8/19 8:26 PM, Sakari Ailus wrote:
> Hi Bingbu,
> 
> Thanks for the patch.
> 
> On Fri, Mar 22, 2019 at 07:14:45PM +0800, bingbu....@intel.com wrote:
>> From: Bingbu Cao <bingbu....@intel.com>
>>
>> Current ImgU driver processes and releases the parameter buffer
>> immediately after queued from user. This does not align with other
>> image buffers which are grouped in sets and used for the same frame.
>> If user queues multiple parameter buffers continuously, only the last
>> one will take effect.
>> To make consistent buffers usage, this patch changes the parameter
>> buffer handling and group parameter buffer with other image buffers
>> for each frame.
>> Each time driver will queue one more group of buffers when previous
>> frame processed and buffers consumed by css.
>>
>> Signed-off-by: Tianshu Qiu <tian.shu....@intel.com>
>> Signed-off-by: Bingbu Cao <bingbu....@intel.com>
>> ---
>> changes since v1:
>> - add payload check for parameter buffer
>> - queue buffer only when previous buffer consumed
>> ---
>>  drivers/staging/media/ipu3/ipu3-css.c  |  5 ----
>>  drivers/staging/media/ipu3/ipu3-v4l2.c | 46 
>> ++++++++++++----------------------
>>  drivers/staging/media/ipu3/ipu3.c      | 30 ++++++++++++++++++++++
>>  3 files changed, 46 insertions(+), 35 deletions(-)
>>
>> diff --git a/drivers/staging/media/ipu3/ipu3-css.c 
>> b/drivers/staging/media/ipu3/ipu3-css.c
>> index 15ab77e4b766..018f5a266c42 100644
>> --- a/drivers/staging/media/ipu3/ipu3-css.c
>> +++ b/drivers/staging/media/ipu3/ipu3-css.c
>> @@ -2160,11 +2160,6 @@ int imgu_css_set_parameters(struct imgu_css *css, 
>> unsigned int pipe,
>>      obgrid_size = imgu_css_fw_obgrid_size(bi);
>>      stripes = bi->info.isp.sp.iterator.num_stripes ? : 1;
>>  
>> -    /*
>> -     * TODO(b/118782861): If userspace queues more than 4 buffers, the
>> -     * parameters from previous buffers will be overwritten. Fix the driver
>> -     * not to allow this.
>> -     */
>>      imgu_css_pool_get(&css_pipe->pool.parameter_set_info);
>>      param_set = imgu_css_pool_last(&css_pipe->pool.parameter_set_info,
>>                                     0)->vaddr;
>> diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c 
>> b/drivers/staging/media/ipu3/ipu3-v4l2.c
>> index 9c0352b193a7..87a7919c12f0 100644
>> --- a/drivers/staging/media/ipu3/ipu3-v4l2.cguess it'd take
significant changes to the code handling them, and there are more important
things to do. Just a note.
>> +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
>> @@ -341,8 +341,10 @@ static void imgu_vb2_buf_queue(struct vb2_buffer *vb)
>>      struct imgu_video_device *node =
>>              container_of(vb->vb2_queue, struct imgu_video_device, vbq);
>>      unsigned int queue = imgu_node_to_queue(node->id);
>> +    struct imgu_buffer *buf = container_of(vb, struct imgu_buffer,
>> +                                           vid_buf.vbb.vb2_buf);
>>      unsigned long need_bytes;
>> -    unsigned int pipe = node->pipe;
>> +    unsigned long payload = vb2_get_plane_payload(vb, 0);
>>  
>>      if (vb->vb2_queue->type == V4L2_BUF_TYPE_META_CAPTURE ||
>>          vb->vb2_queue->type == V4L2_BUF_TYPE_META_OUTPUT)
>> @@ -350,42 +352,26 @@ static void imgu_vb2_buf_queue(struct vb2_buffer *vb)
>>      else
>>              need_bytes = node->vdev_fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
>>  
>> -    if (queue == IPU3_CSS_QUEUE_PARAMS) {guess it'd take
significant changes to the code handling them, and there are more important
things to do. Just a note.
>> -            unsigned long payload = vb2_get_plane_payload(vb, 0);
>> -            struct vb2_v4l2_buffer *buf =
>> -                    container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
>> -            int r = -EINVAL;
>> -
>> -            if (payload == 0) {
>> -                    payload = need_bytes;
>> -                    vb2_set_plane_payload(vb, 0, payload);
>> -            }
>> -            if (payload >= need_bytes)
>> -                    r = imgu_css_set_parameters(&imgu->css, pipe,
>> -                                                vb2_plane_vaddr(vb, 0));
>> -            buf->flags = V4L2_BUF_FLAG_DONE;
>> -            vb2_buffer_done(vb, r == 0 ? VB2_BUF_STATE_DONE
>> -                                       : VB2_BUF_STATE_ERROR);
>> -
>> -    } else {
>> -            struct imgu_buffer *buf = container_of(vb, struct imgu_buffer,
>> -                                                   vid_buf.vbb.vb2_buf);
>> +    if (queue == IPU3_CSS_QUEUE_PARAMS && payload && payload < need_bytes) {
>> +            dev_err(&imgu->pci_dev->dev, "invalid data size for params.");
>> +            vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
> 
> This would better be done in buf_prepare callback --- you can return an
> error right away then. But it could well be another patch.
OK, thanks, I will add this into my TODO list.
> 
>> +            return;
>> +    }
>>  
>> -            mutex_lock(&imgu->lock);
>> +    mutex_lock(&imgu->lock);
>> +    if (queue != IPU3_CSS_QUEUE_PARAMS)
>>              imgu_css_buf_init(&buf->css_buf, queue, buf->map.daddr);
>> -            list_add_tail(&buf->vid_buf.list,
>> -                          &node->buffers);
>> -            mutex_unlock(&imgu->lock);
>>  
>> -            vb2_set_plane_payload(&buf->vid_buf.vbb.vb2_buf, 0, need_bytes);
>> +    list_add_tail(&buf->vid_buf.list, &node->buffers);
>> +    mutex_unlock(&imgu->lock);
>>  
>> -            if (imgu->streaming)
>> -                    imgu_queue_buffers(imgu, false, pipe);
>> -    }
>> +    vb2_set_plane_payload(vb, 0, need_bytes);
>> +
>> +    if (imgu->streaming)
>> +            imgu_queue_buffers(imgu, false, node->pipe);
>>  
>>      dev_dbg(&imgu->pci_dev->dev, "%s for pipe %d node %d", __func__,
>>              node->pipe, node->id);
>> -
>>  }
>>  
>>  static int imgu_vb2_queue_setup(struct vb2_queue *vq,
>> diff --git a/drivers/staging/media/ipu3/ipu3.c 
>> b/drivers/staging/media/ipu3/ipu3.c
>> index d575ac78c8f0..f1045072d535 100644
>> --- a/drivers/staging/media/ipu3/ipu3.c
>> +++ b/drivers/staging/media/ipu3/ipu3.c
>> @@ -236,6 +236,11 @@ int imgu_queue_buffers(struct imgu_device *imgu, bool 
>> initial, unsigned int pipe
>>      dev_dbg(&imgu->pci_dev->dev, "Queue buffers to pipe %d", pipe);
>>      mutex_lock(&imgu->lock);
>>  
>> +    if (!imgu_css_pipe_queue_empty(&imgu->css, pipe)) {
>> +            mutex_unlock(&imgu->lock);
>> +            return 0;
>> +    }
>> +
>>      /* Buffer set is queued to FW only when input buffer is ready */
>>      for (node = IMGU_NODE_NUM - 1;
>>           imgu_queue_getbuf(imgu, IMGU_NODE_IN, pipe);
>> @@ -246,6 +251,31 @@ int imgu_queue_buffers(struct imgu_device *imgu, bool 
>> initial, unsigned int pipe
>>                      dev_warn(&imgu->pci_dev->dev,
>>                               "Vf not enabled, ignore queue");
>>                      continue;
>> +            } else if (node == IMGU_NODE_PARAMS &&
>> +                       imgu_pipe->nodes[node].enabled) {
>> +                    struct vb2_buffer *vb;
>> +                    struct imgu_vb2_buffer *ivb;
>> +
>> +                    /* No parameters for this frame */
>> +                    if (list_empty(&imgu_pipe->nodes[node].buffers))
>> +                            continue;
>> +
>> +                    ivb = list_first_entry(&imgu_pipe->nodes[node].buffers,
>> +                                           struct imgu_vb2_buffer, list);
>> +                    vb = &ivb->vbb.vb2_buf;
>> +                    r = imgu_css_set_parameters(&imgu->css, pipe,
>> +                                                vb2_plane_vaddr(vb, 0));
>> +                    if (r) {
> 
> Ideally the parameters should be validated earlier but I guess it'd take
> significant changes to the code handling them, and there are more important
> things to do. Just a note.
> 
>> +                            vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
>> +                            dev_warn(&imgu->pci_dev->dev,
>> +                                     "set parameters failed.");
>> +                            continue;
>> +                    }
>> +
>> +                    vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
>> +                    dev_dbg(&imgu->pci_dev->dev,
>> +                            "queue user parameters %d to css.", vb->index);
> 
> %d -> %u.
> 
> I can fix that while applying the patch.
Thanks.
> 
>> +                    list_del(&ivb->list);
>>              } else if (imgu_pipe->queue_enabled[node]) {
>>                      struct imgu_css_buffer *buf =
>>                              imgu_queue_getbuf(imgu, node, pipe);
> 

Reply via email to