svn commit: r351276 - stable/12/sys/net

Eric Joyner erj at FreeBSD.org
Tue Aug 20 20:15:34 UTC 2019


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);


More information about the svn-src-all mailing list