Re: [PATCH v4 5/7] media: rkisp1: Cache the currently active format

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jul 03, 2024 at 04:00:59PM +0300, Laurent Pinchart wrote:
> Hi Jacopo,
> 
> Thank you for the patch.
> 
> On Wed, Jul 03, 2024 at 12:19:48PM +0200, Jacopo Mondi wrote:
> > The rkisp1-params driver assumes the data buffer format is the only
> > currently supported "fixed" one. The usage of the "fixed" format is
> > assumed when allocating memory for the scratch buffers and when
> > initializing the vb2 queue.
> > 
> > In order to prepare to support the "extensible" format beside the
> > existing "fixed" one, add support in the driver for both formats by
> > caching a pointer to the active one in the driver structure and use it
> > in the vb2 queue operations and subdev pad operations implementations.
> > 
> > Do not yet allow userspace to select between the two formats as the
> > support for the "extensible" format parsing will be introduced in a later
> > patch in the series.
> > 
> > While at it, document the un-documented ycbcr_encoding field of
> > struct rkisp1_params_ops.
> > 
> > Signed-off-by: Jacopo Mondi <jacopo.mondi@xxxxxxxxxxxxxxxx>
> > ---
> >  .../platform/rockchip/rkisp1/rkisp1-common.h  |  8 ++-
> >  .../platform/rockchip/rkisp1/rkisp1-params.c  | 58 +++++++++++--------
> >  2 files changed, 40 insertions(+), 26 deletions(-)
> > 
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > index 8d520c5c71c3..43cc727a628d 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > @@ -255,7 +255,7 @@ struct rkisp1_buffer {
> >  struct rkisp1_params_buffer {
> >  	struct vb2_v4l2_buffer vb;
> >  	struct list_head queue;
> > -	struct rkisp1_params_cfg *cfg;
> > +	void *cfg;
> >  };
> >  
> >  static inline struct rkisp1_params_buffer *
> > @@ -392,8 +392,9 @@ struct rkisp1_params_ops {
> >   * @ops:		pointer to the variant-specific operations
> >   * @config_lock:	locks the buffer list 'params'
> >   * @params:		queue of rkisp1_buffer
> > - * @vdev_fmt:		v4l2_format of the metadata format
> > + * @metafmt		the currently enabled metadata format
> >   * @quantization:	the quantization configured on the isp's src pad
> > + * @ycbcr_encoding	the YCbCr encoding
> >   * @raw_type:		the bayer pattern on the isp video sink pad
> >   */
> >  struct rkisp1_params {
> > @@ -403,7 +404,8 @@ struct rkisp1_params {
> >  
> >  	spinlock_t config_lock; /* locks the buffers list 'params' */
> >  	struct list_head params;
> > -	struct v4l2_format vdev_fmt;
> > +
> > +	const struct v4l2_meta_format *metafmt;
> >  
> >  	enum v4l2_quantization quantization;
> >  	enum v4l2_ycbcr_encoding ycbcr_encoding;
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> > index 2d49038f8983..9444790c564f 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> > @@ -35,6 +35,22 @@
> >  #define RKISP1_ISP_CC_COEFF(n) \
> >  			(RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4)
> >  
> > +enum rkisp1_params_formats {
> > +	RKISP1_PARAMS_FIXED,
> > +	RKISP1_PARAMS_EXTENSIBLE,
> > +};
> > +
> > +static const struct v4l2_meta_format rkisp1_params_formats[] = {
> > +	[RKISP1_PARAMS_FIXED] = {
> > +		.dataformat = V4L2_META_FMT_RK_ISP1_PARAMS,
> > +		.buffersize = sizeof(struct rkisp1_params_cfg),
> > +	},
> > +	[RKISP1_PARAMS_EXTENSIBLE] = {
> > +		.dataformat = V4L2_META_FMT_RK_ISP1_EXT_PARAMS,
> > +		.buffersize = sizeof(struct rkisp1_ext_params_cfg),
> > +	},
> > +};
> > +
> >  static inline void
> >  rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
> >  {
> > @@ -1738,7 +1754,7 @@ static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv,
> >  	if (f->index > 0 || f->type != video->queue->type)
> >  		return -EINVAL;
> >  
> > -	f->pixelformat = params->vdev_fmt.fmt.meta.dataformat;
> > +	f->pixelformat = params->metafmt->dataformat;
> >  
> >  	return 0;
> >  }
> > @@ -1754,8 +1770,8 @@ static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh,
> >  		return -EINVAL;
> >  
> >  	memset(meta, 0, sizeof(*meta));
> > -	meta->dataformat = params->vdev_fmt.fmt.meta.dataformat;
> > -	meta->buffersize = params->vdev_fmt.fmt.meta.buffersize;
> > +	meta->dataformat = params->metafmt->dataformat;
> > +	meta->buffersize = params->metafmt->buffersize;
> >  
> >  	return 0;
> >  }
> > @@ -1798,13 +1814,15 @@ static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq,
> >  					 unsigned int sizes[],
> >  					 struct device *alloc_devs[])
> >  {
> > +	struct rkisp1_params *params = vq->drv_priv;
> > +
> >  	*num_buffers = clamp_t(u32, *num_buffers,
> >  			       RKISP1_ISP_PARAMS_REQ_BUFS_MIN,
> >  			       RKISP1_ISP_PARAMS_REQ_BUFS_MAX);
> >  
> >  	*num_planes = 1;
> >  
> > -	sizes[0] = sizeof(struct rkisp1_params_cfg);
> > +	sizes[0] = params->metafmt->buffersize;
> >  
> >  	return 0;
> >  }
> > @@ -1813,8 +1831,10 @@ static int rkisp1_params_vb2_buf_init(struct vb2_buffer *vb)
> >  {
> >  	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> >  	struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf);
> > +	struct rkisp1_params *params = vb->vb2_queue->drv_priv;
> >  
> > -	params_buf->cfg = kvmalloc(sizeof(*params_buf->cfg), GFP_KERNEL);
> > +	params_buf->cfg = kvmalloc(params->metafmt->buffersize,
> > +				   GFP_KERNEL);
> >  	if (!params_buf->cfg)
> >  		return -ENOMEM;
> >  
> > @@ -1849,16 +1869,14 @@ static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)
> >  	struct rkisp1_params_cfg *cfg =
> >  		vb2_plane_vaddr(&params_buf->vb.vb2_buf, 0);
> >  
> > -	if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg))
> > +	if (vb2_get_plane_payload(vb, 0) < sizeof(struct rkisp1_params_cfg))
> 
> sizeof(*cfg)
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
> 
> >  		return -EINVAL;
> >  
> > -	vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg));
> > -
> >  	/*
> >  	 * Copy the parameters buffer to the internal scratch buffer to avoid
> >  	 * userspace modifying the buffer content while the driver processes it.
> >  	 */
> > -	memcpy(params_buf->cfg, cfg, sizeof(*cfg));
> > +	memcpy(params_buf->cfg, cfg, vb2_get_plane_payload(vb, 0));

