Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 31 Dec 2018 22:09:09 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r342656 - in stable: 11/sys/x86/include 11/sys/x86/x86 11/sys/x86/xen 12/sys/x86/include 12/sys/x86/x86 12/sys/x86/xen
Message-ID:  <201812312209.wBVM997N031756@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Mon Dec 31 22:09:08 2018
New Revision: 342656
URL: https://svnweb.freebsd.org/changeset/base/342656

Log:
  MFC 340460: Convert the number of MSI IRQs on x86 from a constant to a tunable.
  
  The number of MSI IRQs still defaults to 512, but it can now be
  changed at boot time via the machdep.num_msi_irqs tunable.
  
  Relnotes:	yes

Modified:
  stable/12/sys/x86/include/intr_machdep.h
  stable/12/sys/x86/x86/msi.c
  stable/12/sys/x86/xen/xen_intr.c
  stable/12/sys/x86/xen/xen_msi.c
Directory Properties:
  stable/12/   (props changed)

Changes in other areas also in this revision:
Modified:
  stable/11/sys/x86/include/intr_machdep.h
  stable/11/sys/x86/x86/msi.c
  stable/11/sys/x86/xen/xen_intr.c
  stable/11/sys/x86/xen/xen_msi.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/12/sys/x86/include/intr_machdep.h
==============================================================================
--- stable/12/sys/x86/include/intr_machdep.h	Mon Dec 31 21:55:12 2018	(r342655)
+++ stable/12/sys/x86/include/intr_machdep.h	Mon Dec 31 22:09:08 2018	(r342656)
@@ -58,11 +58,11 @@
  * the minimum IRQ value for MSI interrupts to attempt to leave 255
  * unused since 255 is used in PCI to indicate an invalid INTx IRQ.
  */
-#define	NUM_MSI_INTS	512
 #define	MINIMUM_MSI_INT	256
 
 extern u_int first_msi_irq;
 extern u_int num_io_irqs;
+extern u_int num_msi_irqs;
 
 /*
  * Default base address for MSI messages on x86 platforms.

Modified: stable/12/sys/x86/x86/msi.c
==============================================================================
--- stable/12/sys/x86/x86/msi.c	Mon Dec 31 21:55:12 2018	(r342655)
+++ stable/12/sys/x86/x86/msi.c	Mon Dec 31 22:09:08 2018	(r342656)
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
+#include <sys/limits.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mutex.h>
@@ -153,6 +154,10 @@ struct pic msi_pic = {
 
 u_int first_msi_irq;
 
+u_int num_msi_irqs = 512;
+SYSCTL_UINT(_machdep, OID_AUTO, num_msi_irqs, CTLFLAG_RDTUN, &num_msi_irqs, 0,
+    "Number of IRQs reserved for MSI and MSI-X interrupts");
+
 #ifdef SMP
 /**
  * Xen hypervisors prior to 4.6.0 do not properly handle updates to
@@ -331,8 +336,13 @@ msi_init(void)
 	}
 #endif
 
+	if (num_msi_irqs == 0)
+		return;
+
 	first_msi_irq = max(MINIMUM_MSI_INT, num_io_irqs);
-	num_io_irqs = first_msi_irq + NUM_MSI_INTS;
+	if (num_msi_irqs > UINT_MAX - first_msi_irq)
+		panic("num_msi_irq too high");
+	num_io_irqs = first_msi_irq + num_msi_irqs;
 
 	msi_enabled = 1;
 	intr_register_pic(&msi_pic);
@@ -346,7 +356,7 @@ msi_create_source(void)
 	u_int irq;
 
 	mtx_lock(&msi_lock);
-	if (msi_last_irq >= NUM_MSI_INTS) {
+	if (msi_last_irq >= num_msi_irqs) {
 		mtx_unlock(&msi_lock);
 		return;
 	}
@@ -390,7 +400,7 @@ again:
 
 	/* Try to find 'count' free IRQs. */
 	cnt = 0;
