From: Russell King - ARM Linux <linux@armlinux.org.uk>
To: Nicolae Rosia <nicolae.rosia.oss@gmail.com>
Cc: Tony Lindgren <tony@atomide.com>,
Nicolae Rosia <Nicolae_Rosia@mentor.com>,
linux-omap@vger.kernel.org, Lee Jones <lee.jones@linaro.org>,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH] mfd: twl-core: export twl_get_regmap
Date: Mon, 21 Nov 2016 13:37:55 +0000 [thread overview]
Message-ID: <20161121133755.GF23750@n2100.armlinux.org.uk> (raw)
In-Reply-To: <CAKP5S=28xVyNE=Q7hd2UbtOmT=12ayrcWM5m1OTvk5kGN5pZrw@mail.gmail.com>
On Mon, Nov 21, 2016 at 12:03:03PM +0200, Nicolae Rosia wrote:
> On Mon, Nov 21, 2016 at 11:31 AM, Russell King - ARM Linux
> <linux@armlinux.org.uk> wrote:
> > Passing data between drivers using *_set_drvdata() is a layering
> > violation:
> >
> > 1. Driver data is supposed to be driver private data associated with
> > the currently bound driver.
> > 2. The driver data pointer is NULL'd when the driver unbinds from the
> > device. See __device_release_driver() and the
> > dev_set_drvdata(dev, NULL).
> > 3. It will break with CONFIG_DEBUG_TEST_DRIVER_REMOVE enabled for a
> > similar reason to (2).
> >
> > So, do not pass data between drivers using *_set_drvdata() - any
> > examples in the kernel already are founded on bad practice, are
> > fragile, and are already broken for some kernel configurations.
>
> After inspecting mfd_add_device, it seems that it creates a
> platform_device which has the parent set to the driver calling the
> function.
> Isn't module unloading forbidden if there is a parent->child
> relationship in place and you're removing the parent?
Forget this idea that there's any connection between modules and
the struct device relationships - there isn't anything of the kind!
Each struct device is refcounted, and child devices will hold a
reference to their parent device, so the parent device doesn't get
freed before its children are all gone.
That's a completely separate issue to when a struct device is bound
to a struct device_driver - it's entirely possible for parent drivers
to be unbound at any time, even when there are child drivers in place.
There are cases where we want that to happen - think of any driver
which is a bus driver in itself - eg, PCMCIA, MMC, USB, etc. These
drivers enumerate their children, and destroy their children when
the driver is unbound - but the driver has to be in the process of
being unbound for that to happen. That process may very well start
with the child devices being bound to their drivers.
What makes the child drivers unbind is when the bus driver deletes
the child struct devices.
> What should be the best practice to share data between drivers?
> Reference counted data?
I guess so, but you will still have a race if you do something like:
struct parent_private_data *parent_priv = dev_get_drvdata(dev->parent);
Yes, that'll get the parent's driver private data, but what you don't
know is whether the pointer remains valid, and even if you do as the
very next step:
kref_get(&parent_priv->kref);
you don't know whether parent_priv was kfree()d between these two
statements.
However, if the parent driver creates the struct device that you're
using and deletes the struct device before it frees its private data,
then you can be sure that parent_priv will be valid, because the child
drivers will be unbound during the parent driver's ->remove function,
_before_ the private data is freed.
> In the case of TWL, the twl-core is just a simple container for
> regmaps - all other "sub devices" are using those regmaps to access
> the I2C device's registers, it makes no sense to remove the parent
> driver since it does *nothing*.
I can't comment on what twl-core is doing, I haven't looked at it in
ages, but most MFD drivers have the parent device creating and destroying
their children, so it should be fine.
My original comment was more along the lines of a parent device poking
driver-private data into the child devices it was creating for the
child drivers to pick up. However, it's worth discussing the validity
cases of the parent's driver data too, as per the above.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
next prev parent reply other threads:[~2016-11-21 13:37 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-12 11:38 [PATCH] mfd: twl-core: export twl_get_regmap Nicolae Rosia
2016-11-18 18:55 ` Lee Jones
2016-11-20 12:54 ` Nicolae Rosia
2016-11-21 9:23 ` Lee Jones
2016-11-21 9:31 ` Russell King - ARM Linux
2016-11-21 10:03 ` Nicolae Rosia
2016-11-21 13:37 ` Russell King - ARM Linux [this message]
2016-11-23 11:12 ` Russell King - ARM Linux
2016-11-23 11:22 ` Rosia, Nicolae
2016-11-26 18:23 ` Nicolae Rosia
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=20161121133755.GF23750@n2100.armlinux.org.uk \
--to=linux@armlinux.org.uk \
--cc=Nicolae_Rosia@mentor.com \
--cc=lee.jones@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-omap@vger.kernel.org \
--cc=nicolae.rosia.oss@gmail.com \
--cc=tony@atomide.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;
as well as URLs for NNTP newsgroup(s).