Add IFLIB_SINGLE_IRQ_RX_ONLY.

As of r347221 the iflib legacy interrupt mode setup assumes that drivers
perform both receive and transmit processing from the interrupt handler.
This assumption is invalid in the vmxnet3 driver, so introduce the
IFLIB_SINGLE_IRQ_RX_ONLY flag to make iflib avoid tx processing in the
interrupt handler.

PR:		239118
Reported and tested by:	Juraj Lutter <otis@sk.freebsd.org>
Obtained from:	marius
Reviewed by:	gallatin
MFC after:	3 days
Differential Revision:	https://reviews.freebsd.org/D21831
This commit is contained in:
Mark Johnston 2019-09-30 15:59:07 +00:00
parent 6e5eac8cc0
commit 4166913371
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=352906
3 changed files with 12 additions and 4 deletions

View File

@ -287,7 +287,7 @@ static struct if_shared_ctx vmxnet3_sctx_init = {
.isc_vendor_info = vmxnet3_vendor_info_array,
.isc_driver_version = "2",
.isc_driver = &vmxnet3_iflib_driver,
.isc_flags = IFLIB_HAS_RXCQ | IFLIB_HAS_TXCQ,
.isc_flags = IFLIB_HAS_RXCQ | IFLIB_HAS_TXCQ | IFLIB_SINGLE_IRQ_RX_ONLY,
/*
* Number of receive queues per receive queue set, with associated

View File

@ -6059,6 +6059,7 @@ iflib_legacy_setup(if_ctx_t ctx, driver_filter_t filter, void *filter_arg, int *
gtask_fn_t *fn;
void *q;
int err, tqrid;
bool rx_only;
q = &ctx->ifc_rxqs[0];
info = &rxq[0].ifr_filter_info;
@ -6066,17 +6067,19 @@ iflib_legacy_setup(if_ctx_t ctx, driver_filter_t filter, void *filter_arg, int *
tqg = qgroup_if_io_tqg;
tqrid = *rid;
fn = _task_fn_rx;
rx_only = (ctx->ifc_sctx->isc_flags & IFLIB_SINGLE_IRQ_RX_ONLY) != 0;
ctx->ifc_flags |= IFC_LEGACY;
info->ifi_filter = filter;
info->ifi_filter_arg = filter_arg;
info->ifi_task = gtask;
info->ifi_ctx = q;
info->ifi_ctx = rx_only ? ctx : q;
dev = ctx->ifc_dev;
/* We allocate a single interrupt resource */
if ((err = _iflib_irq_alloc(ctx, irq, tqrid, iflib_fast_intr_rxtx,
NULL, info, name)) != 0)
err = _iflib_irq_alloc(ctx, irq, tqrid, rx_only ? iflib_fast_intr_ctx :
iflib_fast_intr_rxtx, NULL, info, name);
if (err != 0)
return (err);
GROUPTASK_INIT(gtask, 0, fn, q);
res = irq->ii_res;

View File

@ -366,6 +366,11 @@ typedef enum {
* Driver will pass the media
*/
#define IFLIB_DRIVER_MEDIA 0x20000
/*
* When using a single hardware interrupt for the interface, only process RX
* interrupts instead of doing combined RX/TX processing.
*/
#define IFLIB_SINGLE_IRQ_RX_ONLY 0x40000
/*
* field accessors