[PATCH net-next v2 0/4] net: pse-pd: decouple controller lookup from MDIO probe
From: Carlo Szelinsky
Date: Sat Jun 20 2026 - 07:25:31 EST
This is v2 of Corey's RFC [1]. Corey is busy at the moment, so I'm picking
it up to unblock everyone. The design is unchanged. The main thing v2
fixes is the SFP deadlock Jonas reported, plus a couple of smaller points
from the review.
The problem:
When a PSE controller driver is built as a module and a DT PHY node has a
"pses = <&...>" phandle, fwnode_mdiobus_register_phy() tries to resolve the
PSE handle before the controller has probed. It gets -EPROBE_DEFER, the
MDIO/DSA probe fails, and driver-core keeps retrying until the PSE module
loads. Since fa2f0454174c each retry does a full phy_device_register() /
phy_device_remove() cycle, so on a board with a tight watchdog the retry
loop can reset the box before userspace is up.
Rather than make the retry cheaper, this takes the PSE lookup out of the
MDIO probe path completely. pse_core gets a notifier chain (REGISTERED /
UNREGISTERED), the phy layer subscribes, owns phydev->psec, and attaches the
PSE handle when the controller actually shows up instead of during probe.
fwnode_mdio no longer knows about PSE, so no -EPROBE_DEFER crosses that
boundary and the retry loop is gone.
What changed since v1:
- v1 made phy_device_register() hold rtnl across the whole registration,
including device_add(). That deadlocks a PHY that drives its own SFP cage:
device_add() -> phy_probe() -> phy_sfp_probe() -> sfp_bus_add_upstream(),
and sfp_bus_add_upstream() takes rtnl again. Jonas hit this with
RTL8214FC. v2 keeps device_add() out of rtnl and only takes rtnl around
the psec attach, which now runs after device_add(). Doing the attach
after the phy is on the bus keeps the PSE_REGISTERED race closed: either
the notifier walk finds the phy and attaches it, or our own attach does,
and the phydev->psec check makes that idempotent.
- A broken "pses" binding now gets a phydev_warn() instead of being
swallowed. -ENOENT (no phandle) and -EPROBE_DEFER stay quiet.
Tested on a Realtek rtl93xx PoE switch with two HS104 PSE controllers on
i2c:
- clean boot, no probe-retry loop, no watchdog reset
- 10G SFP+ port: module hotplug works, no deadlock (this is the path that
hung with v1)
- ethtool --set-pse enable/disable cuts and restores power to a connected PD
- full i2c unbind -> rmmod -> modprobe cycle: PSE detaches on unbind (module
refcount drops to 0 so rmmod works), and re-attaches on reload with power
restored, no reboot. No lockdep splats.
Tested-by: Carlo Szelinsky <github@xxxxxxxxxxxx>
One thing I'd like input on: the Fixes: tags. Patch 1 is a standalone
regulator lifetime fix and carries its own Fixes:. The boot-hang itself is
fixed by patches 2-4 together. Should those three carry
Fixes: fa2f0454174c so the fix can be backported, or should the series stay
net-next only? I'm fine either way.
[1] https://lore.kernel.org/netdev/20260423-pse-notifier-decouple-v1-0-86ed750a9d62@xxxxxxxxxxxx/
Corey Leavitt (4):
net: pse-pd: scope pse_control regulator handle to kref lifetime
net: pse-pd: add notifier chain for controller lifecycle events
net: pse-pd: fire lifecycle events on controller register/unregister
net: phy: own phydev->psec via PSE notifier and remove fwnode_mdio
hook
drivers/net/mdio/fwnode_mdio.c | 34 -------
drivers/net/phy/phy_device.c | 168 +++++++++++++++++++++++++++++++--
drivers/net/phy/sfp.c | 2 +-
drivers/net/pse-pd/pse_core.c | 60 +++++++++++-
include/linux/phy.h | 2 +
include/linux/pse-pd/pse.h | 41 ++++++++
6 files changed, 261 insertions(+), 46 deletions(-)
base-commit: b85966adbf5de0668a815c6e3527f87e0c387fb4
--
2.43.0