public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Hans Verkuil <hverkuil@xs4all.nl>,
	Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>,
	<linux-media@vger.kernel.org>,
	Sakari Ailus <sakari.ailus@linux.intel.com>
Subject: Re: [PATCH v5 1/2] media: Add obj_type field to struct media_entity
Date: Wed, 23 Mar 2016 14:29:35 -0300	[thread overview]
Message-ID: <20160323142935.68d417be@recife.lan> (raw)
In-Reply-To: <4580235.WOIJ26Ec16@avalon>

Em Wed, 23 Mar 2016 17:41:44 +0200
Laurent Pinchart <laurent.pinchart@ideasonboard.com> escreveu:

> On Wednesday 23 Mar 2016 12:17:30 Mauro Carvalho Chehab wrote:
> > Em Wed, 23 Mar 2016 15:57:10 +0100 Hans Verkuil escreveu:  
> > > On 03/23/2016 03:45 PM, Laurent Pinchart wrote:  
> > >> On Wednesday 23 Mar 2016 15:05:41 Hans Verkuil wrote:  
> > >>> On 03/23/2016 11:35 AM, Mauro Carvalho Chehab wrote:  
> > >>>> Em Wed, 23 Mar 2016 10:45:55 +0200 Laurent Pinchart escreveu:  
> > >>>>> Code that processes media entities can require knowledge of the
> > >>>>> structure type that embeds a particular media entity instance in
> > >>>>> order
> > >>>>> to cast the entity to the proper object type. This needs is shown by
> > >>>>> the
> > >>>>> presence of the is_media_entity_v4l2_io and
> > >>>>> is_media_entity_v4l2_subdev
> > >>>>> functions.
> > >>>>> 
> > >>>>> The implementation of those two functions relies on the entity
> > >>>>> function
> > >>>>> field, which is both a wrong and an inefficient design, without even
> > >>>>> mentioning the maintenance issue involved in updating the functions
> > >>>>> every time a new entity function is added. Fix this by adding add an
> > >>>>> obj_type field to the media entity structure to carry the
> > >>>>> information.
> > >>>>> 
> > >>>>> Signed-off-by: Laurent Pinchart
> > >>>>> <laurent.pinchart+renesas@ideasonboard.com>
> > >>>>> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
> > >>>>> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > >>>>> ---
> > >>>>> 
> > >>>>>  drivers/media/media-device.c          |  2 +
> > >>>>>  drivers/media/v4l2-core/v4l2-dev.c    |  1 +
> > >>>>>  drivers/media/v4l2-core/v4l2-subdev.c |  1 +
> > >>>>>  include/media/media-entity.h          | 79 ++++++++++++-------------
> > >>>>>  4 files changed, 46 insertions(+), 37 deletions(-)
> > >>>>> 
> > >>>>> diff --git a/drivers/media/media-device.c
> > >>>>> b/drivers/media/media-device.c
> > >>>>> index 4a97d92a7e7d..88d8de3b7a4f 100644
> > >>>>> --- a/drivers/media/media-device.c
> > >>>>> +++ b/drivers/media/media-device.c
> > >>>>> @@ -580,6 +580,8 @@ int __must_check
> > >>>>> media_device_register_entity(struct
> > >>>>> media_device *mdev,
> > >>>>> 
> > >>>>>  			 "Entity type for entity %s was not initialized!\n",
> > >>>>>  			 entity->name);
> > >>>>> 
> > >>>>> +	WARN_ON(entity->obj_type == MEDIA_ENTITY_TYPE_INVALID);
> > >>>>> +  
> > >>>> 
> > >>>> This is not ok. There are valid cases where the entity is not embedded
> > >>>> on some other struct. That's the case of connectors/connections, for
> > >>>> example: a connector/connection entity doesn't need anything else but
> > >>>> struct media device.  
> > >>> 
> > >>> Once connectors are enabled, then we do need a
> > >>> MEDIA_ENTITY_TYPE_CONNECTOR
> > >>> or MEDIA_ENTITY_TYPE_STANDALONE or something along those lines.  
> > >> 
> > >> MEDIA_ENTITY_TYPE_CONNECTOR would make sense, but only if we add a
> > >> struct media_connector. I believe that can be a good idea, at least to
> > >> simplify management of the entity and the connector pad(s).
> > >>   
> > >>>> Also, this is V4L2 specific. Neither ALSA nor DVB need to use
> > >>>> container_of(). Actually, this won't even work there, as the entity is
> > >>>> stored as a pointer, and not as an embedded data.  
> > >> 
> > >> That's sounds like a strange design decision at the very least. There
> > >> can be valid cases that require creation of bare entities, but I don't
> > >> think they should be that common.  
> > 
> > This is where we disagree.
> > 
> > Basically the problem we have is that we have something like:
> > 
> > struct container {
> > 	struct object obj;
> > };
> > 
> > or
> > 
> > struct container {
> > 	struct object *obj;
> > };
> > 
> > 
> > The normal usage is the way both DVB and ALSA currently does: they
> > always go from the container to the obj:
> > 
> > 	obj = container.obj;
> > or
> > 	obj = container->obj;
> > 
> > Anyway, either embeeding or usin a pointer, for such usage, there's no
> > need for an "obj_type".
> > 
> > At some V4L2 drivers, however, it is needed to do something like:
> > 
> > if (obj_type == MEDIA_TYPE_FOO)
> > 	container_foo = container_of(obj, struct container_foo, obj);
> > 
> > if (obj_type == MEDIA_TYPE_BAR)
> > 	container_bar = container_of(obj, struct container_bar, obj);
> > 
> > Ok, certainly there are cases where this could be unavoidable, but it is
> > *ugly*.
> > 
> > The way DVB uses it is a way cleaner, as never needs to use
> > container_of(), as the container struct is always known. Also, there's
> > no need to embed the struct.  
> 
> No, no, no and no. Looks like it's time for a bit of Object Oriented 
> Programming 101.

