Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F133656073
D20175.id57116.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D20175.id57116.diff
View Options
Index: head/sys/net/iflib.c
===================================================================
--- head/sys/net/iflib.c
+++ head/sys/net/iflib.c
@@ -1461,6 +1461,7 @@
void *sc;
int i, cidx, result;
qidx_t txqid;
+ bool intr_enable, intr_legacy;
if (!iflib_started)
return (FILTER_STRAY);
@@ -1474,6 +1475,8 @@
ctx = rxq->ifr_ctx;
sc = ctx->ifc_softc;
+ intr_enable = false;
+ intr_legacy = !!(ctx->ifc_flags & IFC_LEGACY);
MPASS(rxq->ifr_ntxqirq);
for (i = 0; i < rxq->ifr_ntxqirq; i++) {
txqid = rxq->ifr_txqid[i];
@@ -1481,7 +1484,10 @@
bus_dmamap_sync(txq->ift_ifdi->idi_tag, txq->ift_ifdi->idi_map,
BUS_DMASYNC_POSTREAD);
if (!ctx->isc_txd_credits_update(sc, txqid, false)) {
- IFDI_TX_QUEUE_INTR_ENABLE(ctx, txqid);
+ if (intr_legacy)
+ intr_enable = true;
+ else
+ IFDI_TX_QUEUE_INTR_ENABLE(ctx, txqid);
continue;
}
GROUPTASK_ENQUEUE(&txq->ift_task);
@@ -1493,9 +1499,14 @@
if (iflib_rxd_avail(ctx, rxq, cidx, 1))
GROUPTASK_ENQUEUE(gtask);
else {
- IFDI_RX_QUEUE_INTR_ENABLE(ctx, rxq->ifr_id);
+ if (intr_legacy)
+ intr_enable = true;
+ else
+ IFDI_RX_QUEUE_INTR_ENABLE(ctx, rxq->ifr_id);
DBG_COUNTER_INC(rx_intr_enables);
}
+ if (intr_enable)
+ IFDI_INTR_ENABLE(ctx);
return (FILTER_HANDLED);
}
@@ -2352,7 +2363,9 @@
}
for (j = 0, fl = rxq->ifr_fl; j < rxq->ifr_nfl; j++, fl++) {
if (iflib_fl_setup(fl)) {
- device_printf(ctx->ifc_dev, "freelist setup failed - check cluster settings\n");
+ device_printf(ctx->ifc_dev,
+ "setting up free list %d failed - "
+ "check cluster settings\n", j);
goto done;
}
}
@@ -3733,7 +3746,10 @@
BUS_DMASYNC_POSTREAD);
if (ctx->isc_txd_credits_update(ctx->ifc_softc, txq->ift_id, false))
netmap_tx_irq(ifp, txq->ift_id);
- IFDI_TX_QUEUE_INTR_ENABLE(ctx, txq->ift_id);
+ if (ctx->ifc_flags & IFC_LEGACY)
+ IFDI_INTR_ENABLE(ctx);
+ else
+ IFDI_TX_QUEUE_INTR_ENABLE(ctx, txq->ift_id);
return;
}
#endif
@@ -3752,13 +3768,8 @@
ifmp_ring_check_drainage(txq->ift_br, TX_BATCH_SIZE);
if (ctx->ifc_flags & IFC_LEGACY)
IFDI_INTR_ENABLE(ctx);
- else {
-#ifdef INVARIANTS
- int rc =
-#endif
- IFDI_TX_QUEUE_INTR_ENABLE(ctx, txq->ift_id);
- KASSERT(rc != ENOTSUP, ("MSI-X support requires queue_intr_enable, but not implemented in driver"));
- }
+ else
+ IFDI_TX_QUEUE_INTR_ENABLE(ctx, txq->ift_id);
}
static void
@@ -3790,14 +3801,9 @@
if (more == false || (more = iflib_rxeof(rxq, budget)) == false) {
if (ctx->ifc_flags & IFC_LEGACY)
IFDI_INTR_ENABLE(ctx);
- else {
-#ifdef INVARIANTS
- int rc =
-#endif
- IFDI_RX_QUEUE_INTR_ENABLE(ctx, rxq->ifr_id);
- KASSERT(rc != ENOTSUP, ("MSI-X support requires queue_intr_enable, but not implemented in driver"));
- DBG_COUNTER_INC(rx_intr_enables);
- }
+ else
+ IFDI_RX_QUEUE_INTR_ENABLE(ctx, rxq->ifr_id);
+ DBG_COUNTER_INC(rx_intr_enables);
}
if (__predict_false(!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING)))
return;
@@ -4532,15 +4538,14 @@
int
iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ctxp)
{
- int err, rid, msix;
if_ctx_t ctx;
if_t ifp;
if_softc_ctx_t scctx;
- int i;
- uint16_t main_txq;
- uint16_t main_rxq;
+ kobjop_desc_t kobj_desc;
+ kobj_method_t *kobj_method;
+ int err, i, msix, rid;
+ uint16_t main_rxq, main_txq;
-
ctx = malloc(sizeof(* ctx), M_IFLIB, M_WAITOK|M_ZERO);
if (sc == NULL) {
@@ -4699,11 +4704,43 @@
* interrupt storm.
*/
IFDI_INTR_DISABLE(ctx);
- if (msix > 1 && (err = IFDI_MSIX_INTR_ASSIGN(ctx, msix)) != 0) {
- device_printf(dev, "IFDI_MSIX_INTR_ASSIGN failed %d\n", err);
- goto fail_queues;
- }
- if (msix <= 1) {
+
+ if (msix > 1) {
+ /*
+ * When using MSI-X, ensure that ifdi_{r,t}x_queue_intr_enable
+ * aren't the default NULL implementation.
+ */
+ kobj_desc = &ifdi_rx_queue_intr_enable_desc;
+ kobj_method = kobj_lookup_method(((kobj_t)ctx)->ops->cls, NULL,
+ kobj_desc);
+ if (kobj_method == &kobj_desc->deflt) {
+ device_printf(dev,
+ "MSI-X requires ifdi_rx_queue_intr_enable method");
+ err = EOPNOTSUPP;
+ goto fail_queues;
+ }
+ kobj_desc = &ifdi_tx_queue_intr_enable_desc;
+ kobj_method = kobj_lookup_method(((kobj_t)ctx)->ops->cls, NULL,
+ kobj_desc);
+ if (kobj_method == &kobj_desc->deflt) {
+ device_printf(dev,
+ "MSI-X requires ifdi_tx_queue_intr_enable method");
+ err = EOPNOTSUPP;
+ goto fail_queues;
+ }
+
+ /*
+ * Assign the MSI-X vectors.
+ * Note that the default NULL ifdi_msix_intr_assign method will
+ * fail here, too.
+ */
+ err = IFDI_MSIX_INTR_ASSIGN(ctx, msix);
+ if (err != 0) {
+ device_printf(dev, "IFDI_MSIX_INTR_ASSIGN failed %d\n",
+ err);
+ goto fail_queues;
+ }
+ } else {
rid = 0;
if (scctx->isc_intr == IFLIB_INTR_MSI) {
MPASS(msix == 1);
@@ -4743,6 +4780,7 @@
iflib_add_pfil(ctx);
ctx->ifc_flags |= IFC_INIT_DONE;
CTX_UNLOCK(ctx);
+
return (0);
fail_detach:
@@ -4957,6 +4995,7 @@
iflib_add_device_sysctl_post(ctx);
ctx->ifc_flags |= IFC_INIT_DONE;
CTX_UNLOCK(ctx);
+
return (0);
fail_detach:
ether_ifdetach(ctx->ifc_ifp);
@@ -5349,7 +5388,6 @@
return (0);
}
-
static int
iflib_queues_alloc(if_ctx_t ctx)
{
@@ -5608,17 +5646,20 @@
iflib_rxq_t rxq = ctx->ifc_rxqs;
int q;
#if defined(INET6) || defined(INET)
- int i, err;
+ int err, i;
#endif
for (q = 0; q < ctx->ifc_softc_ctx.isc_nrxqsets; q++, rxq++) {
#if defined(INET6) || defined(INET)
- tcp_lro_free(&rxq->ifr_lc);
- if ((err = tcp_lro_init_args(&rxq->ifr_lc, ctx->ifc_ifp,
- TCP_LRO_ENTRIES, min(1024,
- ctx->ifc_softc_ctx.isc_nrxd[rxq->ifr_fl_offset]))) != 0) {
- device_printf(ctx->ifc_dev, "LRO Initialization failed!\n");
- goto fail;
+ if (if_getcapabilities(ctx->ifc_ifp) & IFCAP_LRO) {
+ err = tcp_lro_init_args(&rxq->ifr_lc, ctx->ifc_ifp,
+ TCP_LRO_ENTRIES, min(1024,
+ ctx->ifc_softc_ctx.isc_nrxd[rxq->ifr_fl_offset]));
+ if (err != 0) {
+ device_printf(ctx->ifc_dev,
+ "LRO Initialization failed!\n");
+ goto fail;
+ }
}
#endif
IFDI_RXQ_SETUP(ctx, rxq->ifr_id);
@@ -5627,14 +5668,14 @@
#if defined(INET6) || defined(INET)
fail:
/*
- * Free RX software descriptors allocated so far, we will only handle
+ * Free LRO resources allocated so far, we will only handle
* the rings that completed, the failing case will have
- * cleaned up for itself. 'q' failed, so its the terminus.
+ * cleaned up for itself. 'q' failed, so its the terminus.
*/
rxq = ctx->ifc_rxqs;
for (i = 0; i < q; ++i, rxq++) {
- iflib_rx_sds_free(rxq);
- rxq->ifr_cq_cidx = 0;
+ if (if_getcapabilities(ctx->ifc_ifp) & IFCAP_LRO)
+ tcp_lro_free(&rxq->ifr_lc);
}
return (err);
#endif
@@ -5649,9 +5690,12 @@
iflib_rx_structures_free(if_ctx_t ctx)
{
iflib_rxq_t rxq = ctx->ifc_rxqs;
+ int i;
- for (int i = 0; i < ctx->ifc_softc_ctx.isc_nrxqsets; i++, rxq++) {
+ for (i = 0; i < ctx->ifc_softc_ctx.isc_nrxqsets; i++, rxq++) {
iflib_rx_sds_free(rxq);
+ if (if_getcapabilities(ctx->ifc_ifp) & IFCAP_LRO)
+ tcp_lro_free(&rxq->ifr_lc);
}
free(ctx->ifc_rxqs, M_IFLIB);
ctx->ifc_rxqs = NULL;
@@ -5822,7 +5866,10 @@
co += ctx->ifc_softc_ctx.isc_nrxqsets;
cpuid = find_nth(ctx, qid + co);
tid = get_core_offset(ctx, type, qid);
- MPASS(tid >= 0);
+ if (tid < 0) {
+ device_printf(dev, "get_core_offset failed\n");
+ return (EOPNOTSUPP);
+ }
cpuid = find_close_core(cpuid, tid);
err = taskqgroup_attach_cpu(tqg, gtask, uniq, cpuid, dev, irq->ii_res,
name);
@@ -5834,7 +5881,7 @@
if (cpuid > ctx->ifc_cpuid_highest)
ctx->ifc_cpuid_highest = cpuid;
#endif
- return 0;
+ return (0);
}
int
@@ -5894,7 +5941,9 @@
intr_fast = iflib_fast_intr_ctx;
break;
default:
- panic("unknown net intr type");
+ device_printf(ctx->ifc_dev, "%s: unknown net intr type\n",
+ __func__);
+ return (EINVAL);
}
info->ifi_filter = filter;
@@ -6005,11 +6054,12 @@
info->ifi_filter = filter;
info->ifi_filter_arg = filter_arg;
info->ifi_task = gtask;
- info->ifi_ctx = ctx;
+ info->ifi_ctx = q;
dev = ctx->ifc_dev;
/* We allocate a single interrupt resource */
- if ((err = _iflib_irq_alloc(ctx, irq, tqrid, iflib_fast_intr_ctx, NULL, info, name)) != 0)
+ if ((err = _iflib_irq_alloc(ctx, irq, tqrid, iflib_fast_intr_rxtx,
+ NULL, info, name)) != 0)
return (err);
GROUPTASK_INIT(gtask, 0, fn, q);
res = irq->ii_res;
@@ -6174,9 +6224,8 @@
device_t dev = ctx->ifc_dev;
if_shared_ctx_t sctx = ctx->ifc_sctx;
if_softc_ctx_t scctx = &ctx->ifc_softc_ctx;
- int vectors, queues, rx_queues, tx_queues, queuemsgs, msgs;
- int iflib_num_tx_queues, iflib_num_rx_queues;
- int err, admincnt, bar;
+ int admincnt, bar, err, iflib_num_rx_queues, iflib_num_tx_queues;
+ int msgs, queuemsgs, queues, rx_queues, tx_queues, vectors;
iflib_num_tx_queues = ctx->ifc_sysctl_ntxqs;
iflib_num_rx_queues = ctx->ifc_sysctl_nrxqs;
@@ -6185,8 +6234,6 @@
device_printf(dev, "msix_init qsets capped at %d\n",
imax(scctx->isc_ntxqsets, scctx->isc_nrxqsets));
- bar = ctx->ifc_softc_ctx.isc_msix_bar;
- admincnt = sctx->isc_admin_intrcnt;
/* Override by tuneable */
if (scctx->isc_disable_msix)
goto msi;
@@ -6197,6 +6244,8 @@
device_printf(dev, "MSI-X not supported or disabled\n");
goto msi;
}
+
+ bar = ctx->ifc_softc_ctx.isc_msix_bar;
/*
* bar == -1 => "trust me I know what I'm doing"
* Some drivers are for hardware that is so shoddily
@@ -6212,6 +6261,8 @@
goto msi;
}
}
+
+ admincnt = sctx->isc_admin_intrcnt;
#if IFLIB_DEBUG
/* use only 1 qset in debug mode */
queuemsgs = min(msgs - admincnt, 1);
@@ -6263,11 +6314,30 @@
rx_queues = min(rx_queues, tx_queues);
}
+ vectors = rx_queues + admincnt;
+ if (msgs < vectors) {
+ device_printf(dev,
+ "insufficient number of MSI-X vectors "
+ "(supported %d, need %d)\n", msgs, vectors);
+ goto msi;
+ }
+
device_printf(dev, "Using %d RX queues %d TX queues\n", rx_queues,
tx_queues);
-
- vectors = rx_queues + admincnt;
+ msgs = vectors;
if ((err = pci_alloc_msix(dev, &vectors)) == 0) {
+ if (vectors != msgs) {
+ device_printf(dev,
+ "Unable to allocate sufficient MSI-X vectors "
+ "(got %d, need %d)\n", vectors, msgs);
+ pci_release_msi(dev);
+ if (bar != -1) {
+ bus_release_resource(dev, SYS_RES_MEMORY, bar,
+ ctx->ifc_msix_mem);
+ ctx->ifc_msix_mem = NULL;
+ }
+ goto msi;
+ }
device_printf(dev, "Using MSI-X interrupts with %d vectors\n",
vectors);
scctx->isc_vectors = vectors;
@@ -6278,12 +6348,15 @@
return (vectors);
} else {
device_printf(dev,
- "failed to allocate %d MSI-X vectors, err: %d - using MSI\n",
- vectors, err);
- bus_release_resource(dev, SYS_RES_MEMORY, bar,
- ctx->ifc_msix_mem);
- ctx->ifc_msix_mem = NULL;
+ "failed to allocate %d MSI-X vectors, err: %d\n", vectors,
+ err);
+ if (bar != -1) {
+ bus_release_resource(dev, SYS_RES_MEMORY, bar,
+ ctx->ifc_msix_mem);
+ ctx->ifc_msix_mem = NULL;
+ }
}
+
msi:
vectors = pci_msi_count(dev);
scctx->isc_nrxqsets = 1;
@@ -6345,8 +6418,6 @@
char *p, *next;
int nqs, rc, i;
- MPASS(type == IFLIB_NTXD_HANDLER || type == IFLIB_NRXD_HANDLER);
-
nqs = 8;
switch(type) {
case IFLIB_NTXD_HANDLER:
@@ -6360,7 +6431,8 @@
nqs = ctx->ifc_sctx->isc_nrxqs;
break;
default:
- panic("unhandled type");
+ printf("%s: unhandled type\n", __func__);
+ return (EINVAL);
}
if (nqs == 0)
nqs = 8;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Oct 28, 8:03 AM (3 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24347251
Default Alt Text
D20175.id57116.diff (11 KB)
Attached To
Mode
D20175: iflib: Correct and optimize interrupt handling, assorted fixes and improvements
Attached
Detach File
Event Timeline
Log In to Comment