changeset 4974:c7454a80ea3d

PSARC/2007/453 MSI-X interrupt limit override 6592959 MSI-X interrupt limit override
author egillett
date Fri, 31 Aug 2007 14:35:42 -0700
parents e9e56fdeb64d
children 8544fd5abe8b
files usr/src/uts/common/os/ddi_intr.c usr/src/uts/common/os/ddi_intr_impl.c usr/src/uts/common/sys/ddi_intr_impl.h
diffstat 3 files changed, 58 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/os/ddi_intr.c	Fri Aug 31 14:10:02 2007 -0700
+++ b/usr/src/uts/common/os/ddi_intr.c	Fri Aug 31 14:35:42 2007 -0700
@@ -44,10 +44,12 @@
  */
 
 /*
- * MSI/X allocation limit.
- * This limit will change with Resource Management support.
+ * MSI-X allocation limit.
+ *
+ * This MSI-X limit or tunable may be obsolete or change with Interrupt
+ * Resource Management (IRM) support.
  */
-uint_t		ddi_msix_alloc_limit = DDI_INTR_DEFAULT_ALLOC;
+uint_t		ddi_msix_alloc_limit = DDI_DEFAULT_MSIX_ALLOC;
 
 /*
  * ddi_intr_get_supported_types:
@@ -264,20 +266,33 @@
 	}
 
 	/*
-	 * Limit max MSI/X allocation to ddi_msix_alloc_limit.
-	 * This limit will change with Resource Management support.
+	 * NOTE:
+	 *
+	 * An intermediate solution is added here to allocate more MSI-X
+	 * interrupts to drivers to address some significant performance
+	 * issues discovered on various SPARC platforms. More MSI-X interrupts
+	 * will be allocated based on existence of "#msix-request" property.
+	 * The DDI framework will not honor this property after the Interrupt
+	 * Resource Management (IRM) project's integration.
+	 *
+	 * Hard limit for maximum MSI allocation is set to DDI_MAX_MSI_ALLOC,
+	 * however MSI-X's max allocation is controlled by
+	 * ddi_msix_alloc_limit().
 	 */
 	if (DDI_INTR_IS_MSI_OR_MSIX(type)) {
-		if (curr_nintrs == ddi_msix_alloc_limit) {
+		uint_t	alloc_limit = (type == DDI_INTR_TYPE_MSIX) ?
+		    i_ddi_get_msix_alloc_limit(dip) : DDI_MAX_MSI_ALLOC;
+
+		if (curr_nintrs == alloc_limit) {
 			DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: "
 			    "max # of intrs %d already allocated\n",
 			    curr_nintrs));
 			return (DDI_EINVAL);
 		}
-		if ((count + curr_nintrs) > ddi_msix_alloc_limit) {
+		if ((count + curr_nintrs) > alloc_limit) {
 			DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: Requested "
 			    "MSI/Xs %d Max MSI/Xs limit %d\n", count,
-			    ddi_msix_alloc_limit));
+			    alloc_limit));
 
 			if (behavior == DDI_INTR_ALLOC_STRICT) {
 				DDI_INTR_APIDBG((CE_CONT, "ddi_intr_alloc: "
@@ -286,7 +301,7 @@
 				return (DDI_EAGAIN);
 			}
 
-			count = ddi_msix_alloc_limit - curr_nintrs;
+			count = alloc_limit - curr_nintrs;
 		}
 	}
 
--- a/usr/src/uts/common/os/ddi_intr_impl.c	Fri Aug 31 14:10:02 2007 -0700
+++ b/usr/src/uts/common/os/ddi_intr_impl.c	Fri Aug 31 14:35:42 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -38,6 +38,8 @@
 #include <sys/sunndi.h>
 #include <sys/ndi_impldefs.h>	/* include prototypes */
 
+extern uint_t		ddi_msix_alloc_limit;
+
 /*
  * New DDI interrupt framework
  */
@@ -403,3 +405,20 @@
 		intr_p->devi_cap_ptr = cap_ptr;
 }
 #endif
+
+/* ARGSUSED */
+uint_t
+i_ddi_get_msix_alloc_limit(dev_info_t *dip)
+{
+	uint_t	msix_alloc_limit = ddi_msix_alloc_limit;
+
+#if defined(__sparc)
+	if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_NOTPROM |
+	    DDI_PROP_DONTPASS, "#msix-request")) {
+		msix_alloc_limit = MAX(DDI_MAX_MSIX_ALLOC,
+		    ddi_msix_alloc_limit);
+	}
+#endif
+
+	return (msix_alloc_limit);
+}
--- a/usr/src/uts/common/sys/ddi_intr_impl.h	Fri Aug 31 14:10:02 2007 -0700
+++ b/usr/src/uts/common/sys/ddi_intr_impl.h	Fri Aug 31 14:35:42 2007 -0700
@@ -132,8 +132,18 @@
 /* values for ih_flags */
 #define	DDI_INTR_MSIX_DUP	0x01	/* MSI-X vector which has been dupped */
 
-/* Default number of MSI/X resources to allocate */
-#define	DDI_INTR_DEFAULT_ALLOC		2
+/* Maximum number of MSI resources to allocate */
+#define	DDI_MAX_MSI_ALLOC	2
+
+/*
+ * The following MSI-X limits will change with Interrupt Resource Management
+ * (IRM) support.
+ */
+/* Default number of MSI-X resources to allocate */
+#define	DDI_DEFAULT_MSIX_ALLOC	2
+
+/* Maximum number of MSI-X resources to allocate */
+#define	DDI_MAX_MSIX_ALLOC	8
 
 struct av_softinfo;
 
@@ -250,6 +260,8 @@
 void	i_ddi_set_msi_msix_cap_ptr(dev_info_t *dip, int cap_ptr);
 #endif
 
+uint_t	i_ddi_get_msix_alloc_limit(dev_info_t *dip);
+
 int32_t i_ddi_get_intr_weight(dev_info_t *);
 int32_t i_ddi_set_intr_weight(dev_info_t *, int32_t);