Date: Sat, 26 Dec 2020 16:14:32 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 252165] mii bus media status race condition Message-ID: <bug-252165-227@https.bugs.freebsd.org/bugzilla/>
next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D252165 Bug ID: 252165 Summary: mii bus media status race condition Product: Base System Version: CURRENT Hardware: Any OS: Any Status: New Severity: Affects Many People Priority: --- Component: kern Assignee: bugs@FreeBSD.org Reporter: ali.abdallah@suse.com I'm using if_ure on a USB-C dock station. I'm having the following random issue: Dec 25 12:20:10 Fryzen495 kernel: ue0: link state changed to UP Dec 25 12:20:10 Fryzen495 kernel: ue0: link state changed to DOWN Dec 25 12:20:10 Fryzen495 kernel: ue0: link state changed to UP Dec 25 12:20:58 Fryzen495 kernel: ue0: link state changed to DOWN Dec 25 12:21:01 Fryzen495 kernel: ue0: link state changed to UP Dec 25 12:21:07 Fryzen495 dhclient[20388]: New IP Address (ue0): 192.168.1.= 145 Dec 25 12:21:07 Fryzen495 dhclient[21191]: New Subnet Mask (ue0): 255.255.2= 55.0 Dec 25 12:21:07 Fryzen495 dhclient[22099]: New Broadcast Address (ue0): 192.168.1.255 Dec 25 12:21:07 Fryzen495 dhclient[22651]: New Routers (ue0): 192.168.1.254 After digging into the code, I've discovered that the issue is caused by the following race condition: In mii/mii.c, the function miibus_linkchg(device_t dev) reads mii->mii_media_status and sets the link state accordingly.=20 static void miibus_linkchg(device_t dev) { ... if (mii->mii_media_status & IFM_AVALID) { if (mii->mii_media_status & IFM_ACTIVE) link_state =3D LINK_STATE_UP; else link_state =3D LINK_STATE_DOWN; ... } On the other hand, the function mii_pollstat running on another thread, pol= ls the media status, which is using rgephy.c code in my case. (via PHY_SERVICE call) static void rgephy_status(struct mii_softc *sc) { mii->mii_media_status =3D IFM_AVALID; mii->mii_media_active =3D IFM_ETHER; /* HERE IS THE ISSUE The read in miibus_linkchg is randomly seeing mii->mii_media_status as IFM_AVALID, but it does not yet have the IFM_ACTIVE flag set, which makes it trigg= er a link state change... */ if (rgephy_linkup(sc) !=3D 0) mii->mii_media_status |=3D IFM_ACTIVE; ... This is an issue in all miibus modules, rgephy.c, truephy.c, mlphy.c, etc... Please note that also in mii_pollstat, mii->mii_media_status is initialized= to 0 (not sure why), and that also races with miibus_linkchg. There are many ways to fix it, locally I'm not resetting mii->mii_media_sta= tus until rgephy_linkup(sc) returns link down. --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-252165-227>