summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/os/ddi_intr.c33
-rw-r--r--usr/src/uts/common/os/ddi_intr_impl.c21
-rw-r--r--usr/src/uts/common/sys/ddi_intr_impl.h16
3 files changed, 58 insertions, 12 deletions
diff --git a/usr/src/uts/common/os/ddi_intr.c b/usr/src/uts/common/os/ddi_intr.c
index 26863015bd..6741e6ae15 100644
--- a/usr/src/uts/common/os/ddi_intr.c
+++ b/usr/src/uts/common/os/ddi_intr.c
@@ -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 @@ ddi_intr_alloc(dev_info_t *dip, ddi_intr_handle_t *h_array, int type, int inum,
}
/*
- * 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 @@ ddi_intr_alloc(dev_info_t *dip, ddi_intr_handle_t *h_array, int type, int inum,
return (DDI_EAGAIN);
}
- count = ddi_msix_alloc_limit - curr_nintrs;
+ count = alloc_limit - curr_nintrs;
}
}
diff --git a/usr/src/uts/common/os/ddi_intr_impl.c b/usr/src/uts/common/os/ddi_intr_impl.c
index 74c403d0ec..b1678cb144 100644
--- a/usr/src/uts/common/os/ddi_intr_impl.c
+++ b/usr/src/uts/common/os/ddi_intr_impl.c
@@ -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 @@ i_ddi_set_msi_msix_cap_ptr(dev_info_t *dip, int cap_ptr)
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);
+}
diff --git a/usr/src/uts/common/sys/ddi_intr_impl.h b/usr/src/uts/common/sys/ddi_intr_impl.h
index 84a477998b..b56a6a4c1f 100644
--- a/usr/src/uts/common/sys/ddi_intr_impl.h
+++ b/usr/src/uts/common/sys/ddi_intr_impl.h
@@ -132,8 +132,18 @@ typedef struct ddi_intr_handle_impl {
/* 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 @@ int i_ddi_get_msi_msix_cap_ptr(dev_info_t *dip);
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);