]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
iflib: ensure that tx interrupts enabled and cleanups
authorMatt Macy <mmacy@FreeBSD.org>
Sat, 19 Dec 2020 01:08:33 +0000 (17:08 -0800)
committerKevin Bowling <kbowling@FreeBSD.org>
Sun, 3 Oct 2021 02:03:11 +0000 (19:03 -0700)
commita5a91bd2a09ffe748b6dd7d5f996fe725c22c774
treea3b4f7953e46a799c87e3a8ad993b555fb951912
parent660b6999cc95aa56f5981c538234bd3475b3abc5
iflib: ensure that tx interrupts enabled and cleanups

Doing a 'dd' over iscsi will reliably cause stalls. Tx
cleaning _should_ reliably happen as data is sent.
However, currently if the transmit queue fills it will
wait until the iflib timer (hz/2) runs.

This change causes the the tx taskq thread to be run
if there are completed descriptors.

While here:

- make timer interrupt delay a sysctl

- simplify txd_db_check handling

- comment on INTR types

Background on the change:

Initially doorbell updates were minimized by only writing to the register
on every fourth packet. If txq_drain would return without writing to the
doorbell it scheduled a callout on the next tick to do the doorbell write
to ensure that the write otherwise happened "soon". At that time a sysctl
was added for users to avoid the potential added latency by simply writing
to the doorbell register on every packet. This worked perfectly well for
e1000 and ixgbe ... and appeared to work well on ixl. However, as it
turned out there was a race to this approach that would lockup the ixl MAC.
It was possible for a lower producer index to be written after a higher one.
On e1000 and ixgbe this was harmless - on ixl it was fatal. My initial
response was to add a lock around doorbell writes - fixing the problem but
adding an unacceptable amount of lock contention.

The next iteration was to use transmit interrupts to drive delayed doorbell
writes. If there were no packets in the queue all doorbell writes would be
immediate as the queue started to fill up we could delay doorbell writes
further and further. At the start of drain if we've cleaned any packets we
know we've moved the state machine along and we write the doorbell (an
obvious missing optimization was to skip that doorbell write if db_pending
is zero). This change required that tx interrupts be scheduled periodically
as opposed to just when the hardware txq was full. However, that just leads
to our next problem.

Initially dedicated msix vectors were used for both tx and rx. However, it
was often possible to use up all available vectors before we set up all the
queues we wanted. By having rx and tx share a vector for a given queue we
could halve the number of vectors used by a given configuration. The problem
here is that with this change only e1000 passed the necessary value to have
the fast interrupt drive tx when appropriate.

Reported by: mav@
Tested by: mav@
Reviewed by:    gallatin@
MFC after:      1 month
Sponsored by:   iXsystems
Differential Revision:  https://reviews.freebsd.org/D27683

(cherry picked from commit 81be655266fac2b333e25f386f32c9bcd17f523d)
sys/dev/bnxt/if_bnxt.c
sys/dev/ice/if_ice_iflib.c
sys/dev/ixgbe/if_ix.c
sys/dev/ixgbe/if_ixv.c
sys/dev/ixl/if_iavf.c
sys/dev/ixl/if_ixl.c
sys/dev/vmware/vmxnet3/if_vmx.c
sys/net/iflib.c
sys/net/iflib.h