[4/8] media: v4l2-subdev: Refactor warnings in v4l2_subdev_link_validate()

Message ID 20240619012356.22685-5-laurent.pinchart+renesas@ideasonboard.com (mailing list archive)
State New
Headers
Series media: v4l2: Improve media link validation |

Commit Message

Laurent Pinchart June 19, 2024, 1:23 a.m. UTC
  The v4l2_subdev_link_validate() function prints a one-time warning if it
gets called on a link whose source or sink is not a subdev. As links get
validated in the context of their sink, a call to the helper when the
link's sink is not a subdev indicates that the driver has set its
.link_validate() handler to v4l2_subdev_link_validate() on a non-subdev
entity, which is a clear driver bug. On the other hand, the link's
source not being a subdev indicates that the helper is used for a subdev
connected to a video output device, which is a lesser issue, if only
because this is currently common practice.

There are no drivers left in the kernel that use
v4l2_subdev_link_validate() in a context where it may get called on a
non-subdev sink. Replace the pr_warn_once() with a WARN_ON() in this
case to make sure that new offenders won't be introduced.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/v4l2-core/v4l2-subdev.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
  

Comments

Sakari Ailus June 22, 2024, 4:47 p.m. UTC | #1
Hi Laurent,

Thanks for the patch.

On Wed, Jun 19, 2024 at 04:23:52AM +0300, Laurent Pinchart wrote:
> The v4l2_subdev_link_validate() function prints a one-time warning if it
> gets called on a link whose source or sink is not a subdev. As links get
> validated in the context of their sink, a call to the helper when the
> link's sink is not a subdev indicates that the driver has set its
> .link_validate() handler to v4l2_subdev_link_validate() on a non-subdev
> entity, which is a clear driver bug. On the other hand, the link's
> source not being a subdev indicates that the helper is used for a subdev
> connected to a video output device, which is a lesser issue, if only
> because this is currently common practice.
> 
> There are no drivers left in the kernel that use
> v4l2_subdev_link_validate() in a context where it may get called on a
> non-subdev sink. Replace the pr_warn_once() with a WARN_ON() in this
> case to make sure that new offenders won't be introduced.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/media/v4l2-core/v4l2-subdev.c | 14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> index 4f71199bf592..2d5e39c79620 100644
> --- a/drivers/media/v4l2-core/v4l2-subdev.c
> +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> @@ -1451,11 +1451,15 @@ int v4l2_subdev_link_validate(struct media_link *link)
>  	bool states_locked;
>  	int ret;
>  
> -	if (!is_media_entity_v4l2_subdev(link->sink->entity) ||
> -	    !is_media_entity_v4l2_subdev(link->source->entity)) {
> -		pr_warn_once("%s of link '%s':%u->'%s':%u is not a V4L2 sub-device, driver bug!\n",
> -			     !is_media_entity_v4l2_subdev(link->sink->entity) ?
> -			     "sink" : "source",
> +	/*
> +	 * Links are validated in the context of the sink entity. Usage of this
> +	 * helper on a sink that is not a subdev is a clear driver bug.
> +	 */
> +	if (WARN_ON(!is_media_entity_v4l2_subdev(link->sink->entity)))
> +		return -EINVAL;

WARN*() is nowadays deprecated. Could you continue to use pr_warn_once()
for this (or dev_warn_one())?

> +
> +	if (!is_media_entity_v4l2_subdev(link->source->entity)) {
> +		pr_warn_once("source of link '%s':%u->'%s':%u is not a V4L2 sub-device, driver bug!\n",
>  			     link->source->entity->name, link->source->index,
>  			     link->sink->entity->name, link->sink->index);
>  		return 0;
  
Laurent Pinchart June 25, 2024, 2:02 p.m. UTC | #2
On Sat, Jun 22, 2024 at 04:47:33PM +0000, Sakari Ailus wrote:
> Hi Laurent,
> 
> Thanks for the patch.
> 
> On Wed, Jun 19, 2024 at 04:23:52AM +0300, Laurent Pinchart wrote:
> > The v4l2_subdev_link_validate() function prints a one-time warning if it
> > gets called on a link whose source or sink is not a subdev. As links get
> > validated in the context of their sink, a call to the helper when the
> > link's sink is not a subdev indicates that the driver has set its
> > .link_validate() handler to v4l2_subdev_link_validate() on a non-subdev
> > entity, which is a clear driver bug. On the other hand, the link's
> > source not being a subdev indicates that the helper is used for a subdev
> > connected to a video output device, which is a lesser issue, if only
> > because this is currently common practice.
> > 
> > There are no drivers left in the kernel that use
> > v4l2_subdev_link_validate() in a context where it may get called on a
> > non-subdev sink. Replace the pr_warn_once() with a WARN_ON() in this
> > case to make sure that new offenders won't be introduced.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> >  drivers/media/v4l2-core/v4l2-subdev.c | 14 +++++++++-----
> >  1 file changed, 9 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> > index 4f71199bf592..2d5e39c79620 100644
> > --- a/drivers/media/v4l2-core/v4l2-subdev.c
> > +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> > @@ -1451,11 +1451,15 @@ int v4l2_subdev_link_validate(struct media_link *link)
> >  	bool states_locked;
> >  	int ret;
> >  
> > -	if (!is_media_entity_v4l2_subdev(link->sink->entity) ||
> > -	    !is_media_entity_v4l2_subdev(link->source->entity)) {
> > -		pr_warn_once("%s of link '%s':%u->'%s':%u is not a V4L2 sub-device, driver bug!\n",
> > -			     !is_media_entity_v4l2_subdev(link->sink->entity) ?
> > -			     "sink" : "source",
> > +	/*
> > +	 * Links are validated in the context of the sink entity. Usage of this
> > +	 * helper on a sink that is not a subdev is a clear driver bug.
> > +	 */
> > +	if (WARN_ON(!is_media_entity_v4l2_subdev(link->sink->entity)))
> > +		return -EINVAL;
> 
> WARN*() is nowadays deprecated.

Why so ? I've followed a recent discussion where some people pointed out
they disliked WARN*() due to panic-on-warn, but I didn't see any
conclusion there that deprecated WARN*().

> Could you continue to use pr_warn_once()
> for this (or dev_warn_one())?

I think a WARN_ON() is the right option here. A failure indicates a
clear driver bug, we should be as loud as possible to make sure it gets
noticed during development.

> > +
> > +	if (!is_media_entity_v4l2_subdev(link->source->entity)) {
> > +		pr_warn_once("source of link '%s':%u->'%s':%u is not a V4L2 sub-device, driver bug!\n",
> >  			     link->source->entity->name, link->source->index,
> >  			     link->sink->entity->name, link->sink->index);
> >  		return 0;
  
Sakari Ailus June 25, 2024, 3:46 p.m. UTC | #3
Hi Laurent,

On Tue, Jun 25, 2024 at 05:02:47PM +0300, Laurent Pinchart wrote:
> On Sat, Jun 22, 2024 at 04:47:33PM +0000, Sakari Ailus wrote:
> > Hi Laurent,
> > 
> > Thanks for the patch.
> > 
> > On Wed, Jun 19, 2024 at 04:23:52AM +0300, Laurent Pinchart wrote:
> > > The v4l2_subdev_link_validate() function prints a one-time warning if it
> > > gets called on a link whose source or sink is not a subdev. As links get
> > > validated in the context of their sink, a call to the helper when the
> > > link's sink is not a subdev indicates that the driver has set its
> > > .link_validate() handler to v4l2_subdev_link_validate() on a non-subdev
> > > entity, which is a clear driver bug. On the other hand, the link's
> > > source not being a subdev indicates that the helper is used for a subdev
> > > connected to a video output device, which is a lesser issue, if only
> > > because this is currently common practice.
> > > 
> > > There are no drivers left in the kernel that use
> > > v4l2_subdev_link_validate() in a context where it may get called on a
> > > non-subdev sink. Replace the pr_warn_once() with a WARN_ON() in this
> > > case to make sure that new offenders won't be introduced.
> > > 
> > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > > ---
> > >  drivers/media/v4l2-core/v4l2-subdev.c | 14 +++++++++-----
> > >  1 file changed, 9 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> > > index 4f71199bf592..2d5e39c79620 100644
> > > --- a/drivers/media/v4l2-core/v4l2-subdev.c
> > > +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> > > @@ -1451,11 +1451,15 @@ int v4l2_subdev_link_validate(struct media_link *link)
> > >  	bool states_locked;
> > >  	int ret;
> > >  
> > > -	if (!is_media_entity_v4l2_subdev(link->sink->entity) ||
> > > -	    !is_media_entity_v4l2_subdev(link->source->entity)) {
> > > -		pr_warn_once("%s of link '%s':%u->'%s':%u is not a V4L2 sub-device, driver bug!\n",
> > > -			     !is_media_entity_v4l2_subdev(link->sink->entity) ?
> > > -			     "sink" : "source",
> > > +	/*
> > > +	 * Links are validated in the context of the sink entity. Usage of this
> > > +	 * helper on a sink that is not a subdev is a clear driver bug.
> > > +	 */
> > > +	if (WARN_ON(!is_media_entity_v4l2_subdev(link->sink->entity)))
> > > +		return -EINVAL;
> > 
> > WARN*() is nowadays deprecated.
> 
> Why so ? I've followed a recent discussion where some people pointed out
> they disliked WARN*() due to panic-on-warn, but I didn't see any
> conclusion there that deprecated WARN*().

Fair enough, there seems to have been more discussion.

As this is still user-triggerable, this should be WARN_ON_ONCE() to prevent
the user from filling the logs, intentionally or not.

> 
> > Could you continue to use pr_warn_once()
> > for this (or dev_warn_one())?
> 
> I think a WARN_ON() is the right option here. A failure indicates a
> clear driver bug, we should be as loud as possible to make sure it gets
> noticed during development.
> 
> > > +
> > > +	if (!is_media_entity_v4l2_subdev(link->source->entity)) {
> > > +		pr_warn_once("source of link '%s':%u->'%s':%u is not a V4L2 sub-device, driver bug!\n",
> > >  			     link->source->entity->name, link->source->index,
> > >  			     link->sink->entity->name, link->sink->index);
> > >  		return 0;
>
  
Laurent Pinchart June 25, 2024, 3:54 p.m. UTC | #4
On Tue, Jun 25, 2024 at 03:46:06PM +0000, Sakari Ailus wrote:
> Hi Laurent,
> 
> On Tue, Jun 25, 2024 at 05:02:47PM +0300, Laurent Pinchart wrote:
> > On Sat, Jun 22, 2024 at 04:47:33PM +0000, Sakari Ailus wrote:
> > > Hi Laurent,
> > > 
> > > Thanks for the patch.
> > > 
> > > On Wed, Jun 19, 2024 at 04:23:52AM +0300, Laurent Pinchart wrote:
> > > > The v4l2_subdev_link_validate() function prints a one-time warning if it
> > > > gets called on a link whose source or sink is not a subdev. As links get
> > > > validated in the context of their sink, a call to the helper when the
> > > > link's sink is not a subdev indicates that the driver has set its
> > > > .link_validate() handler to v4l2_subdev_link_validate() on a non-subdev
> > > > entity, which is a clear driver bug. On the other hand, the link's
> > > > source not being a subdev indicates that the helper is used for a subdev
> > > > connected to a video output device, which is a lesser issue, if only
> > > > because this is currently common practice.
> > > > 
> > > > There are no drivers left in the kernel that use
> > > > v4l2_subdev_link_validate() in a context where it may get called on a
> > > > non-subdev sink. Replace the pr_warn_once() with a WARN_ON() in this
> > > > case to make sure that new offenders won't be introduced.
> > > > 
> > > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > > > ---
> > > >  drivers/media/v4l2-core/v4l2-subdev.c | 14 +++++++++-----
> > > >  1 file changed, 9 insertions(+), 5 deletions(-)
> > > > 
> > > > diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> > > > index 4f71199bf592..2d5e39c79620 100644
> > > > --- a/drivers/media/v4l2-core/v4l2-subdev.c
> > > > +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> > > > @@ -1451,11 +1451,15 @@ int v4l2_subdev_link_validate(struct media_link *link)
> > > >  	bool states_locked;
> > > >  	int ret;
> > > >  
> > > > -	if (!is_media_entity_v4l2_subdev(link->sink->entity) ||
> > > > -	    !is_media_entity_v4l2_subdev(link->source->entity)) {
> > > > -		pr_warn_once("%s of link '%s':%u->'%s':%u is not a V4L2 sub-device, driver bug!\n",
> > > > -			     !is_media_entity_v4l2_subdev(link->sink->entity) ?
> > > > -			     "sink" : "source",
> > > > +	/*
> > > > +	 * Links are validated in the context of the sink entity. Usage of this
> > > > +	 * helper on a sink that is not a subdev is a clear driver bug.
> > > > +	 */
> > > > +	if (WARN_ON(!is_media_entity_v4l2_subdev(link->sink->entity)))
> > > > +		return -EINVAL;
> > > 
> > > WARN*() is nowadays deprecated.
> > 
> > Why so ? I've followed a recent discussion where some people pointed out
> > they disliked WARN*() due to panic-on-warn, but I didn't see any
> > conclusion there that deprecated WARN*().
> 
> Fair enough, there seems to have been more discussion.
> 
> As this is still user-triggerable, this should be WARN_ON_ONCE() to prevent
> the user from filling the logs, intentionally or not.

It's user-triggerable, but only when the driver is clearly buggy :-)
WARN_ON_ONCE() is OK with me though, I don't think warning every time
would provide much added value.

> > > Could you continue to use pr_warn_once()
> > > for this (or dev_warn_one())?
> > 
> > I think a WARN_ON() is the right option here. A failure indicates a
> > clear driver bug, we should be as loud as possible to make sure it gets
> > noticed during development.
> > 
> > > > +
> > > > +	if (!is_media_entity_v4l2_subdev(link->source->entity)) {
> > > > +		pr_warn_once("source of link '%s':%u->'%s':%u is not a V4L2 sub-device, driver bug!\n",
> > > >  			     link->source->entity->name, link->source->index,
> > > >  			     link->sink->entity->name, link->sink->index);
> > > >  		return 0;
  

Patch

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 4f71199bf592..2d5e39c79620 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -1451,11 +1451,15 @@  int v4l2_subdev_link_validate(struct media_link *link)
 	bool states_locked;
 	int ret;
 
-	if (!is_media_entity_v4l2_subdev(link->sink->entity) ||
-	    !is_media_entity_v4l2_subdev(link->source->entity)) {
-		pr_warn_once("%s of link '%s':%u->'%s':%u is not a V4L2 sub-device, driver bug!\n",
-			     !is_media_entity_v4l2_subdev(link->sink->entity) ?
-			     "sink" : "source",
+	/*
+	 * Links are validated in the context of the sink entity. Usage of this
+	 * helper on a sink that is not a subdev is a clear driver bug.
+	 */
+	if (WARN_ON(!is_media_entity_v4l2_subdev(link->sink->entity)))
+		return -EINVAL;
+
+	if (!is_media_entity_v4l2_subdev(link->source->entity)) {
+		pr_warn_once("source of link '%s':%u->'%s':%u is not a V4L2 sub-device, driver bug!\n",
 			     link->source->entity->name, link->source->index,
 			     link->sink->entity->name, link->sink->index);
 		return 0;