Open jrichardson-neurio opened 2 years ago
ipconfig
is instantaneous for me using a Pi 3B running RPiOS bullseye with a 5.15.61 kernel, whether or not the Ethernet cable is plugged in.
I found the problem. SIOCETHTOOL ioctl was being called every second by ifplugd also. This causes get_link() to be called. smsc95xx_get_link() then calls phy_read_status(). It looks like that call is redundant because the phy state machine is already calling it. There is a huge performance hit in that scenario. It actually affects ifup from working on unrelated interfaces such as wifi. It will time out and fail to bring up the interface.
The best solution I've found is to get rid of get_link in smsc95xx or use ethtool_op_get_link. ethtool won't call it if it's unimplemented. I'll test ifplugd further.
If I kill ifplugd ifconfig is fast when cable is unplugged. I don't think that phy_read_status call from get_link is the right thing to do. Not exactly sure yet why the performace is so bad.
Try running '/usr/sbin/ifplugd -i eth0 -fI -u0 -d10' (busybox ifplugd) and see if you can repro.
I removed get_link from smsc95xx.c and it's fine. SIOCETHTOOL will be unimplemented for this driver but ifplugd has other methods of determining link state. When ifplugd calls this ioctl it takes 4 seconds to complete due to lan87xx_read_status() in the smsc phy sleeping. It looks like multiple paths into that function is the issue. The comment says it all:
Due to this abnormality I think get_state() should be removed from the smsc95xx driver. Maybe you could use the ethtool version to keep that ioctl implemented for some apps that may use it but it still introduces unnecessary overhead. That would be up to the maintainers of this driver.
Describe the bug
After upgrading to kirkstone and the 5.15 kernel I've noticed the smsc95xx driver is slow when the ethernet cable is unplugged. Running 'ifconfig' or 'ip' can take up to 20 seconds to complete but usually more like 5. Performance is good when the cable is plugged.
Steps to reproduce the behaviour
Unplug ethernet cable ifconfig or ip a
Device (s)
Raspberry Pi 3 Mod. B
System
OS: kirkstone branch of yocto poky, meta-openembedded, and meta-raspberrypi.
Linux lcm_0AFD 5.15.34-v7 #1 SMP Tue Oct 4 00:13:54 UTC 2022 armv7l GNU/Linux
Logs
No response
Additional context
It looks like this occurred around the 2.0.0 driver version on this commit:
commit 05b35e7eb9a11bbe8102836965e634c04e712c88 Author: Andre Edich andre.edich@microchip.com Date: Wed Aug 26 13:17:17 2020 +0200
The ethtool_ops get_link() function changed from usbnet_get_link() to smsc95xx_get_link().
On the current driver version 2.0.0 (commit fe83b18ef954a4b7eb920a40172a58f0c5f5aa8a) changing it back to usbnet_get_link() results in WARN's and is still slow. If I use ethtool_op_get_link() it is fast but it takes a long time to get an IP address when the cable is plugged in as it tries to resolve link status.
The ioctl sent from ifconfig is SIOCGIFCONF. The call stack is, roughly:
net/core/dev_ioctl.c: int dev_ifconf(struct net net, struct ifconf __user uifc) {