Changeset View
Changeset View
Standalone View
Standalone View
sys/net/iflib.c
Show First 20 Lines • Show All 4,379 Lines • ▼ Show 20 Lines | if (scctx->isc_nrxd[i] < sctx->isc_nrxd_min[i]) { | ||||
i, scctx->isc_nrxd[i], sctx->isc_nrxd_min[i]); | i, scctx->isc_nrxd[i], sctx->isc_nrxd_min[i]); | ||||
scctx->isc_nrxd[i] = sctx->isc_nrxd_min[i]; | scctx->isc_nrxd[i] = sctx->isc_nrxd_min[i]; | ||||
} | } | ||||
if (scctx->isc_nrxd[i] > sctx->isc_nrxd_max[i]) { | if (scctx->isc_nrxd[i] > sctx->isc_nrxd_max[i]) { | ||||
device_printf(dev, "nrxd%d: %d greater than nrxd_max %d - resetting to max\n", | device_printf(dev, "nrxd%d: %d greater than nrxd_max %d - resetting to max\n", | ||||
i, scctx->isc_nrxd[i], sctx->isc_nrxd_max[i]); | i, scctx->isc_nrxd[i], sctx->isc_nrxd_max[i]); | ||||
scctx->isc_nrxd[i] = sctx->isc_nrxd_max[i]; | scctx->isc_nrxd[i] = sctx->isc_nrxd_max[i]; | ||||
} | } | ||||
if (!powerof2(scctx->isc_nrxd[i])) { | |||||
int rounded = 1 << (fls(scctx->isc_nrxd[i]) - 1); | |||||
device_printf(dev, "nrxd%d: %d is not a power of 2 - rounding down to %d\n", | |||||
i, scctx->isc_nrxd[i], rounded); | |||||
scctx->isc_nrxd[i] = rounded; | |||||
marius: As previously suggested, please just go with sctx->isc_nrxd_default[i] in case the user… | |||||
} | } | ||||
} | |||||
for (i = 0; i < sctx->isc_ntxqs; i++) { | for (i = 0; i < sctx->isc_ntxqs; i++) { | ||||
if (scctx->isc_ntxd[i] < sctx->isc_ntxd_min[i]) { | if (scctx->isc_ntxd[i] < sctx->isc_ntxd_min[i]) { | ||||
device_printf(dev, "ntxd%d: %d less than ntxd_min %d - resetting to min\n", | device_printf(dev, "ntxd%d: %d less than ntxd_min %d - resetting to min\n", | ||||
i, scctx->isc_ntxd[i], sctx->isc_ntxd_min[i]); | i, scctx->isc_ntxd[i], sctx->isc_ntxd_min[i]); | ||||
scctx->isc_ntxd[i] = sctx->isc_ntxd_min[i]; | scctx->isc_ntxd[i] = sctx->isc_ntxd_min[i]; | ||||
} | } | ||||
jacob.e.keller_intel.comAuthorUnsubmitted Done Inline ActionsShould we move the minimum check to after the round down? or should we add a 2nd minimum check? I.e. in the off chance that the minimum value the driver specifies isn't a power of 2, we'd round down below what the minimum hardware support is. jacob.e.keller_intel.com: Should we move the minimum check to after the round down? or should we add a 2nd minimum check? | |||||
if (scctx->isc_ntxd[i] > sctx->isc_ntxd_max[i]) { | if (scctx->isc_ntxd[i] > sctx->isc_ntxd_max[i]) { | ||||
device_printf(dev, "ntxd%d: %d greater than ntxd_max %d - resetting to max\n", | device_printf(dev, "ntxd%d: %d greater than ntxd_max %d - resetting to max\n", | ||||
i, scctx->isc_ntxd[i], sctx->isc_ntxd_max[i]); | i, scctx->isc_ntxd[i], sctx->isc_ntxd_max[i]); | ||||
scctx->isc_ntxd[i] = sctx->isc_ntxd_max[i]; | scctx->isc_ntxd[i] = sctx->isc_ntxd_max[i]; | ||||
} | } | ||||
if (!powerof2(scctx->isc_ntxd[i])) { | |||||
int rounded = 1 << (fls(scctx->isc_ntxd[i]) - 1); | |||||
jacob.e.keller_intel.comAuthorUnsubmitted Done Inline ActionsI feel like this should be some sort of macro we can call, but I'm not sure where to put it. Also, I don't know how to make it size-agnostic. jacob.e.keller_intel.com: I feel like this should be some sort of macro we can call, but I'm not sure where to put it. | |||||
device_printf(dev, "ntxd%d: %d is not a power of 2 - rounding down to %d\n", | |||||
i, scctx->isc_ntxd[i], rounded); | |||||
scctx->isc_ntxd[i] = rounded; | |||||
Done Inline ActionsLikewise for sctx->isc_nrxd* marius: Likewise for sctx->isc_nrxd* | |||||
} | } | ||||
} | } | ||||
} | |||||
int | int | ||||
iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ctxp) | iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ctxp) | ||||
{ | { | ||||
int err, rid, msix; | int err, rid, msix; | ||||
if_ctx_t ctx; | if_ctx_t ctx; | ||||
if_t ifp; | if_t ifp; | ||||
if_softc_ctx_t scctx; | if_softc_ctx_t scctx; | ||||
int i; | |||||
uint16_t main_txq; | uint16_t main_txq; | ||||
uint16_t main_rxq; | uint16_t main_rxq; | ||||
ctx = malloc(sizeof(* ctx), M_IFLIB, M_WAITOK|M_ZERO); | ctx = malloc(sizeof(* ctx), M_IFLIB, M_WAITOK|M_ZERO); | ||||
if (sc == NULL) { | if (sc == NULL) { | ||||
sc = malloc(sctx->isc_driver->size, M_IFLIB, M_WAITOK|M_ZERO); | sc = malloc(sctx->isc_driver->size, M_IFLIB, M_WAITOK|M_ZERO); | ||||
Show All 38 Lines | if (scctx->isc_nrxqsets == 0 || (scctx->isc_nrxqsets_max && scctx->isc_nrxqsets_max < scctx->isc_nrxqsets)) | ||||
scctx->isc_nrxqsets = scctx->isc_nrxqsets_max; | scctx->isc_nrxqsets = scctx->isc_nrxqsets_max; | ||||
main_txq = (sctx->isc_flags & IFLIB_HAS_TXCQ) ? 1 : 0; | main_txq = (sctx->isc_flags & IFLIB_HAS_TXCQ) ? 1 : 0; | ||||
main_rxq = (sctx->isc_flags & IFLIB_HAS_RXCQ) ? 1 : 0; | main_rxq = (sctx->isc_flags & IFLIB_HAS_RXCQ) ? 1 : 0; | ||||
/* XXX change for per-queue sizes */ | /* XXX change for per-queue sizes */ | ||||
device_printf(dev, "Using %d tx descriptors and %d rx descriptors\n", | device_printf(dev, "Using %d tx descriptors and %d rx descriptors\n", | ||||
scctx->isc_ntxd[main_txq], scctx->isc_nrxd[main_rxq]); | scctx->isc_ntxd[main_txq], scctx->isc_nrxd[main_rxq]); | ||||
for (i = 0; i < sctx->isc_nrxqs; i++) { | |||||
if (!powerof2(scctx->isc_nrxd[i])) { | |||||
/* round down instead? */ | |||||
device_printf(dev, "# rx descriptors must be a power of 2\n"); | |||||
err = EINVAL; | |||||
goto fail_iflib_detach; | |||||
} | |||||
} | |||||
for (i = 0; i < sctx->isc_ntxqs; i++) { | |||||
if (!powerof2(scctx->isc_ntxd[i])) { | |||||
device_printf(dev, | |||||
"# tx descriptors must be a power of 2"); | |||||
err = EINVAL; | |||||
goto fail_iflib_detach; | |||||
} | |||||
} | |||||
if (scctx->isc_tx_nsegments > scctx->isc_ntxd[main_txq] / | if (scctx->isc_tx_nsegments > scctx->isc_ntxd[main_txq] / | ||||
MAX_SINGLE_PACKET_FRACTION) | MAX_SINGLE_PACKET_FRACTION) | ||||
scctx->isc_tx_nsegments = max(1, scctx->isc_ntxd[main_txq] / | scctx->isc_tx_nsegments = max(1, scctx->isc_ntxd[main_txq] / | ||||
MAX_SINGLE_PACKET_FRACTION); | MAX_SINGLE_PACKET_FRACTION); | ||||
if (scctx->isc_tx_tso_segments_max > scctx->isc_ntxd[main_txq] / | if (scctx->isc_tx_tso_segments_max > scctx->isc_ntxd[main_txq] / | ||||
MAX_SINGLE_PACKET_FRACTION) | MAX_SINGLE_PACKET_FRACTION) | ||||
scctx->isc_tx_tso_segments_max = max(1, | scctx->isc_tx_tso_segments_max = max(1, | ||||
▲ Show 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | |||||
fail_detach: | fail_detach: | ||||
ether_ifdetach(ctx->ifc_ifp); | ether_ifdetach(ctx->ifc_ifp); | ||||
fail_intr_free: | fail_intr_free: | ||||
iflib_free_intr_mem(ctx); | iflib_free_intr_mem(ctx); | ||||
fail_queues: | fail_queues: | ||||
iflib_tx_structures_free(ctx); | iflib_tx_structures_free(ctx); | ||||
iflib_rx_structures_free(ctx); | iflib_rx_structures_free(ctx); | ||||
fail_iflib_detach: | |||||
IFDI_DETACH(ctx); | IFDI_DETACH(ctx); | ||||
fail_unlock: | fail_unlock: | ||||
CTX_UNLOCK(ctx); | CTX_UNLOCK(ctx); | ||||
fail_ctx_free: | fail_ctx_free: | ||||
if (ctx->ifc_flags & IFC_SC_ALLOCATED) | if (ctx->ifc_flags & IFC_SC_ALLOCATED) | ||||
free(ctx->ifc_softc, M_IFLIB); | free(ctx->ifc_softc, M_IFLIB); | ||||
free(ctx, M_IFLIB); | free(ctx, M_IFLIB); | ||||
return (err); | return (err); | ||||
Show All 26 Lines | if ((err = iflib_register(ctx)) != 0) { | ||||
device_printf(dev, "%s: iflib_register failed %d\n", __func__, err); | device_printf(dev, "%s: iflib_register failed %d\n", __func__, err); | ||||
goto fail_ctx_free; | goto fail_ctx_free; | ||||
} | } | ||||
iflib_add_device_sysctl_pre(ctx); | iflib_add_device_sysctl_pre(ctx); | ||||
scctx = &ctx->ifc_softc_ctx; | scctx = &ctx->ifc_softc_ctx; | ||||
ifp = ctx->ifc_ifp; | ifp = ctx->ifc_ifp; | ||||
/* | |||||
* XXX sanity check that ntxd & nrxd are a power of 2 | |||||
*/ | |||||
iflib_reset_qvalues(ctx); | iflib_reset_qvalues(ctx); | ||||
CTX_LOCK(ctx); | CTX_LOCK(ctx); | ||||
if ((err = IFDI_ATTACH_PRE(ctx)) != 0) { | if ((err = IFDI_ATTACH_PRE(ctx)) != 0) { | ||||
device_printf(dev, "IFDI_ATTACH_PRE failed %d\n", err); | device_printf(dev, "IFDI_ATTACH_PRE failed %d\n", err); | ||||
goto fail_unlock; | goto fail_unlock; | ||||
} | } | ||||
if (sctx->isc_flags & IFLIB_GEN_MAC) | if (sctx->isc_flags & IFLIB_GEN_MAC) | ||||
iflib_gen_mac(ctx); | iflib_gen_mac(ctx); | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | if (scctx->isc_nrxqsets == 0 || (scctx->isc_nrxqsets_max && scctx->isc_nrxqsets_max < scctx->isc_nrxqsets)) | ||||
scctx->isc_nrxqsets = scctx->isc_nrxqsets_max; | scctx->isc_nrxqsets = scctx->isc_nrxqsets_max; | ||||
main_txq = (sctx->isc_flags & IFLIB_HAS_TXCQ) ? 1 : 0; | main_txq = (sctx->isc_flags & IFLIB_HAS_TXCQ) ? 1 : 0; | ||||
main_rxq = (sctx->isc_flags & IFLIB_HAS_RXCQ) ? 1 : 0; | main_rxq = (sctx->isc_flags & IFLIB_HAS_RXCQ) ? 1 : 0; | ||||
/* XXX change for per-queue sizes */ | /* XXX change for per-queue sizes */ | ||||
device_printf(dev, "Using %d tx descriptors and %d rx descriptors\n", | device_printf(dev, "Using %d tx descriptors and %d rx descriptors\n", | ||||
scctx->isc_ntxd[main_txq], scctx->isc_nrxd[main_rxq]); | scctx->isc_ntxd[main_txq], scctx->isc_nrxd[main_rxq]); | ||||
for (i = 0; i < sctx->isc_nrxqs; i++) { | |||||
if (!powerof2(scctx->isc_nrxd[i])) { | |||||
/* round down instead? */ | |||||
device_printf(dev, "# rx descriptors must be a power of 2\n"); | |||||
err = EINVAL; | |||||
goto fail_iflib_detach; | |||||
} | |||||
} | |||||
for (i = 0; i < sctx->isc_ntxqs; i++) { | |||||
if (!powerof2(scctx->isc_ntxd[i])) { | |||||
device_printf(dev, | |||||
"# tx descriptors must be a power of 2"); | |||||
err = EINVAL; | |||||
goto fail_iflib_detach; | |||||
} | |||||
} | |||||
if (scctx->isc_tx_nsegments > scctx->isc_ntxd[main_txq] / | if (scctx->isc_tx_nsegments > scctx->isc_ntxd[main_txq] / | ||||
MAX_SINGLE_PACKET_FRACTION) | MAX_SINGLE_PACKET_FRACTION) | ||||
scctx->isc_tx_nsegments = max(1, scctx->isc_ntxd[main_txq] / | scctx->isc_tx_nsegments = max(1, scctx->isc_ntxd[main_txq] / | ||||
MAX_SINGLE_PACKET_FRACTION); | MAX_SINGLE_PACKET_FRACTION); | ||||
if (scctx->isc_tx_tso_segments_max > scctx->isc_ntxd[main_txq] / | if (scctx->isc_tx_tso_segments_max > scctx->isc_ntxd[main_txq] / | ||||
MAX_SINGLE_PACKET_FRACTION) | MAX_SINGLE_PACKET_FRACTION) | ||||
scctx->isc_tx_tso_segments_max = max(1, | scctx->isc_tx_tso_segments_max = max(1, | ||||
▲ Show 20 Lines • Show All 1,821 Lines • Show Last 20 Lines |
As previously suggested, please just go with sctx->isc_nrxd_default[i] in case the user-supplied value isn't a power of 2 in order to avoid the complexity of dealing with case that the rounded down value happens to be smaller than sctx->isc_nrxd_min[i].