Author: erj
Date: Tue Aug 20 20:15:32 2019
New Revision: 351276
URL: https://svnweb.freebsd.org/changeset/base/351276

Log:
  MFC various iflib fixes from head
  
  Included revisions:
  r347418 - iflib: use default ntxd and rxd when user value is not power of 2
  r348372 - iflib: provide probe wrapper for vendor drivers
  r350306 - iflib: fix dangling device softc pointer
  r350507 - iflib: remove kobject class reference increment
  r350509 - iflib: Prevent kernel panic caused by loading driver with a 
specific interrupt configuration
  r351152 - iflib: add iflib_deregister to help cleanup on exit
  
  Sponsored by: Intel Corporation

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

Modified: stable/12/sys/net/iflib.c
==============================================================================
--- stable/12/sys/net/iflib.c   Tue Aug 20 20:04:16 2019        (r351275)
+++ stable/12/sys/net/iflib.c   Tue Aug 20 20:15:32 2019        (r351276)
@@ -707,6 +707,7 @@ static void iflib_altq_if_start(if_t ifp);
 static int iflib_altq_if_transmit(if_t ifp, struct mbuf *m);
 #endif
 static int iflib_register(if_ctx_t);
+static void iflib_deregister(if_ctx_t);
 static void iflib_init_locked(if_ctx_t ctx);
 static void iflib_add_device_sysctl_pre(if_ctx_t ctx);
 static void iflib_add_device_sysctl_post(if_ctx_t ctx);
@@ -4350,6 +4351,18 @@ iflib_device_probe(device_t dev)
        return (ENXIO);
 }
 
+int
+iflib_device_probe_vendor(device_t dev)
+{
+       int probe;
+
+       probe = iflib_device_probe(dev);
+       if (probe == BUS_PROBE_DEFAULT)
+               return (BUS_PROBE_VENDOR);
+       else
+               return (probe);
+}
+
 static void
 iflib_reset_qvalues(if_ctx_t ctx)
 {
@@ -4360,9 +4373,6 @@ iflib_reset_qvalues(if_ctx_t ctx)
 
        scctx->isc_txrx_budget_bytes_max = IFLIB_MAX_TX_BYTES;
        scctx->isc_tx_qdepth = IFLIB_DEFAULT_TX_QDEPTH;
-       /*
-        * XXX sanity check that ntxd & nrxd are a power of 2
-        */
        if (ctx->ifc_sysctl_ntxqs != 0)
                scctx->isc_ntxqsets = ctx->ifc_sysctl_ntxqs;
        if (ctx->ifc_sysctl_nrxqs != 0)
@@ -4393,6 +4403,11 @@ iflib_reset_qvalues(if_ctx_t ctx)
                                      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])) {
+                       device_printf(dev, "nrxd%d: %d is not a power of 2 - 
using default value of %d\n",
+                                     i, scctx->isc_nrxd[i], 
sctx->isc_nrxd_default[i]);
+                       scctx->isc_nrxd[i] = sctx->isc_nrxd_default[i];
+               }
        }
 
        for (i = 0; i < sctx->isc_ntxqs; i++) {
@@ -4406,6 +4421,11 @@ iflib_reset_qvalues(if_ctx_t ctx)
                                      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])) {
+                       device_printf(dev, "ntxd%d: %d is not a power of 2 - 
using default value of %d\n",
+                                     i, scctx->isc_ntxd[i], 
sctx->isc_ntxd_default[i]);
+                       scctx->isc_ntxd[i] = sctx->isc_ntxd_default[i];
+               }
        }
 }
 
