FAILED: patch "[PATCH] net: usb: asix: hold PM usage ref to avoid PM/MDIO + RTNL" failed to apply to 5.15-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 3d3c4cd5c62f24bb3cb4511b7a95df707635e00a
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025101349-reptile-seldom-427d@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 3d3c4cd5c62f24bb3cb4511b7a95df707635e00a Mon Sep 17 00:00:00 2001
From: Oleksij Rempel <[email protected]>
Date: Sun, 5 Oct 2025 10:12:03 +0200
Subject: [PATCH] net: usb: asix: hold PM usage ref to avoid PM/MDIO + RTNL
deadlock
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Prevent USB runtime PM (autosuspend) for AX88772* in bind.
usbnet enables runtime PM (autosuspend) by default, so disabling it via the usb_driver flag is ineffective. On AX88772B, autosuspend shows no measurable power saving with current driver (no link partner, admin up/down). The ~0.453 W -> ~0.248 W drop on v6.1 comes from phylib powering the PHY off on admin-down, not from USB autosuspend.
The real hazard is that with runtime PM enabled, ndo_open() (under RTNL) may synchronously trigger autoresume (usb_autopm_get_interface()) into asix_resume() while the USB PM lock is held. Resume paths then invoke phylink/phylib and MDIO, which also expect RTNL, leading to possible deadlocks or PM lock vs MDIO wake issues.
To avoid this, keep the device runtime-PM active by taking a usage reference in ax88772_bind() and dropping it in unbind(). A non-zero PM usage count blocks runtime suspend regardless of userspace policy (.../power/control - pm_runtime_allow/forbid), making this approach robust against sysfs overrides.
Holding a runtime-PM usage ref does not affect system-wide suspend; system sleep/resume callbacks continue to run as before.
drivers/net/usb/asix_devices.c +29 -0
@@ -625,6 +625,21 @@ static void ax88772_suspend(struct usbnet *dev) asix_read_medium_status(dev, 1)); } +/* Notes on PM callbacks and locking context: +* +* - asix_suspend()/asix_resume() are invoked for both runtime PM and +* system-wide suspend/resume. For struct usb_driver the ->resume() +* callback does not receive pm_message_t, so the resume type cannot +* be distinguished here. +* +* - The MAC driver must hold RTNL when calling phylink interfaces such as +* phylink_suspend()/resume(). Those calls will also perform MDIO I/O. +* +* - Taking RTNL and doing MDIO from a runtime-PM resume callback (while +* the USB PM lock is held) is fragile. Since autosuspend brings no +* measurable power saving here, we block it by holding a PM usage +* reference in ax88772_bind(). +*/ static int asix_suspend (struct usb_interface *intf,pm_message_t message) {struct usbnet *dev =usb_get_intfdata (intf);
@@ -919,6 +934,13 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)if (ret) goto initphy_err; +/* Keep this interface runtime-PM active by taking a usage ref. +* Prevents runtime suspend while bound and avoids resume paths +* that could deadlock (autoresume under RTNL while USB PM lock +* is held, phylink/MDIO wants RTNL). +*/ +pm_runtime_get_noresume (&intf->dev); +return 0 ; initphy_err:
@@ -948,6 +970,8 @@ static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf)phylink_destroy (priv->phylink);ax88772_mdio_unregister (priv);asix_rx_fixup_common_free (dev->driver_priv); +/* Drop the PM usage ref taken in bind() */ +pm_runtime_put (&intf->dev); }static void ax88178_unbind (struct usbnet *dev,struct usb_interface *intf)
@@ -1600,6 +1624,11 @@ static struct usb_driver asix_driver = { .resume = asix_resume, .reset_resume = asix_resume, .disconnect = usbnet_disconnect, +/* usbnet enables autosuspend by default (supports_autosuspend=1). +* We keep runtime-PM active for AX88772* by taking a PM usage +* reference in ax88772_bind() (pm_runtime_get_noresume()) and +* dropping it in unbind(), which effectively blocks autosuspend. +*/ .supports_autosuspend = 1, .disable_hub_initiated_lpm = 1, };
Sasha Levin
maintainerPATCH 1/1 net: usb: asix: hold PM usage ref to avoid PM/MDIO + RTNL deadlock
From: Oleksij Rempel <[email protected]>
[ Upstream commit 3d3c4cd5c62f24bb3cb4511b7a95df707635e00a ]
Prevent USB runtime PM (autosuspend) for AX88772* in bind.
usbnet enables runtime PM (autosuspend) by default, so disabling it via the usb_driver flag is ineffective. On AX88772B, autosuspend shows no measurable power saving with current driver (no link partner, admin up/down). The ~0.453 W -> ~0.248 W drop on v6.1 comes from phylib powering the PHY off on admin-down, not from USB autosuspend.
The real hazard is that with runtime PM enabled, ndo_open() (under RTNL) may synchronously trigger autoresume (usb_autopm_get_interface()) into asix_resume() while the USB PM lock is held. Resume paths then invoke phylink/phylib and MDIO, which also expect RTNL, leading to possible deadlocks or PM lock vs MDIO wake issues.
To avoid this, keep the device runtime-PM active by taking a usage reference in ax88772_bind() and dropping it in unbind(). A non-zero PM usage count blocks runtime suspend regardless of userspace policy (.../power/control - pm_runtime_allow/forbid), making this approach robust against sysfs overrides.
Holding a runtime-PM usage ref does not affect system-wide suspend; system sleep/resume callbacks continue to run as before.
--- drivers/net/usb/asix_devices.c | 35 +++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-)
drivers/net/usb/asix_devices.c +34 -1
@@ -608,6 +608,21 @@ static void ax88772_suspend(struct usbnet *dev) asix_read_medium_status(dev, 1)); } +/* Notes on PM callbacks and locking context: +* +* - asix_suspend()/asix_resume() are invoked for both runtime PM and +* system-wide suspend/resume. For struct usb_driver the ->resume() +* callback does not receive pm_message_t, so the resume type cannot +* be distinguished here. +* +* - The MAC driver must hold RTNL when calling phylink interfaces such as +* phylink_suspend()/resume(). Those calls will also perform MDIO I/O. +* +* - Taking RTNL and doing MDIO from a runtime-PM resume callback (while +* the USB PM lock is held) is fragile. Since autosuspend brings no +* measurable power saving here, we block it by holding a PM usage +* reference in ax88772_bind(). +*/ static int asix_suspend (struct usb_interface *intf,pm_message_t message) {struct usbnet *dev =usb_get_intfdata (intf);
@@ -809,7 +824,18 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)if (ret)return ret; -return ax88772_init_phy (dev); + ret =ax88772_init_phy (dev); +if (ret) +return ret; + +/* Keep this interface runtime-PM active by taking a usage ref. +* Prevents runtime suspend while bound and avoids resume paths +* that could deadlock (autoresume under RTNL while USB PM lock +* is held, phylink/MDIO wants RTNL). +*/ +pm_runtime_get_noresume (&intf->dev); + +return 0 ; }static int ax88772_stop (struct usbnet *dev)
@@ -827,6 +853,8 @@ static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf)phy_disconnect (priv->phydev);asix_rx_fixup_common_free (dev->driver_priv); +/* Drop the PM usage ref taken in bind() */ +pm_runtime_put (&intf->dev); }static void ax88178_unbind (struct usbnet *dev,struct usb_interface *intf)
@@ -1452,6 +1480,11 @@ static struct usb_driver asix_driver = { .resume = asix_resume, .reset_resume = asix_resume, .disconnect = usbnet_disconnect, +/* usbnet enables autosuspend by default (supports_autosuspend=1). +* We keep runtime-PM active for AX88772* by taking a PM usage +* reference in ax88772_bind() (pm_runtime_get_noresume()) and +* dropping it in unbind(), which effectively blocks autosuspend. +*/ .supports_autosuspend = 1, .disable_hub_initiated_lpm = 1, };
Signature · 1 line
2.51.0