On 29/11/17(Wed) 18:25, Hrvoje Popovski wrote:
> hi all,
> 
> sending ip6 traffic from host connected to vlan200 on ix0 to host
> connected to vlan300 on ix1 and running
> 
> ifconfig vlan200 destroy
> ifconfig ix0 down
> sh netstart vlan200
> sh netstart ix0
> ifconfing vlan300 destroy
> ifconfig ix1 down
> sh netstart vlan300
> sh netstart ix1
> sh netstart
> 
> triggers panic.
> 
> i'm running current from today with WITNESS. there aren't any traffic
> over em interfaces except em0 which is ssh interface.
> 
> i will leave box in ddb if something else is needed
> 
> em2: watchdog: head 1 tail 0 TDH 1 TDT 1
> panic() at panic+0x141
> __assert(ffffffff813a2004,ffff800023bc4de0,0,ffff800000504000) at
> __assert+0x24
> 
> em_stop(ffff800000504000,7) at em_stop+0x118
> em_init(1) at em_init+0x25
> em_watchdog(0) at em_watchdog+0xc1
> if_watchdog_task(ffffffff810ff560) at if_watchdog_task+0xa4
> taskq_thread(0) at taskq_thread+0x67

This is a race in the em(4) driver.  When em_stop() sleeps in the
barriers a context switch can occurs.  If this context switch schedule
a thread that was already sleeping at the same point, like ifconfig,
you get this panic.

If believe em_init() should only be called if IFF_RUNNING is still set.

If you agree on that we should generalize this fix.

Index: if_em.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em.c,v
retrieving revision 1.336
diff -u -p -r1.336 if_em.c
--- if_em.c     25 Jul 2017 20:45:18 -0000      1.336
+++ if_em.c     7 Dec 2017 11:56:19 -0000
@@ -775,7 +775,8 @@ em_watchdog(struct ifnet *ifp)
            sc->sc_tx_desc_head, sc->sc_tx_desc_tail,
            E1000_READ_REG(&sc->hw, TDH), E1000_READ_REG(&sc->hw, TDT));
 
-       em_init(sc);
+       if (ifp->if_flags & IFF_RUNNING)
+               em_init(sc);
 
        sc->watchdog_events++;
 }

Reply via email to