[PATCH v2] media: stm32: dcmi: Switch to __v4l2_subdev_state_alloc()
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Wed Jun 29 05:20:59 PDT 2022
On Wed, Jun 29, 2022 at 03:14:54PM +0300, Tomi Valkeinen wrote:
> On 29/06/2022 12:41, Hans Verkuil wrote:
> > Hi Marek, Tomi, Laurent,
> >
> > On 27/06/2022 19:41, Marek Vasut wrote:
> >> Any local subdev state should be allocated and free'd using
> >> __v4l2_subdev_state_alloc()/__v4l2_subdev_state_free(), which
> >> takes care of calling .init_cfg() subdev op. Without this,
> >> subdev internal state might be uninitialized by the time
> >> any other subdev op is called.
> >>
> >> Signed-off-by: Marek Vasut <marex at denx.de>
> >> Cc: Alain Volmat <alain.volmat at foss.st.com>
> >> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> >> Cc: Amelie DELAUNAY <amelie.delaunay at foss.st.com>
> >> Cc: Hugues FRUCHET <hugues.fruchet at foss.st.com>
> >> Cc: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> >> Cc: Philippe CORNU <philippe.cornu at foss.st.com>
> >> Cc: linux-stm32 at st-md-mailman.stormreply.com
> >> Cc: linux-arm-kernel at lists.infradead.org
> >> ---
> >> V2: Add FIXME comment above __v4l2_subdev_state_alloc() calls
> >> ---
> >> drivers/media/platform/st/stm32/stm32-dcmi.c | 59 ++++++++++++--------
> >> 1 file changed, 37 insertions(+), 22 deletions(-)
> >>
> >> diff --git a/drivers/media/platform/st/stm32/stm32-dcmi.c b/drivers/media/platform/st/stm32/stm32-dcmi.c
> >> index c604d672c2156..c68d32931b277 100644
> >> --- a/drivers/media/platform/st/stm32/stm32-dcmi.c
> >> +++ b/drivers/media/platform/st/stm32/stm32-dcmi.c
> >> @@ -996,22 +996,30 @@ static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f,
> >> struct dcmi_framesize *sd_framesize)
> >> {
> >> const struct dcmi_format *sd_fmt;
> >> + static struct lock_class_key key;
> >> struct dcmi_framesize sd_fsize;
> >> struct v4l2_pix_format *pix = &f->fmt.pix;
> >> - struct v4l2_subdev_pad_config pad_cfg;
> >> - struct v4l2_subdev_state pad_state = {
> >> - .pads = &pad_cfg
> >> - };
> >> + struct v4l2_subdev_state *sd_state;
> >> struct v4l2_subdev_format format = {
> >> .which = V4L2_SUBDEV_FORMAT_TRY,
> >> };
> >> bool do_crop;
> >> int ret;
> >>
> >> + /*
> >> + * FIXME: Drop this call, drivers are not supposed to use
> >> + * __v4l2_subdev_state_alloc().
> >> + */
> >> + sd_state = __v4l2_subdev_state_alloc(dcmi->source, "dcmi:state->lock", &key);
> >> + if (IS_ERR(sd_state))
> >> + return PTR_ERR(sd_state);
> >> +
> >
> > I've been reading the discussion for the v1 patch, and I seriously do not like this.
>
> I don't like it either.
>
> > My comments are not specifically for this patch, but for all cases where
> > __v4l2_subdev_state_alloc is called.
>
> Just to emphasize it: afaics this is not an issue with the subdev state.
> This driver was already broken. Before the subdev state change the fix
> would have been to call source subdev's init_cfg. Now
> __v4l2_subdev_state_alloc handles calling init_cfg (along with a few
> other inits).
>
> > It is now used in 4 drivers, so that's no longer a rare case, and the code isn't
> > exactly trivial either.
>
> Counting this one? I found 3 cases in v5.18-rc4:
>
> 1) drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c:
>
> Allocates the state for v4l2_subdev_call, set_fmt, TRY.
>
> Here, a helper macro which does the alloc would be a solution.
>
> 2) drivers/media/platform/renesas/vsp1/vsp1_entity.c:
>
> Allocates the state for storing internal active state.
>
> Here, I think, the easiest fix is for the driver to use the subdev state
> properly.
>
> 3) drivers/staging/media/tegra-video/vi.c:
>
> Allocates the state for v4l2_subdev_call, enum_frame_size and set_fmt,
> TRY. Interestingly the code also calls get_selection but without passing
> the state...
>
> This is a more interesting case as the source's subdev state is actually
> modified by the driver. The driver calls enum_frame_size, then modifies
> the state, then calls set_fmt. I'm not sure if that's really legal...
> The driver directly modifies the state, instead of calling set_selection?
>
> > I think a helper function might be beneficial, but the real problem is with the
> > comment: it does not explain why you shouldn't use it and what needs to be done
> > to fix it.
>
> That is true. There's no single answer to that. I think instead of
> trying to document that in the v4l2-subdev doc, we can enhance the
> comments in those three call sites to explain how it needs to be fixed.
>
> > My suggestion would be to document that in the kerneldoc for this function in
> > media/v4l2-subdev.h, and then refer to that from this comment (and similar comments
> > in the other drivers that use this).
> >
> > And another question: are more drivers affected by this? Is it possible to
> > find those and fix them all?
>
> I think any driver that calls a source subdev's subdev ops which a
> subdev state as a parameter (the ones that used to take
> v4l2_subdev_pad_config), and does not call init_cfg is broken in the
> same way. With some grepping, I couldn't find anyone calling init_cfg.
> Finding those drivers which do those calls is a bit more difficult, but
> can be done with some efforts.
A quick check identified the following files:
atmel-isc-base.c
atmel-isi.c
cxusb-analog.c
fimc-capture.c
mcam-core.c
pxa_camera.c
renesas-ceu.c
saa7134-empress.c
via-camera.c
A few drivers with more complex call patterns may be missing.
> atmel-isc-base.c is one I found, and looks like it's doing something a
> bit similar to the 3) case above.
>
> Perhaps the best way to solve this is just to remove the underscores
> from __v4l2_subdev_state_alloc, and change all the drivers which create
> temporary v4l2_subdev_states to use that (and the free) functions. And
> also create the helper macro which can be used in those cases where the
> call is simple (the state is not modified or accessed by the caller).
As long as we prevent any new driver from using that API, that's fine
with me.
> It would've been nice to keep __v4l2_subdev_state_alloc internal to the
> v4l2-subdev, but maybe the v4l2 drivers are not there yet. The non-MC
> drivers seem to be doing all kinds of interesting things.
--
Regards,
Laurent Pinchart
More information about the linux-arm-kernel
mailing list