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>

next in thread | previous in thread | raw e-mail | index | archive | help
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



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