Re: [PATCH v3 15/29] media: v4l2-subdev: Return dynamically allocated pass-through routes
Frank Li <[email protected]>
| Newsgroups | org.kernel.vger.linux-media |
|---|---|
| Message-ID | <aoyw4BDB21IgUc3V@lizhi-Precision-Tower-5810> |
On Mon, Aug 24, 2026 at 03:14:37PM +0300, Sakari Ailus wrote: > Count the number of pass-through routes, allocate memory and then return > the full table to the caller. > > Signed-off-by: Sakari Ailus <[email protected]> > --- > drivers/media/v4l2-core/v4l2-subdev.c | 61 +++++++++++++++++++++++---- > 1 file changed, 52 insertions(+), 9 deletions(-) > > diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c > index c9f38b0313eb..d34704aad88e 100644 > --- a/drivers/media/v4l2-core/v4l2-subdev.c > +++ b/drivers/media/v4l2-core/v4l2-subdev.c > @@ -2561,13 +2561,42 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd, > struct media_pad *local_sink_pad; > struct v4l2_subdev_route *route; > struct device *dev = sd->dev; > - int ret = 0; > + unsigned int num_entries = 0; > + int ret; > > lockdep_assert_held(state->lock); > > if (WARN_ON(!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))) > return -EINVAL; > > + /* Count the number of entries first */ > + media_entity_for_each_pad(&sd->entity, local_sink_pad) { > + if (!(local_sink_pad->flags & MEDIA_PAD_FL_SINK)) > + continue; > + > + for_each_active_route(&state->routing, route) { > + if (route->source_pad != pad || > + route->sink_pad != local_sink_pad->index) > + continue; > + > + num_entries++; > + > + if (num_entries > V4L2_FRAME_DESC_ENTRY_MAX) > + return -E2BIG; > + } > + } > + > + if (num_entries > V4L2_FRAME_DESC_ENTRY_MAX) > + return -E2BIG; > + > + if (num_entries > V4L2_FRAME_DESC_ENTRY_PREALLOC) { > + fd->entry = kzalloc_objs(*fd->entry, num_entries, GFP_KERNEL); nit: Default should be GFP_KERNEL, needn't GFP_KERNEL when call kzalloc_objs() Reviewed-by: Frank Li <[email protected]> > + if (!fd->entry) > + return -ENOMEM; > + > + fd->len_entries = num_entries; > + } > + > /* Iterate over sink pads */ > media_entity_for_each_pad(&sd->entity, local_sink_pad) { > struct v4l2_mbus_frame_desc source_fd; > @@ -2594,12 +2623,15 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd, > if (IS_ERR(remote_source_pad)) { > dev_dbg(dev, "Failed to find remote pad for sink pad %u\n", > local_sink_pad->index); > - return PTR_ERR(remote_source_pad); > + ret = PTR_ERR(remote_source_pad); > + goto err_free; > } > > remote_sd = media_entity_to_v4l2_subdev(remote_source_pad->entity); > - if (!remote_sd) > - return -EINVAL; > + if (!remote_sd) { > + ret = -EINVAL; > + goto err_free; > + } > > ret = v4l2_subdev_call(remote_sd, pad, > get_frame_desc, > @@ -2609,7 +2641,7 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd, > dev_err(dev, > "Failed to get frame desc from remote subdev %s\n", > remote_sd->name); > - return ret; > + goto err_free; > } > > have_source_fd = true; > @@ -2620,7 +2652,8 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd, > dev_err(dev, > "Frame desc type mismatch: %u != %u\n", > fd->type, source_fd.type); > - return -EPIPE; > + ret = -EPIPE; > + goto err_free; > } > } > > @@ -2635,12 +2668,14 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd, > dev_dbg(dev, > "Failed to find stream %u from source frame desc\n", > route->sink_stream); > - return -EPIPE; > + ret = -EPIPE; > + goto err_free; > } > > - if (fd->num_entries >= V4L2_FRAME_DESC_ENTRY_PREALLOC) { > + if (fd->num_entries >= fd->len_entries) { > dev_dbg(dev, "Frame desc entry limit reached\n"); > - return -E2BIG; > + ret = -E2BIG; > + goto err_free; > } > > fd->entry[fd->num_entries] = *source_entry; > @@ -2652,6 +2687,14 @@ int __v4l2_subdev_get_frame_desc_passthrough(struct v4l2_subdev *sd, > } Is it simpler if __free(kfree) *p = kzalloc_objs(*fd->entry, num_entries); fd->entry = no_free_ptr(p); fd->num_entries = > > return 0; > + > +err_free: > + kfree(fd->entry); > + fd->entry = fd->entry_mem; > + fd->num_entries = 0; > + fd->len_entries = V4L2_FRAME_DESC_ENTRY_PREALLOC; > + > + return ret; > } > EXPORT_SYMBOL_GPL(__v4l2_subdev_get_frame_desc_passthrough); > > -- > 2.47.3 >