Page MenuHomeFreeBSD

D20175.id57116.diff
No OneTemporary

D20175.id57116.diff

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

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)

Event Timeline