Author: vmaffione
Date: Mon Aug 10 17:53:09 2020
New Revision: 364085
URL: https://svnweb.freebsd.org/changeset/base/364085

Log:
  MFC r363378
  
  iflib: initialize netmap with the correct number of descriptors
  
  In case the network device has a RX or TX control queue, the correct
  number of TX/RX descriptors is contained in the second entry of the
  isc_ntxd (or isc_nrxd) array, rather than in the first entry.
  This case is correctly handled by iflib_device_register() and
  iflib_pseudo_register(), but not by iflib_netmap_attach().
  If the first entry is larger than the second, this can result in a
  panic. This change fixes the bug by introducing two helper functions
  that also lead to some code simplification.
  
  PR:     247647
  Differential Revision:  https://reviews.freebsd.org/D25541

Modified:
  stable/12/sys/net/iflib.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/net/iflib.c
==============================================================================
--- stable/12/sys/net/iflib.c   Mon Aug 10 17:35:58 2020        (r364084)
+++ stable/12/sys/net/iflib.c   Mon Aug 10 17:53:09 2020        (r364085)
@@ -735,6 +735,26 @@ MTX_SYSINIT(iflib_cpu_offset, &cpu_offset_mtx, "iflib_
 
 NETDUMP_DEFINE(iflib);
 
+static int
+iflib_num_rx_descs(if_ctx_t ctx)
+{
+       if_softc_ctx_t scctx = &ctx->ifc_softc_ctx;
+       if_shared_ctx_t sctx = ctx->ifc_sctx;
+       uint16_t first_rxq = (sctx->isc_flags & IFLIB_HAS_RXCQ) ? 1 : 0;
+
+       return scctx->isc_nrxd[first_rxq];
+}
+
+static int
+iflib_num_tx_descs(if_ctx_t ctx)
+{
+       if_softc_ctx_t scctx = &ctx->ifc_softc_ctx;
+       if_shared_ctx_t sctx = ctx->ifc_sctx;
+       uint16_t first_txq = (sctx->isc_flags & IFLIB_HAS_TXCQ) ? 1 : 0;
+
+       return scctx->isc_ntxd[first_txq];
+}
+
 #ifdef DEV_NETMAP
 #include <sys/selinfo.h>
 #include <net/netmap.h>
@@ -1170,7 +1190,6 @@ static int
 iflib_netmap_attach(if_ctx_t ctx)
 {
        struct netmap_adapter na;
-       if_softc_ctx_t scctx = &ctx->ifc_softc_ctx;
 
        bzero(&na, sizeof(na));
 
@@ -1179,8 +1198,8 @@ iflib_netmap_attach(if_ctx_t ctx)
        MPASS(ctx->ifc_softc_ctx.isc_ntxqsets);
        MPASS(ctx->ifc_softc_ctx.isc_nrxqsets);
 
-       na.num_tx_desc = scctx->isc_ntxd[0];
-       na.num_rx_desc = scctx->isc_nrxd[0];
+       na.num_tx_desc = iflib_num_tx_descs(ctx);
+       na.num_rx_desc = iflib_num_rx_descs(ctx);
        na.nm_txsync = iflib_netmap_txsync;
        na.nm_rxsync = iflib_netmap_rxsync;
        na.nm_register = iflib_netmap_register;
@@ -4570,7 +4589,7 @@ iflib_device_register(device_t dev, void *sc, if_share
        kobjop_desc_t kobj_desc;
        kobj_method_t *kobj_method;
        int err, msix, rid;
-       uint16_t main_rxq, main_txq;
+       int num_txd, num_rxd;
 
        ctx = malloc(sizeof(* ctx), M_IFLIB, M_WAITOK|M_ZERO);
 
@@ -4615,21 +4634,20 @@ iflib_device_register(device_t dev, void *sc, if_share
        if (scctx->isc_nrxqsets == 0 || (scctx->isc_nrxqsets_max && 
scctx->isc_nrxqsets_max < scctx->isc_nrxqsets))
                scctx->isc_nrxqsets = scctx->isc_nrxqsets_max;
 
-       main_txq = (sctx->isc_flags & IFLIB_HAS_TXCQ) ? 1 : 0;
-       main_rxq = (sctx->isc_flags & IFLIB_HAS_RXCQ) ? 1 : 0;
+       num_txd = iflib_num_tx_descs(ctx);
+       num_rxd = iflib_num_rx_descs(ctx);
 
        /* XXX change for per-queue sizes */
        device_printf(dev, "Using %d TX descriptors and %d RX descriptors\n",
-           scctx->isc_ntxd[main_txq], scctx->isc_nrxd[main_rxq]);
+           num_txd, num_rxd);
 
-       if (scctx->isc_tx_nsegments > scctx->isc_ntxd[main_txq] /
-           MAX_SINGLE_PACKET_FRACTION)
-               scctx->isc_tx_nsegments = max(1, scctx->isc_ntxd[main_txq] /
+       if (scctx->isc_tx_nsegments > num_txd / MAX_SINGLE_PACKET_FRACTION)
+               scctx->isc_tx_nsegments = max(1, num_txd /
                    MAX_SINGLE_PACKET_FRACTION);
-       if (scctx->isc_tx_tso_segments_max > scctx->isc_ntxd[main_txq] /
+       if (scctx->isc_tx_tso_segments_max > num_txd /
            MAX_SINGLE_PACKET_FRACTION)
                scctx->isc_tx_tso_segments_max = max(1,
-                   scctx->isc_ntxd[main_txq] / MAX_SINGLE_PACKET_FRACTION);
+                   num_txd / MAX_SINGLE_PACKET_FRACTION);
 
        /* TSO parameters - dig these out of the data sheet - simply correspond 
to tag setup */
        if (if_getcapabilities(ifp) & IFCAP_TSO) {
@@ -4817,14 +4835,13 @@ int
 iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
                                          struct iflib_cloneattach_ctx *clctx)
 {
+       int num_txd, num_rxd;
        int err;
        if_ctx_t ctx;
        if_t ifp;
        if_softc_ctx_t scctx;
        int i;
        void *sc;
-       uint16_t main_txq;
-       uint16_t main_rxq;
 
        ctx = malloc(sizeof(*ctx), M_IFLIB, M_WAITOK|M_ZERO);
        sc = malloc(sctx->isc_driver->size, M_IFLIB, M_WAITOK|M_ZERO);
@@ -4912,21 +4929,20 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sc
        if (scctx->isc_nrxqsets == 0 || (scctx->isc_nrxqsets_max && 
scctx->isc_nrxqsets_max < scctx->isc_nrxqsets))
                scctx->isc_nrxqsets = scctx->isc_nrxqsets_max;
 
-       main_txq = (sctx->isc_flags & IFLIB_HAS_TXCQ) ? 1 : 0;
-       main_rxq = (sctx->isc_flags & IFLIB_HAS_RXCQ) ? 1 : 0;
+       num_txd = iflib_num_tx_descs(ctx);
+       num_rxd = iflib_num_rx_descs(ctx);
 
        /* XXX change for per-queue sizes */
        device_printf(dev, "Using %d TX descriptors and %d RX descriptors\n",
-           scctx->isc_ntxd[main_txq], scctx->isc_nrxd[main_rxq]);
+           num_txd, num_rxd);
 
-       if (scctx->isc_tx_nsegments > scctx->isc_ntxd[main_txq] /
-           MAX_SINGLE_PACKET_FRACTION)
-               scctx->isc_tx_nsegments = max(1, scctx->isc_ntxd[main_txq] /
+       if (scctx->isc_tx_nsegments > num_txd / MAX_SINGLE_PACKET_FRACTION)
+               scctx->isc_tx_nsegments = max(1, num_txd /
                    MAX_SINGLE_PACKET_FRACTION);
-       if (scctx->isc_tx_tso_segments_max > scctx->isc_ntxd[main_txq] /
+       if (scctx->isc_tx_tso_segments_max > num_txd /
            MAX_SINGLE_PACKET_FRACTION)
                scctx->isc_tx_tso_segments_max = max(1,
-                   scctx->isc_ntxd[main_txq] / MAX_SINGLE_PACKET_FRACTION);
+                   num_txd / MAX_SINGLE_PACKET_FRACTION);
 
        /* TSO parameters - dig these out of the data sheet - simply correspond 
to tag setup */
        if (if_getcapabilities(ifp) & IFCAP_TSO) {
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to