[Bug 252165] mii bus media status race condition
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Sat Dec 26 16:14:32 UTC 2020
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=252165
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 at FreeBSD.org
Reporter: ali.abdallah at 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.255.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.
static void
miibus_linkchg(device_t dev)
{
...
if (mii->mii_media_status & IFM_AVALID) {
if (mii->mii_media_status & IFM_ACTIVE)
link_state = LINK_STATE_UP;
else
link_state = LINK_STATE_DOWN;
...
}
On the other hand, the function mii_pollstat running on another thread, polls
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 = IFM_AVALID;
mii->mii_media_active = 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 trigger a
link state change...
*/
if (rgephy_linkup(sc) != 0)
mii->mii_media_status |= 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_status
until rgephy_linkup(sc) returns link down.
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the freebsd-bugs
mailing list