@@ -4482,7 +4502,7 @@ iflib_device_register(device_t dev, void *sc, if_share
        if_softc_ctx_t scctx;
        kobjop_desc_t kobj_desc;
        kobj_method_t *kobj_method;
-       int err, i, msix, rid;
+       int err, msix, rid;
        uint16_t main_rxq, main_txq;
 
        ctx = malloc(sizeof(* ctx), M_IFLIB, M_WAITOK|M_ZERO);
@@ -4534,23 +4554,6 @@ iflib_device_register(device_t dev, void *sc, if_share
        /* 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]);
-       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] /
            MAX_SINGLE_PACKET_FRACTION)
@@ -4676,7 +4679,7 @@ iflib_device_register(device_t dev, void *sc, if_share
                            err);
                        goto fail_queues;
                }
-       } else {
+       } else if (scctx->isc_intr != IFLIB_INTR_MSIX) {
                rid = 0;
                if (scctx->isc_intr == IFLIB_INTR_MSI) {
                        MPASS(msix == 1);
@@ -4686,6 +4689,11 @@ iflib_device_register(device_t dev, void *sc, if_share
                        device_printf(dev, "iflib_legacy_setup failed %d\n", 
err);
                        goto fail_queues;
                }
+       } else {
+               device_printf(dev,
+                   "Cannot use iflib with only 1 MSI-X interrupt!\n");
+               err = ENODEV;
+               goto fail_intr_free;
        }
 
        ether_ifattach(ctx->ifc_ifp, ctx->ifc_mac);
@@ -4725,11 +4733,13 @@ fail_intr_free:
 fail_queues:
        iflib_tx_structures_free(ctx);
        iflib_rx_structures_free(ctx);
-fail_iflib_detach:
+       taskqgroup_detach(qgroup_if_config_tqg, &ctx->ifc_admin_task);
        IFDI_DETACH(ctx);
 fail_unlock:
        CTX_UNLOCK(ctx);
+       iflib_deregister(ctx);
 fail_ctx_free:
+       device_set_softc(ctx->ifc_dev, NULL);
         if (ctx->ifc_flags & IFC_SC_ALLOCATED)
                 free(ctx->ifc_softc, M_IFLIB);
         free(ctx, M_IFLIB);
@@ -4768,9 +4778,6 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sc
        scctx = &ctx->ifc_softc_ctx;
        ifp = ctx->ifc_ifp;
 
-       /*
-        * XXX sanity check that ntxd & nrxd are a power of 2
-        */
        iflib_reset_qvalues(ctx);
        CTX_LOCK(ctx);
        if ((err = IFDI_ATTACH_PRE(ctx)) != 0) {
@@ -4834,23 +4841,6 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sc
        /* 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]);
-       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] /
            MAX_SINGLE_PACKET_FRACTION)
@@ -4941,6 +4931,7 @@ fail_iflib_detach:
        IFDI_DETACH(ctx);
 fail_unlock:
        CTX_UNLOCK(ctx);
+       iflib_deregister(ctx);
 fail_ctx_free:
        free(ctx->ifc_softc, M_IFLIB);
        free(ctx, M_IFLIB);
@@ -4957,15 +4948,7 @@ iflib_pseudo_deregister(if_ctx_t ctx)
        struct taskqgroup *tqg;
        iflib_fl_t fl;
 
-       /* Unregister VLAN events */
-       if (ctx->ifc_vlan_attach_event != NULL)
-               EVENTHANDLER_DEREGISTER(vlan_config, 
ctx->ifc_vlan_attach_event);
-       if (ctx->ifc_vlan_detach_event != NULL)
-               EVENTHANDLER_DEREGISTER(vlan_unconfig, 
ctx->ifc_vlan_detach_event);
-
        ether_ifdetach(ifp);
-       /* ether_ifdetach calls if_qflush - lock must be destroy afterwards*/
-       CTX_LOCK_DESTROY(ctx);
        /* XXX drain any dependent tasks */
        tqg = qgroup_if_io_tqg;
        for (txq = ctx->ifc_txqs, i = 0; i < NTXQSETS(ctx); i++, txq++) {
@@ -4986,10 +4969,11 @@ iflib_pseudo_deregister(if_ctx_t ctx)
        if (ctx->ifc_vflr_task.gt_uniq != NULL)
                taskqgroup_detach(tqg, &ctx->ifc_vflr_task);
 
-       if_free(ifp);
-
        iflib_tx_structures_free(ctx);
        iflib_rx_structures_free(ctx);
+
+       iflib_deregister(ctx);
+
        if (ctx->ifc_flags & IFC_SC_ALLOCATED)
                free(ctx->ifc_softc, M_IFLIB);
        free(ctx, M_IFLIB);
@@ -5075,19 +5059,19 @@ iflib_device_deregister(if_ctx_t ctx)
        CTX_UNLOCK(ctx);
 
        /* ether_ifdetach calls if_qflush - lock must be destroy afterwards*/
-       CTX_LOCK_DESTROY(ctx);
-       device_set_softc(ctx->ifc_dev, NULL);
        iflib_free_intr_mem(ctx);
 
        bus_generic_detach(dev);
-       if_free(ifp);
 
        iflib_tx_structures_free(ctx);
        iflib_rx_structures_free(ctx);
+
+       iflib_deregister(ctx);
+
+       device_set_softc(ctx->ifc_dev, NULL);
        if (ctx->ifc_flags & IFC_SC_ALLOCATED)
                free(ctx->ifc_softc, M_IFLIB);
        unref_ctx_core_offset(ctx);
-       STATE_LOCK_DESTROY(ctx);
        free(ctx, M_IFLIB);
        return (0);
 }
@@ -5239,6 +5223,8 @@ iflib_module_event_handler(module_t mod, int what, voi
 static void
 _iflib_assert(if_shared_ctx_t sctx)
 {
+       int i;
+
        MPASS(sctx->isc_tx_maxsize);
        MPASS(sctx->isc_tx_maxsegsize);
 
@@ -5246,12 +5232,25 @@ _iflib_assert(if_shared_ctx_t sctx)
        MPASS(sctx->isc_rx_nsegments);
        MPASS(sctx->isc_rx_maxsegsize);
 
-       MPASS(sctx->isc_nrxd_min[0]);
-       MPASS(sctx->isc_nrxd_max[0]);
-       MPASS(sctx->isc_nrxd_default[0]);
-       MPASS(sctx->isc_ntxd_min[0]);
-       MPASS(sctx->isc_ntxd_max[0]);
-       MPASS(sctx->isc_ntxd_default[0]);
+       MPASS(sctx->isc_nrxqs >= 1 && sctx->isc_nrxqs <= 8);
+       for (i = 0; i < sctx->isc_nrxqs; i++) {
+               MPASS(sctx->isc_nrxd_min[i]);
+               MPASS(powerof2(sctx->isc_nrxd_min[i]));
+               MPASS(sctx->isc_nrxd_max[i]);
+               MPASS(powerof2(sctx->isc_nrxd_max[i]));
+               MPASS(sctx->isc_nrxd_default[i]);
+               MPASS(powerof2(sctx->isc_nrxd_default[i]));
+       }
+
+       MPASS(sctx->isc_ntxqs >= 1 && sctx->isc_ntxqs <= 8);
+       for (i = 0; i < sctx->isc_ntxqs; i++) {
+               MPASS(sctx->isc_ntxd_min[i]);
+               MPASS(powerof2(sctx->isc_ntxd_min[i]));
+               MPASS(sctx->isc_ntxd_max[i]);
+               MPASS(powerof2(sctx->isc_ntxd_max[i]));
+               MPASS(sctx->isc_ntxd_default[i]);
+               MPASS(powerof2(sctx->isc_ntxd_default[i]));
+       }
 }
 
 static void
@@ -5290,7 +5289,6 @@ iflib_register(if_ctx_t ctx)
         */
        kobj_init((kobj_t) ctx, (kobj_class_t) driver);
        kobj_class_compile((kobj_class_t) driver);
-       driver->refs++;
 
        if_initname(ifp, device_get_name(dev), device_get_unit(dev));
        if_setsoftc(ifp, ctx);
@@ -5318,6 +5316,36 @@ iflib_register(if_ctx_t ctx)
                                         iflib_media_change, 
iflib_media_status);
 
        return (0);
+}
+
+static void
+iflib_deregister(if_ctx_t ctx)
+{
+       if_t ifp = ctx->ifc_ifp;
+
+       /* Remove all media */
+       ifmedia_removeall(&ctx->ifc_media);
+
+       /* Unregister VLAN events */
+       if (ctx->ifc_vlan_attach_event != NULL) {
+               EVENTHANDLER_DEREGISTER(vlan_config, 
ctx->ifc_vlan_attach_event);
+               ctx->ifc_vlan_attach_event = NULL;
+       }
+       if (ctx->ifc_vlan_detach_event != NULL) {
+               EVENTHANDLER_DEREGISTER(vlan_unconfig, 
ctx->ifc_vlan_detach_event);
+               ctx->ifc_vlan_detach_event = NULL;
+       }
+
+       /* Release kobject reference */
+       kobj_delete((kobj_t) ctx, NULL);
+
+       /* Free the ifnet structure */
+       if_free(ifp);
+
+       STATE_LOCK_DESTROY(ctx);
+
+       /* ether_ifdetach calls if_qflush - lock must be destroy afterwards*/
+       CTX_LOCK_DESTROY(ctx);
 }
 
 static int

Modified: stable/12/sys/net/iflib.h
==============================================================================
--- stable/12/sys/net/iflib.h   Tue Aug 20 20:04:16 2019        (r351275)
+++ stable/12/sys/net/iflib.h   Tue Aug 20 20:15:32 2019        (r351276)
@@ -393,6 +393,13 @@ int iflib_device_suspend(device_t);
 int iflib_device_resume(device_t);
 int iflib_device_shutdown(device_t);
 
+/*
+ * Use this instead of iflib_device_probe if the driver should report
+ * BUS_PROBE_VENDOR instead of BUS_PROBE_DEFAULT. (For example, an out-of-tree
+ * driver based on iflib).
+ */
+int iflib_device_probe_vendor(device_t);
+
 
 int iflib_device_iov_init(device_t, uint16_t, const nvlist_t *);
 void iflib_device_iov_uninit(device_t);
_______________________________________________
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