diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/os/ddi_intr.c | 33 | ||||
-rw-r--r-- | usr/src/uts/common/os/ddi_intr_impl.c | 21 | ||||
-rw-r--r-- | usr/src/uts/common/sys/ddi_intr_impl.h | 16 |
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); |