racing ndo_open()/phylink*connect() with phy_probe()

Andrew Halaney
2024-04-30T21:02:28Z

Hi,

I've been taking a look at the following error message:

qcom-ethqos 23000000.ethernet end1: __stmmac_open: Cannot attach to PHY (error: -19)

end1 is using a phy on the mdio bus of end0, not on its own bus. Something
like this devicetree snippet highlights the relationship:

// end0
&ethernet0 {
phy-mode = "sgmii";
phy-handle = <&sgmii_phy0>;

mdio {
compatible = "snps,dwmac-mdio";
sgmii_phy0: phy@8 {
compatible = "ethernet-phy-id0141.0dd4";
reg = <0x8>;
device_type = "ethernet-phy";
};

sgmii_phy1: phy@a {
compatible = "ethernet-phy-id0141.0dd4";
reg = <0xa>;
device_type = "ethernet-phy";
};
};
};

// end1
&ethernet1 {
phy-mode = "sgmii";
phy-handle = <&sgmii_phy1>;
};

Basically, NetworkManager is setting both interfaces to up, and end1's
phy doesn't seem to be ready when ndo_open() runs, returning
-ENODEV in phylink_fwnode_phy_connect() and bubbling that back up. This doesn't
happen very often, but by shoving things into the initramfs or anything to
speed up probe/ndo_open() it's easier to reproduce. Delaying probe()
of end0 and then setting end1 up is another easy way to reproduce.

My question after looking around for a while, is what is the expectation
of userspace in this situation?

NetworkManager retries 4 times right now (tunable via autoconnect-retries setting),
and if you're lucky that's good enough. You could tell it to retry infinitely,
that should get me out of my bind at least, but it's not an amazing solution.

I'm used to dealing with deferral issues in probe() callbacks, but
to me it seems that phylink and netdev sort of move the phy part of the problem
till later (so you don't get the kernel retrying for you, etc, like you do
with deferred probes) when you ndo_open(). I guess the logic there is that
the phys could be hot pluggable, so with phylink we delay getting at them
until ndo_open()? I also guess if the mac is going to create an mdio bus
with phys off of it that also gets dicey as the phy could -EPROBE_DEFER
when you're trying to probe the mac and confirm its phy is ready..

Is retrying the correct solution here from userspace, or am I missing something?
I thought the "does not support carrier detection" below might be my ticket out
of this, but I can still reproduce it even after patching[0] to make that work.
I guess NetworkManager still brings the device up, but doesn't "activate" the
connection until the carrier detect stuff is done.

[0] https://lore.kernel.org/netdev/20240429-stmmac-no-ethtool-begin-v1-1-04c629c1c142@redhat.com/

Thanks,
Andrew