I know what you're doing. I had my usual workload of programs 
in c++ programming.

> Casting from a superclass (a.k.a. base class) type to a subclass type is a 
> basic programming concept found in most languages that deal with objects. It 
> allows creating collections of objects of different subclasses than all 
> inherit from the same base class, handle them with generic code and still 
> offer the ability for custom processing when needed.
> 
> C++ implements this concept with the dynamic_cast<> operator. As the kernel is 
> written in plain C we use container_of() instead for the same purpose, and 
> need explicit object types to perform RTTI.

I'm not arguing against the c++ theory, but, instead, about its
implementation.

On (almost?) all cases where we use container_of() in the Kernel, the
container type is already known. So, drivers just use container_of()
without any if/switch().

That's OK.

What's different in this usecase is that the driver that needs to
use container_of() doesn't know the type of the object that it
is needing to reference. So, it has things like[1]:

        while (pad) {
                if (!is_media_entity_v4l2_subdev(pad->entity))
                       	break;

		subdev = container_of(pad->entity, struct v4l2_subdev, entity)
                entity = container_of(subdev, struct vsp1_entity, subdev);
...
	}

[1] I changed the code snippet a little bit to show the container_of()
that would be otherwise hidden by a function call.

This is needed only because the loop doesn't know if the pad->entity
may not be contained inside struct v4l2_subdev.

While the above *works*, it is, IMHO, ugly, as, if the type is not
properly set, it will cause an horrible crash.

I bet you won't find too many places with similar tests at the Kernel.

On most places, what you'll find is just:

	function xxx(struct foo)
	{
		struct bar = container_of(obj, foo, obj);

without any ifs.

Yet, while I don't like the if's before container_of() and I would
avoid doing that on my own code, I see why you need it, and I'm ok
with that.

Thanks,
Mauro

  reply	other threads:[~2016-03-23 17:29 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-23  8:45 [PATCH v5 0/2] media: Add entity types Laurent Pinchart
2016-03-23  8:45 ` [PATCH v5 1/2] media: Add obj_type field to struct media_entity Laurent Pinchart
2016-03-23 10:35   ` Mauro Carvalho Chehab
2016-03-23 14:05     ` Hans Verkuil
2016-03-23 14:45       ` Laurent Pinchart
2016-03-23 14:57         ` Hans Verkuil
2016-03-23 15:04           ` Laurent Pinchart
2016-03-23 15:17           ` Mauro Carvalho Chehab
2016-03-23 15:41             ` Laurent Pinchart
2016-03-23 17:29               ` Mauro Carvalho Chehab [this message]
2016-03-24  8:15                 ` Laurent Pinchart
2016-03-23 15:00       ` Mauro Carvalho Chehab
2016-03-23 15:11         ` Laurent Pinchart
2016-03-23 15:20           ` Hans Verkuil
2016-03-23 15:24           ` Mauro Carvalho Chehab
2016-03-23 16:30             ` Laurent Pinchart
2016-03-23 17:06               ` Mauro Carvalho Chehab
2016-03-23 16:17         ` Sakari Ailus
2016-03-23 16:47           ` Mauro Carvalho Chehab
2016-03-23 23:42             ` Sakari Ailus
2016-03-24  7:51             ` Laurent Pinchart
2016-03-23  8:45 ` [PATCH v5 2/2] media: Rename is_media_entity_v4l2_io to is_media_entity_v4l2_video_device Laurent Pinchart

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160323142935.68d417be@recife.lan \
    --to=mchehab@osg.samsung.com \
    --cc=hverkuil@xs4all.nl \
    --cc=laurent.pinchart+renesas@ideasonboard.com \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-media@vger.kernel.org \
    --cc=sakari.ailus@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox