Skip site navigation (1)Skip section navigation (2)
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>