misc/72183: em driver em_poll doesn't start send if pending packets
mark at verniernetworks.com
Wed Sep 29 14:10:23 PDT 2004
>Synopsis: em driver em_poll doesn't start send if pending packets
>Arrival-Date: Wed Sep 29 21:10:22 GMT 2004
>Originator: Mark Gooderum
>Release: 5.3 Beta 4
Vernier Networks, Inc.
FreeBSD 172.20.1.199 5.3-BETA4 FreeBSD 5.3-BETA4 #6: Tue Sep 28 21:35:19 PDT 2004 root at eagle.jumpadmin.net:/usr/build/ambit2/freebsd5/sys/i386/compile/VNISMP i386
The em driver has a reversed bit of logic in em_intr() - it will only restart transmission if the queue is empty, not if it is full. em_poll DTRT. Under high enough loads you can wedge a particular instance of an em interface although an ifconfig down/up will clear the condition. The bug is still present in Beta 6.
Blast a _lot_ of packets at the system with very little local activity. We flushed this problem doing GigE<->GigE throughput tests with an Ixia. Once the queue is full the interface will wedge on transmit because ifq_handoff() will never tickled if_start/em_start and em_intr() will incorrectly not call em_start_locked(). Downing/uping the interface will recover because the queue will be flushed - switching to polled will too as em_poll() DTRT.
If there is enough local activity the local sends will tickled em_start often enough to keep the queue from filling. It's hard to reproduce the lockup without a piece of gear like an Ixia or Smartbits but the flaw in th elogic is obvious.
The following patch has fixed the problem for us:
--- /tmp/tmp.44554.0 Wed Sep 29 15:52:32 2004
+++ /data/work/mark/5.3B4A1.i386/usr/build/ambit2/freebsd5/sys/dev/em/if_em.c Wed Sep 29 15:51:31 2004
@@ -986,11 +986,11 @@
- if (ifp->if_flags & IFF_RUNNING && IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ if (ifp->if_flags & IFF_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
More information about the freebsd-bugs