Some logs to illustrate the issue with a little more context (without
the patch in [0], in the end that doesn't help):

[ 1.541839] fedora kernel: qcom-ethqos 23000000.ethernet end1: renamed from eth0
[ 1.545750] fedora NetworkManager[407]: <info> [1709251201.1647] device (eth0): driver '(null)' does not support carrier detection.
[ 1.545826] fedora NetworkManager[407]: <info> [1709251201.1657] device (eth0): driver 'unknown' does not support carrier detection.
[ 1.545854] fedora NetworkManager[407]: <info> [1709251201.1660] manager: (eth0): new Ethernet device (/org/freedesktop/NetworkManager/Devices/2)
[ 1.545880] fedora NetworkManager[407]: <info> [1709251201.1678] device (eth0): interface index 2 renamed iface from 'eth0' to 'end1'
[ 1.551721] fedora NetworkManager[407]: <info> [1709251201.1794] device (end1): state change: unmanaged -> unavailable (reason 'managed', sys-iface-state: 'external')
[ 1.554944] fedora kernel: qcom-ethqos 23000000.ethernet end1: Register MEM_TYPE_PAGE_POOL RxQ-0
[ 1.555962] fedora kernel: qcom-ethqos 23000000.ethernet end1: Register MEM_TYPE_PAGE_POOL RxQ-1
[ 1.557711] fedora kernel: qcom-ethqos 23000000.ethernet end1: Register MEM_TYPE_PAGE_POOL RxQ-2
[ 1.558721] fedora kernel: qcom-ethqos 23000000.ethernet end1: Register MEM_TYPE_PAGE_POOL RxQ-3
[ 1.560297] fedora kernel: qcom-ethqos 23000000.ethernet end1: __stmmac_open: Cannot attach to PHY (error: -19)
[ 1.573664] fedora NetworkManager[407]: <info> [1709251201.2013] device (end1): state change: unavailable -> disconnected (reason 'none', sys-iface-state: 'managed')
[ 1.574344] fedora NetworkManager[407]: <info> [1709251201.2020] policy: auto-activating connection 'Wired Connection' (bfe920e8-6031-4129-bf5c-78198427076a)
[ 1.574733] fedora NetworkManager[407]: <info> [1709251201.2024] device (end1): Activation: starting connection 'Wired Connection' (bfe920e8-6031-4129-bf5c-78198427076a)
[ 1.578589] fedora kernel: qcom-ethqos 23000000.ethernet end1: Register MEM_TYPE_PAGE_POOL RxQ-0
[ 1.579351] fedora kernel: qcom-ethqos 23000000.ethernet end1: Register MEM_TYPE_PAGE_POOL RxQ-1
[ 1.580102] fedora kernel: qcom-ethqos 23000000.ethernet end1: Register MEM_TYPE_PAGE_POOL RxQ-2
[ 1.578337] fedora NetworkManager[407]: <info> [1709251201.2027] device (end1): state change: disconnected -> prepare (reason 'none', sys-iface-state: 'managed')
[ 1.578404] fedora NetworkManager[407]: <info> [1709251201.2030] manager: NetworkManager state is now CONNECTING
[ 1.578431] fedora NetworkManager[407]: <info> [1709251201.2033] device (end1): state change: prepare -> config (reason 'none', sys-iface-state: 'managed')
[ 1.580965] fedora kernel: qcom-ethqos 23000000.ethernet end1: Register MEM_TYPE_PAGE_POOL RxQ-3
[ 1.582390] fedora kernel: qcom-ethqos 23000000.ethernet end1: __stmmac_open: Cannot attach to PHY (error: -19)
[ 1.593993] fedora NetworkManager[407]: <info> [1709251201.2217] device (end1): state change: config -> failed (reason 'config-failed', sys-iface-state: 'managed')
[ 1.648395] fedora NetworkManager[407]: <info> [1709251201.2220] manager: NetworkManager state is now DISCONNECTED
[ 1.648634] fedora NetworkManager[407]: <warn> [1709251201.2222] device (end1): Activation: failed for connection 'Wired Connection'
[ 1.648926] fedora NetworkManager[407]: <info> [1709251201.2224] device (end1): state change: failed -> disconnected (reason 'none', sys-iface-state: 'managed')
[ 1.649179] fedora NetworkManager[407]: <info> [1709251201.2233] manager: startup complete
[ 1.834016] fedora NetworkManager[407]: <info> [1709251201.4617] device (eth0): driver '(null)' does not support carrier detection.
[ 1.836553] fedora NetworkManager[407]: <info> [1709251201.4624] device (eth0): driver 'unknown' does not support carrier detection.
[ 1.836628] fedora NetworkManager[407]: <info> [1709251201.4627] manager: (eth0): new Ethernet device (/org/freedesktop/NetworkManager/Devices/3)
[ 1.896859] fedora kernel: qcom-ethqos 23040000.ethernet end0: renamed from eth0
[ 1.902243] fedora NetworkManager[407]: <info> [1709251201.5299] device (eth0): interface index 3 renamed iface from 'eth0' to 'end0'
[ 1.911400] fedora kernel: qcom-ethqos 23040000.ethernet end0: Register MEM_TYPE_PAGE_POOL RxQ-0
[ 1.909632] fedora NetworkManager[407]: <info> [1709251201.5357] device (end0): state change: unmanaged -> unavailable (reason 'managed', sys-iface-state: 'external')