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
next prev parent 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