-	for (i = first_msi_irq; i < first_msi_irq + NUM_MSI_INTS; i++) {
+	for (i = first_msi_irq; i < first_msi_irq + num_msi_irqs; i++) {
 		msi = (struct msi_intsrc *)intr_lookup_source(i);
 
 		/* End of allocated sources, so break. */
@@ -409,7 +419,7 @@ again:
 	/* Do we need to create some new sources? */
 	if (cnt < count) {
 		/* If we would exceed the max, give up. */
-		if (i + (count - cnt) > first_msi_irq + NUM_MSI_INTS) {
+		if (i + (count - cnt) > first_msi_irq + num_msi_irqs) {
 			mtx_unlock(&msi_lock);
 			free(mirqs, M_MSI);
 			return (ENXIO);
@@ -585,7 +595,7 @@ msi_map(int irq, uint64_t *addr, uint32_t *data)
 #ifdef ACPI_DMAR
 	if (!msi->msi_msix) {
 		for (k = msi->msi_count - 1, i = first_msi_irq; k > 0 &&
-		    i < first_msi_irq + NUM_MSI_INTS; i++) {
+		    i < first_msi_irq + num_msi_irqs; i++) {
 			if (i == msi->msi_irq)
 				continue;
 			msi1 = (struct msi_intsrc *)intr_lookup_source(i);
@@ -635,7 +645,7 @@ again:
 	mtx_lock(&msi_lock);
 
 	/* Find a free IRQ. */
-	for (i = first_msi_irq; i < first_msi_irq + NUM_MSI_INTS; i++) {
+	for (i = first_msi_irq; i < first_msi_irq + num_msi_irqs; i++) {
 		msi = (struct msi_intsrc *)intr_lookup_source(i);
 
 		/* End of allocated sources, so break. */
@@ -648,7 +658,7 @@ again:
 	}
 
 	/* Are all IRQs in use? */
-	if (i == first_msi_irq + NUM_MSI_INTS) {
+	if (i == first_msi_irq + num_msi_irqs) {
 		mtx_unlock(&msi_lock);
 		return (ENXIO);
 	}

Modified: stable/12/sys/x86/xen/xen_intr.c
==============================================================================
--- stable/12/sys/x86/xen/xen_intr.c	Mon Dec 31 21:55:12 2018	(r342655)
+++ stable/12/sys/x86/xen/xen_intr.c	Mon Dec 31 22:09:08 2018	(r342656)
@@ -690,6 +690,8 @@ void
 xen_intr_alloc_irqs(void)
 {
 
+	if (num_io_irqs > UINT_MAX - NR_EVENT_CHANNELS)
+		panic("IRQ allocation overflow (num_msi_irqs too high?)");
 	first_evtchn_irq = num_io_irqs;
 	num_io_irqs += NR_EVENT_CHANNELS;
 }

Modified: stable/12/sys/x86/xen/xen_msi.c
==============================================================================
--- stable/12/sys/x86/xen/xen_msi.c	Mon Dec 31 21:55:12 2018	(r342655)
+++ stable/12/sys/x86/xen/xen_msi.c	Mon Dec 31 22:09:08 2018	(r342656)
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
+#include <sys/limits.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mutex.h>
@@ -57,7 +58,9 @@ xen_msi_init(void)
 
 	MPASS(num_io_irqs > 0);
 	first_msi_irq = min(MINIMUM_MSI_INT, num_io_irqs);
-	num_io_irqs = first_msi_irq + NUM_MSI_INTS;
+	if (num_msi_irqs > UINT_MAX - first_msi_irq)
+		panic("num_msi_irq too high");
+	num_io_irqs = first_msi_irq + num_msi_irqs;
 
 	mtx_init(&msi_lock, "msi", NULL, MTX_DEF);
 }
@@ -73,7 +76,7 @@ xen_msi_alloc(device_t dev, int count, int maxcount, i
 	mtx_lock(&msi_lock);
 
 	/* If we would exceed the max, give up. */
-	if ((msi_last_irq + count) > NUM_MSI_INTS) {
+	if (msi_last_irq + count > num_msi_irqs) {
 		mtx_unlock(&msi_lock);
 		return (ENXIO);
 	}



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