Intel 82574L interface wedging on em 7.1.9/7.2.3 when MSIX
enabled
Adrian Chadd
adrian at freebsd.org
Thu Nov 10 23:40:37 UTC 2011
In the case of multi-threaded OACTIVE, why not just do this:
upon queue completion:
* lock;
* do queue completion;
* if any frames were completed, clear queue busy;
* if (queue busy == clear && OACTIVE) clear OACTIVE;
* run queue completion;
* unlock.
upon queue transmit:
* lock;
* queue frame;
* if (fail) - mark queue as busy;
* if (all busy) - set OACTIVE.
* unlock
The stack will stop sending you frames whilst OACTIVE Is set, but will
continue sending them when you clear it.
If you just clear OACTIVE when _a_ queue is clear then you'll get
frames queued via start/transmit when queues are busy, but what you
won't do is starve them all until all queues have free slots. Ie, you
don't mind clearing it, then getting a frame and immediately finding
you're busy.
Once you've done that, any further issues are likely either
concurrency with accessing the tx/rx descriptor rings (per-queue), or
the interrupt handling races.
Ie, you disable interrupts, handle the tx queue completion, -then-
re-enable interrupts and clear masks. Maybe that logic in
igb_enable_intr() is to blame? Ie, que_mask / link_mask, is that
before or after the queue has been handled? If it's called after the
queue is handled, and que_mask / link_mask is 0, but the queue is
full, you'll never pick up the next interrupt as there won't be one?
2c,
Adrian
More information about the freebsd-net
mailing list