Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Nov 2011 15:40:36 -0800
From:      Adrian Chadd <adrian@freebsd.org>
To:        Jack Vogel <jfvogel@gmail.com>
Cc:        pyunyh@gmail.com, freebsd-net@freebsd.org, Jason Wolfe <nitroboost@gmail.com>, Emil Muratov <gpm@hotplug.ru>, Hooman Fazaeli <hoomanfazaeli@gmail.com>
Subject:   Re: Intel 82574L interface wedging on em 7.1.9/7.2.3 when MSIX enabled
Message-ID:  <CAJ-VmommA0HWWPWYGQQMri9s4GETU%2BYq0qwCpQPT-1nH=A5sUQ@mail.gmail.com>
In-Reply-To: <CAFOYbcnVvL1DHxEgfpRjcAH6QpiYwwRZDUiWF%2BRVTx=xhuxgSA@mail.gmail.com>
References:  <CAAAm0r0RXEJo4UiKS=Ui0e5OQTg6sg-xcYf3mYB5%2Bvk8i8557w@mail.gmail.com> <CAAAm0r1DKvoL9=Ket9up=4%2B5xiCzTTZJK99FhF9jcCA28B0M%2BA@mail.gmail.com> <CAAAm0r3XdsMHZh%2BP_NF-txZasdExzwZ8ymmGQgGhJQds0fOiBQ@mail.gmail.com> <CAAAm0r1iS3z-7CBJ=xYDf%2BJOA1Q2nU0O54Twbyb7FjvgWHjKVw@mail.gmail.com> <4EA7E203.3020306@sepehrs.com> <CAAAm0r3Nr2t8cCetPkFnLQ-3KwqHw_0SpqbtvYPRUkSP=9n8CA@mail.gmail.com> <4EA80818.3030504@sentex.net> <4EA80F88.4000400@hotplug.ru> <4EA82715.2000404@gmail.com> <4EA8FA40.7010504@hotplug.ru> <4EA91836.2040508@gmail.com> <4EA959EE.2070806@hotplug.ru> <4EAD116A.8090006@gmail.com> <CAAAm0r3qm=nQQuAmZDD4k4X8K-xW6_kM9TukRT=1GoG9dYR3zw@mail.gmail.com> <4EAE58A2.9040803@gmail.com> <CAAAm0r0uoPPEQbq5rHkFr6ZLp-WJ4YVjDVvxxV6y%2BUh4eEKDEA@mail.gmail.com> <4EB96511.50701@gmail.com> <CAJ-Vmomf-wxb8dY7YF7qT_FGK5d-YLPU3BkPOeHnOtKZ%2BUrYeQ@mail.gmail.com> <4EBA3F22.2060204@gmail.com> <CAJ-Vmok8kX9F5eXTghx_s7diNiLTWY1-eMDUdCOUHQCz6zW%2BPg@mail.gmail.com> <4EBB9CDF.9090300@gmail.com> <CAJ-VmokfZOHUptqVcfz49ogzk0qCAdSXTO2p8_M=-fAcF4h=1g@mail.gmail.com> <CAFOYbcnVvL1DHxEgfpRjcAH6QpiYwwRZDUiWF%2BRVTx=xhuxgSA@mail.gmail.com>

index | next in thread | previous in thread | raw e-mail

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


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-VmommA0HWWPWYGQQMri9s4GETU%2BYq0qwCpQPT-1nH=A5sUQ>