From: Lukas Wunner <lukas@wunner.de>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: Steve Glendinning <steve.glendinning@shawell.net>,
UNGLinuxDriver@microchip.com, Oliver Neukum <oneukum@suse.com>,
"David S. Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
netdev@vger.kernel.org, linux-usb@vger.kernel.org,
Andre Edich <andre.edich@microchip.com>,
Oleksij Rempel <o.rempel@pengutronix.de>,
Martyn Welch <martyn.welch@collabora.com>,
Gabriel Hojda <ghojda@yo2urs.ro>,
Christoph Fritz <chf.fritz@googlemail.com>,
Lino Sanfilippo <LinoSanfilippo@gmx.de>,
Philipp Rosenberger <p.rosenberger@kunbus.com>,
Heiner Kallweit <hkallweit1@gmail.com>,
Andrew Lunn <andrew@lunn.ch>,
Russell King <linux@armlinux.org.uk>
Subject: Re: [PATCH net] usbnet: smsc95xx: Fix deadlock on runtime resume
Date: Wed, 27 Apr 2022 17:10:53 +0200 [thread overview]
Message-ID: <20220427151053.GA10204@wunner.de> (raw)
In-Reply-To: <YmlMaE53+EhRz5it@rowland.harvard.edu>
On Wed, Apr 27, 2022 at 10:00:08AM -0400, Alan Stern wrote:
> On Wed, Apr 27, 2022 at 08:41:49AM +0200, Lukas Wunner wrote:
> > Commit 05b35e7eb9a1 ("smsc95xx: add phylib support") amended
> > smsc95xx_resume() to call phy_init_hw(). That function waits for the
> > device to runtime resume even though it is placed in the runtime resume
> > path, causing a deadlock.
> >
> > The problem is that phy_init_hw() calls down to smsc95xx_mdiobus_read(),
> > which never uses the _nopm variant of usbnet_read_cmd(). Amend it to
> > autosense that it's called from the runtime resume/suspend path and use
> > the _nopm variant if so.
[...]
> > --- a/drivers/net/usb/smsc95xx.c
> > +++ b/drivers/net/usb/smsc95xx.c
> > @@ -285,11 +285,21 @@ static void smsc95xx_mdio_write_nopm(struct usbnet *dev, int idx, int regval)
> > __smsc95xx_mdio_write(dev, pdata->phydev->mdio.addr, idx, regval, 1);
> > }
> >
> > +static bool smsc95xx_in_pm(struct usbnet *dev)
> > +{
> > +#ifdef CONFIG_PM
> > + return dev->udev->dev.power.runtime_status == RPM_RESUMING ||
> > + dev->udev->dev.power.runtime_status == RPM_SUSPENDING;
> > +#else
> > + return false;
> > +#endif
> > +}
>
> This does not do what you want. You want to know if this function is
> being called in the resume pathway, but all it really tells you is
> whether the function is being called while a resume is in progress (and
> it doesn't even do that very precisely because the code does not use the
> runtime-pm spinlock). The resume could be running in a different
> thread, in which case you most definitely _would_ want to want for it to
> complete.
I'm aware of that. I've explored various approaches and none solved
the problem perfectly. This one seems good enough for all practical
purposes.
One approach I've considered is to use current_work() to determine if
we're called from dev->power.work. But that only works if the runtime
resume/suspend is asynchronous (RPM_ASYNC is set). In this case, the
runtime resume is synchronous and called from a different work item
(hub_event). So the approach is not feasible.
Another approach is to assign a dev_pm_domain to the usb_device, whose
->runtime_resume hook first calls usb_runtime_resume() (so that the
usb_device and usb_interface has status RPM_ACTIVE), *then* calls
phy_init_hw(). Problem is, this only works for runtime resume
and we need a solution for runtime suspend as well. (The device already
has status RPM_SUSPENDING when the dev_pm_domain's ->runtime_suspend hook
is invoked.) So not a feasible approach either.
Fudging the runtime_status in the ->runtime_suspend and ->runtime_resume
hooks via pm_runtime_set_active() / _set_suspended() is rejected by the
runtime PM core.
I've even considered walking up the callstack via _RET_IP_ to determine
if one of the callers is smsc95xx_resume() / _suspend(). But I'm not
sure that's reliable and portable across all arches.
And I don't want to clutter phylib with _nopm variants either.
So the approach I've chosen here, while not perfect, does its job,
is simple and uses very little code. If you've got a better idea,
please let me know.
Thanks,
Lukas
next prev parent reply other threads:[~2022-04-27 15:11 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-27 6:41 [PATCH net] usbnet: smsc95xx: Fix deadlock on runtime resume Lukas Wunner
2022-04-27 14:00 ` Alan Stern
2022-04-27 15:10 ` Lukas Wunner [this message]
2022-04-27 15:24 ` Andrew Lunn
2022-04-27 15:38 ` Lukas Wunner
2022-04-27 18:19 ` Alan Stern
2022-04-27 15:45 ` Lukas Wunner
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=20220427151053.GA10204@wunner.de \
--to=lukas@wunner.de \
--cc=LinoSanfilippo@gmx.de \
--cc=UNGLinuxDriver@microchip.com \
--cc=andre.edich@microchip.com \
--cc=andrew@lunn.ch \
--cc=chf.fritz@googlemail.com \
--cc=davem@davemloft.net \
--cc=ghojda@yo2urs.ro \
--cc=hkallweit1@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=martyn.welch@collabora.com \
--cc=netdev@vger.kernel.org \
--cc=o.rempel@pengutronix.de \
--cc=oneukum@suse.com \
--cc=p.rosenberger@kunbus.com \
--cc=pabeni@redhat.com \
--cc=stern@rowland.harvard.edu \
--cc=steve.glendinning@shawell.net \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.