On Thu, Oct 08, 2015 at 01:20 +0200, Hrvoje Popovski wrote:
> Hi all,
> 
> i have fairly simple setup with receiver connected to em2 and sender
> connected to em3. Both em are Intel I350. Setup is without pf with these
> sysctls:
> 
> kern.pool_debug=1
>        net.inet.ip.forwarding=1
> net.inet.ip.ifq.maxlen=8192
> ddb.console=1
> 
> with if_em.c revisions 1.307 and 1.306 i can trigger
> em2: unable to fill any rx descriptors
> when doing ifconfig em2 down/up (receiver side) while generating
> traffic. i can't trigger this with ifconfig em3 down/up (sender side) or
> destroying bridge and enabling it. this is reproducible.
> 
> with bridged setup when doing ifconfig em2 down/up i'm getting rx
> descriptors log and bridge stops bridging traffic until doing this:
> stop generating traffic
> ifconfig em2 down
> ifconfig em3 down
> ifconfig bridge0 destroy
> ifconfig em2 up
> ifconfig em3 up
> sh netstart bridge0
> start generating traffic
> 
> 
> with routed setup when doing ifconfig em2 down/up traffic is not
> forwarded until
> stop generating traffic
> ifconfig em2 down
> ifconfig em2 up
> start generating traffic
> 
> 
> with if_em.c revisions 1.305 and if_em.h revision 1.57 i can't trigger
> rx descriptors log and bridge starts to bridge traffic almost instantly
> when doing ifconfig em2 up
> 
> 
> i am willing to debug this further but i don't know how...
> 

Is it possible that em_reset_hw is called a bit too early
while we don't have full control of the driver?

Also it appears to me that while we're mi_switch'ing in the
sched_barrier/sleep_finish another process can start running
em_init since mi_switch will unlock all KERNEL_LOCKs that the
process doing em_stop might hold.  Now of course KASSERT would
have fired if IFF_RUNNING would have been set, but perhaps we
just haven't hit this yet.  Shouldn't we do rwlock protection
to make sure that while em_stop is not finished no other
process can do em_stop and/or em_init?

diff --git sys/dev/pci/if_em.c sys/dev/pci/if_em.c
index f2ddb32..7b24dce 100644
--- sys/dev/pci/if_em.c
+++ sys/dev/pci/if_em.c
@@ -1559,13 +1559,14 @@ em_stop(void *arg, int softonly)
        timeout_del(&sc->timer_handle);
        timeout_del(&sc->tx_fifo_timer_handle);
 
-       if (!softonly) {
+       if (!softonly)
                em_disable_intr(sc);
-               em_reset_hw(&sc->hw);
-       }
 
        intr_barrier(sc->sc_intrhand);
 
+       if (!softonly)
+               em_reset_hw(&sc->hw);
+
        KASSERT((ifp->if_flags & IFF_RUNNING) == 0);
 
        em_free_transmit_structures(sc);

Reply via email to