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);