Actually I'm wondering if there's a risk that userspace could set a
payload size larger than the destination buffer, by passing a dmabuf (or
userptr) buffer larger than the destination size. Adding a

	if (vb2_get_plane_payload(vb, 0) > params->metafmt->buffersize)
		return -EINVAL;

above would make it safer. You can already introduce the local payload
size variable from patch 6/7 here. With, you still get my

Reviewed-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>

> >  
> >  	return 0;
> >  }
> > @@ -1921,19 +1939,6 @@ static int rkisp1_params_init_vb2_queue(struct vb2_queue *q,
> >  	return vb2_queue_init(q);
> >  }
> >  
> > -static void rkisp1_init_params(struct rkisp1_params *params)
> > -{
> > -	params->vdev_fmt.fmt.meta.dataformat =
> > -		V4L2_META_FMT_RK_ISP1_PARAMS;
> > -	params->vdev_fmt.fmt.meta.buffersize =
> > -		sizeof(struct rkisp1_params_cfg);
> > -
> > -	if (params->rkisp1->info->isp_ver == RKISP1_V12)
> > -		params->ops = &rkisp1_v12_params_ops;
> > -	else
> > -		params->ops = &rkisp1_v10_params_ops;
> > -}
> > -
> >  int rkisp1_params_register(struct rkisp1_device *rkisp1)
> >  {
> >  	struct rkisp1_params *params = &rkisp1->params;
> > @@ -1962,7 +1967,14 @@ int rkisp1_params_register(struct rkisp1_device *rkisp1)
> >  	vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;
> >  	vdev->vfl_dir = VFL_DIR_TX;
> >  	rkisp1_params_init_vb2_queue(vdev->queue, params);
> > -	rkisp1_init_params(params);
> > +
> > +	params->metafmt = &rkisp1_params_formats[RKISP1_PARAMS_FIXED];
> > +
> > +	if (params->rkisp1->info->isp_ver == RKISP1_V12)
> > +		params->ops = &rkisp1_v12_params_ops;
> > +	else
> > +		params->ops = &rkisp1_v10_params_ops;
> > +
> >  	video_set_drvdata(vdev, params);
> >  
> >  	node->pad.flags = MEDIA_PAD_FL_SOURCE;

-- 
Regards,

Laurent Pinchart




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux