From: jacopo mondi <jacopo@jmondi.org>
To: Sakari Ailus <sakari.ailus@linux.intel.com>
Cc: Jacopo Mondi <jacopo+renesas@jmondi.org>,
niklas.soderlund@ragnatech.se, kieran.bingham@ideasonboard.com,
laurent.pinchart@ideasonboard.com, linux-media@vger.kernel.org,
linux-renesas-soc@vger.kernel.org
Subject: Re: [PATCH 4/5] v4l2: async: Postpone subdev_notifier registration
Date: Sun, 17 Dec 2017 17:13:52 +0100 [thread overview]
Message-ID: <20171217161352.GE20926@w540> (raw)
In-Reply-To: <20171215152040.nex4jjk7awk4ckg3@paasikivi.fi.intel.com>
Hi Sakari,
On Fri, Dec 15, 2017 at 05:20:40PM +0200, Sakari Ailus wrote:
> Hi Jacopo,
>
> On Wed, Dec 13, 2017 at 07:26:19PM +0100, Jacopo Mondi wrote:
> > Currently, subdevice notifiers are tested against all available
> > subdevices as soon as they get registered. It often happens anyway
> > that the subdevice they are connected to is not yet initialized, as
> > it usually gets registered later in drivers' code. This makes debug
> > of v4l2_async particularly painful, as identifying a notifier with
> > an unitialized subdevice is tricky as they don't have a valid
> > 'struct device *' or 'struct fwnode_handle *' to be identified with.
> >
> > In order to make sure that the notifier's subdevices is initialized
> > when the notifier is tesed against available subdevices post-pone the
> > actual notifier registration at subdevice registration time.
> >
> > It is worth noting that post-poning registration of a subdevice notifier
> > does not impact on the completion of the notifiers chain, as even if a
> > subdev notifier completes as soon as it gets registered, the complete()
> > call chain cannot be upscaled as long as the subdevice the notifiers
> > belongs to is not registered.
>
> Let me rephrase to make sure I understand the problem correctly ---
>
> A sub-device notifier is registered but the notifier's sub-device is not
> registered yet, and finding a match for this notifier leads, to, well
> problems. Is that the reason for this patch?
Almost :)
I never encountered problems registering the sub-notifier, but instead
identifying it when trying to debug what's happening in v4l2-async.
I had a lot of "(null)" notifiers, and that makes debug particularly
painful, as in example I had unexpected matches between a subdev and a
"(null)" notifier and it's pretty hard find out what's going wrong.
So I post-poned registratration (and consequentially matching with the
available subdevices) to a time where I know it can be identified.
>
> I think there could be simpler solutions to address this.
>
> I wonder if we could simply check for sub-device notifier's v4l2_dev field,
> and fail in matching if it's not set. v4l2_device_register_subdev() would
> still need to proceed with calling v4l2_async_notifier_try_all_subdevs()
> and v4l2_async_notifier_try_complete() if that was the case.
>
> What do you think?
v4l2_dev is only set in root notifiers, we maybe can check for a valid
"struct device *" and refuse notifiers without an initialized one in
"__v4l2_async_notifier_register()".
And you're actually right here, when later the subdevice owning the just
refused sub-notifier gets registered (and eventually matched) its
sub-notifier will be processed anyhow, and this makes hunk "@@ -548,6
+551,20 @@" of my patch unnecessary.
I will test and simplify it. Thanks
>
> >
> > Also, it is now safe to access a notifier 'struct device *' as we're now
> > sure it is properly initialized when the notifier is actually
> > registered.
> >
> > Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > ---
> > drivers/media/v4l2-core/v4l2-async.c | 65 +++++++++++++++++++++++-------------
> > include/media/v4l2-async.h | 2 ++
> > 2 files changed, 43 insertions(+), 24 deletions(-)
> >
> > diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
> > index 0a1bf1d..c13a781 100644
> > --- a/drivers/media/v4l2-core/v4l2-async.c
> > +++ b/drivers/media/v4l2-core/v4l2-async.c
> > @@ -25,6 +25,13 @@
> > #include <media/v4l2-fwnode.h>
> > #include <media/v4l2-subdev.h>
> >
> > +static struct device *v4l2_async_notifier_dev(
> > + struct v4l2_async_notifier *notifier)
> > +{
> > + return notifier->v4l2_dev ? notifier->v4l2_dev->dev :
> > + notifier->sd->dev;
> > +}
> > +
> > static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n,
> > struct v4l2_subdev *subdev,
> > struct v4l2_async_subdev *asd)
> > @@ -124,19 +131,6 @@ static struct v4l2_async_subdev *v4l2_async_find_match(
> > return NULL;
> > }
> >
> > -/* Find the sub-device notifier registered by a sub-device driver. */
> > -static struct v4l2_async_notifier *v4l2_async_find_subdev_notifier(
> > - struct v4l2_subdev *sd)
> > -{
> > - struct v4l2_async_notifier *n;
> > -
> > - list_for_each_entry(n, ¬ifier_list, list)
> > - if (n->sd == sd)
> > - return n;
> > -
> > - return NULL;
> > -}
> > -
> > /* Get v4l2_device related to the notifier if one can be found. */
> > static struct v4l2_device *v4l2_async_notifier_find_v4l2_dev(
> > struct v4l2_async_notifier *notifier)
> > @@ -160,7 +154,7 @@ static bool v4l2_async_notifier_can_complete(
> >
> > list_for_each_entry(sd, ¬ifier->done, async_list) {
> > struct v4l2_async_notifier *subdev_notifier =
> > - v4l2_async_find_subdev_notifier(sd);
> > + sd->subdev_notifier;
> >
> > if (subdev_notifier &&
> > !v4l2_async_notifier_can_complete(subdev_notifier))
> > @@ -228,7 +222,7 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
> > /*
> > * See if the sub-device has a notifier. If not, return here.
> > */
> > - subdev_notifier = v4l2_async_find_subdev_notifier(sd);
> > + subdev_notifier = sd->subdev_notifier;
> > if (!subdev_notifier || subdev_notifier->parent)
> > return 0;
> >
> > @@ -294,7 +288,7 @@ static void v4l2_async_notifier_unbind_all_subdevs(
> >
> > list_for_each_entry_safe(sd, tmp, ¬ifier->done, async_list) {
> > struct v4l2_async_notifier *subdev_notifier =
> > - v4l2_async_find_subdev_notifier(sd);
> > + sd->subdev_notifier;
> >
> > if (subdev_notifier)
> > v4l2_async_notifier_unbind_all_subdevs(subdev_notifier);
> > @@ -371,8 +365,7 @@ static bool v4l2_async_notifier_fwnode_has_async_subdev(
> >
> > static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
> > {
> > - struct device *dev =
> > - notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL;
> > + struct device *dev = v4l2_async_notifier_dev(notifier);
> > struct v4l2_async_subdev *asd;
> > int ret;
> > int i;
> > @@ -383,6 +376,8 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
> > INIT_LIST_HEAD(¬ifier->waiting);
> > INIT_LIST_HEAD(¬ifier->done);
> >
> > + notifier->owner = dev_fwnode(dev);
> > +
> > mutex_lock(&list_lock);
> >
> > for (i = 0; i < notifier->num_subdevs; i++) {
> > @@ -421,6 +416,7 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
> >
> > /* Keep also completed notifiers on the list */
> > list_add(¬ifier->list, ¬ifier_list);
> > + notifier->registered = true;
> >
> > mutex_unlock(&list_lock);
> >
> > @@ -447,7 +443,7 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
> > return -EINVAL;
> >
> > notifier->v4l2_dev = v4l2_dev;
> > - notifier->owner = dev_fwnode(v4l2_dev->dev);
> > + notifier->registered = false;
> >
> > ret = __v4l2_async_notifier_register(notifier);
> > if (ret)
> > @@ -466,7 +462,11 @@ int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
> > return -EINVAL;
> >
> > notifier->sd = sd;
> > - notifier->owner = dev_fwnode(sd->dev);
> > + sd->subdev_notifier = notifier;
> > + notifier->registered = false;
> > +
> > + if (!sd->dev || !sd->fwnode)
> > + return 0;
> >
> > ret = __v4l2_async_notifier_register(notifier);
> > if (ret)
> > @@ -482,12 +482,15 @@ static void __v4l2_async_notifier_unregister(
> > if (!notifier || (!notifier->v4l2_dev && !notifier->sd))
> > return;
> >
> > - v4l2_async_notifier_unbind_all_subdevs(notifier);
> > + if (notifier->registered) {
> > + v4l2_async_notifier_unbind_all_subdevs(notifier);
> > + list_del(¬ifier->list);
> > + }
> >
> > notifier->sd = NULL;
> > notifier->v4l2_dev = NULL;
> > -
> > - list_del(¬ifier->list);
> > + notifier->owner = NULL;
> > + notifier->registered = false;
> > }
> >
> > void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
> > @@ -548,6 +551,20 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
> > sd->fwnode = dev_fwnode(sd->dev);
> > }
> >
> > + /*
> > + * If the subdevice has an unregisterd notifier, it's now time
> > + * to register it.
> > + */
> > + subdev_notifier = sd->subdev_notifier;
> > + if (subdev_notifier && !subdev_notifier->registered) {
> > + ret = __v4l2_async_notifier_register(subdev_notifier);
> > + if (ret) {
> > + sd->fwnode = NULL;
> > + subdev_notifier->owner = NULL;
> > + return ret;
> > + }
> > + }
> > +
> > mutex_lock(&list_lock);
> >
> > INIT_LIST_HEAD(&sd->async_list);
> > @@ -589,7 +606,7 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
> > * Complete failed. Unbind the sub-devices bound through registering
> > * this async sub-device.
> > */
> > - subdev_notifier = v4l2_async_find_subdev_notifier(sd);
> > + subdev_notifier = sd->subdev_notifier;
> > if (subdev_notifier)
> > v4l2_async_notifier_unbind_all_subdevs(subdev_notifier);
> >
> > diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
> > index a15c01d..6ab04ad 100644
> > --- a/include/media/v4l2-async.h
> > +++ b/include/media/v4l2-async.h
> > @@ -110,6 +110,7 @@ struct v4l2_async_notifier_operations {
> > * @waiting: list of struct v4l2_async_subdev, waiting for their drivers
> > * @done: list of struct v4l2_subdev, already probed
> > * @list: member in a global list of notifiers
> > + * @registered: notifier registered complete flag
> > */
> > struct v4l2_async_notifier {
> > const struct v4l2_async_notifier_operations *ops;
> > @@ -123,6 +124,7 @@ struct v4l2_async_notifier {
> > struct list_head waiting;
> > struct list_head done;
> > struct list_head list;
> > + bool registered;
> > };
> >
> > /**
> > --
> > 2.7.4
> >
>
> --
> Sakari Ailus
> sakari.ailus@linux.intel.com
next prev parent reply other threads:[~2017-12-17 16:13 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-13 18:26 [PATCH 0/5] Add debug output to v4l2-async Jacopo Mondi
2017-12-13 18:26 ` [PATCH 1/5] v4l: async: Use endpoint node, not device node, for fwnode match Jacopo Mondi
2017-12-17 16:45 ` Laurent Pinchart
2017-12-13 18:26 ` [PATCH 2/5] device property: Add fwnode_get_name() operation Jacopo Mondi
2017-12-15 14:35 ` Sakari Ailus
2017-12-17 16:49 ` Laurent Pinchart
2017-12-13 18:26 ` [PATCH 3/5] include: v4l2_async: Add 'owner' field to notifier Jacopo Mondi
2017-12-15 14:38 ` Sakari Ailus
2017-12-17 16:53 ` Laurent Pinchart
2017-12-13 18:26 ` [PATCH 4/5] v4l2: async: Postpone subdev_notifier registration Jacopo Mondi
2017-12-15 15:20 ` Sakari Ailus
2017-12-17 16:13 ` jacopo mondi [this message]
2017-12-17 13:10 ` Kieran Bingham
2017-12-17 13:13 ` Kieran Bingham
2017-12-17 17:03 ` Laurent Pinchart
2017-12-17 23:33 ` Sakari Ailus
2017-12-18 8:38 ` Laurent Pinchart
2017-12-13 18:26 ` [PATCH 5/5] v4l2: async: Add debug output to v4l2-async module Jacopo Mondi
2017-12-15 16:17 ` Sakari Ailus
2017-12-17 16:42 ` jacopo mondi
2017-12-17 23:38 ` Sakari Ailus
2017-12-17 17:06 ` 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=20171217161352.GE20926@w540 \
--to=jacopo@jmondi.org \
--cc=jacopo+renesas@jmondi.org \
--cc=kieran.bingham@ideasonboard.com \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=niklas.soderlund@ragnatech.se \
--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