Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Aug 2019 17:37:25 +0000 (UTC)
From:      Eric Joyner <erj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r350509 - head/sys/net
Message-ID:  <201908011737.x71HbPOe052496@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: erj
Date: Thu Aug  1 17:37:25 2019
New Revision: 350509
URL: https://svnweb.freebsd.org/changeset/base/350509

Log:
  iflib: Prevent kernel panic caused by loading driver with a specific interrupt configuration
  
  If a device has only 1 MSI-X interrupt available and does not support either
  MSI or legacy interrupts, iflib_device_register() will fail, leak memory and
  MSI resources, and the driver will not load. Worse, if another iflib-using
  driver tries to unload afterwards, a kernel panic will occur because the
  previous failed iflib driver loead did not properly call "taskqgroup_detach()"
  during it's cleanup.
  
  This patch is band-aid for this situation -- don't try allocating MSI or legacy
  interrupts if a single MSI-X interrupt was allocated, but fail to load instead.
  As well, during the cleanup, properly call taskqgroup_detach() on the admin
  task to prevent panics when other iflib drivers unload.
  
  This whole interrupt allocation process actually needs re-doing to properly
  support devices with only a single MSI-X interrupt, devices that only support
  MSI-X, non-PCI devices, and multiple non-MSIX interrupts, as well.
  
  Signed-off-by: Eric Joyner <erj@freebsd.org>
  
  Reviewed by:	marius@
  MFC after:	1 week
  Sponsored by:	Intel Corporation
  Differential Revision:	https://reviews.freebsd.org/D20747

Modified:
  head/sys/net/iflib.c

Modified: head/sys/net/iflib.c
==============================================================================
--- head/sys/net/iflib.c	Thu Aug  1 17:36:15 2019	(r350508)
+++ head/sys/net/iflib.c	Thu Aug  1 17:37:25 2019	(r350509)
@@ -4731,7 +4731,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);
@@ -4741,6 +4741,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.octet);
@@ -4781,6 +4786,7 @@ fail_intr_free:
 fail_queues:
 	iflib_tx_structures_free(ctx);
 	iflib_rx_structures_free(ctx);
+	taskqgroup_detach(qgroup_if_config_tqg, &ctx->ifc_admin_task);
 	IFDI_DETACH(ctx);
 fail_unlock:
 	CTX_UNLOCK(ctx);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201908011737.x71HbPOe052496>