Re: [PATCH 0/2] PCI/MSI: Remove arch_msi_check_device()
On Fri, Sep 05, 2014 at 03:27:49PM -0600, Bjorn Helgaas wrote: > > I applied these (with Michael's ack on the first, and v2 of the second) to > > pci/msi for v3.18, thanks! Hi Bjorn, I resent a series with updates that fix kbuild robot errors. Hopefully, the rebase for pci/msi would not cause trouble for anyone. > Oh, I forgot -- if you'd rather take the first one through the PPC > tree, you can do that and I can merge the second one later. Let me > know if you want to do that. Nah, your treee is just fine. Thanks! > Bjorn -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 3/3] PCI/MSI: Remove arch_msi_check_device()
There are no archs that override arch_msi_check_device() hook. Remove it as it is completely redundant. If an arch would need to check MSI/MSI-X possibility for a device it should make it within arch_setup_msi_irqs() hook. Cc: Michael Ellerman Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-...@vger.kernel.org Signed-off-by: Alexander Gordeev --- drivers/pci/msi.c | 49 + include/linux/msi.h | 3 --- 2 files changed, 13 insertions(+), 39 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 5a40516..6c2cc41 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -56,16 +56,6 @@ void __weak arch_teardown_msi_irq(unsigned int irq) chip->teardown_irq(chip, irq); } -int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type) -{ - struct msi_chip *chip = dev->bus->msi; - - if (!chip || !chip->check_device) - return 0; - - return chip->check_device(chip, dev, nvec, type); -} - int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { struct msi_desc *entry; @@ -806,22 +796,23 @@ out_free: } /** - * pci_msi_check_device - check whether MSI may be enabled on a device + * pci_msi_supported - check whether MSI may be enabled on a device * @dev: pointer to the pci_dev data structure of MSI device function * @nvec: how many MSIs have been requested ? - * @type: are we checking for MSI or MSI-X ? * * Look at global flags, the device itself, and its parent buses * to determine if MSI/-X are supported for the device. If MSI/-X is * supported return 0, else return an error code. **/ -static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) +static int pci_msi_supported(struct pci_dev *dev, int nvec) { struct pci_bus *bus; - int ret; /* MSI must be globally enabled and supported by the device */ - if (!pci_msi_enable || !dev || dev->no_msi) + if (!pci_msi_enable) + return -EINVAL; + + if (!dev || dev->no_msi || dev->current_state != PCI_D0) return -EINVAL; /* @@ -843,10 +834,6 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) return -EINVAL; - ret = arch_msi_check_device(dev, nvec, type); - if (ret) - return ret; - return 0; } @@ -949,13 +936,13 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) int status, nr_entries; int i, j; - if (!entries || !dev->msix_cap || dev->current_state != PCI_D0) - return -EINVAL; - - status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX); + status = pci_msi_supported(dev, nvec); if (status) return status; + if (!entries) + return -EINVAL; + nr_entries = pci_msix_vec_count(dev); if (nr_entries < 0) return nr_entries; @@ -1062,8 +1049,9 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) int nvec; int rc; - if (dev->current_state != PCI_D0) - return -EINVAL; + rc = pci_msi_supported(dev, minvec); + if (rc) + return rc; WARN_ON(!!dev->msi_enabled); @@ -1086,17 +1074,6 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) nvec = maxvec; do { - rc = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSI); - if (rc < 0) { - return rc; - } else if (rc > 0) { - if (rc < minvec) - return -ENOSPC; - nvec = rc; - } - } while (rc); - - do { rc = msi_capability_init(dev, nvec); if (rc < 0) { return rc; diff --git a/include/linux/msi.h b/include/linux/msi.h index 8103f32..dbf7cc9 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -60,7 +60,6 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); void arch_teardown_msi_irq(unsigned int irq); int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); void arch_teardown_msi_irqs(struct pci_dev *dev); -int arch_msi_check_device(struct pci_dev* dev, int nvec, int type); void arch_restore_msi_irqs(struct pci_dev *dev); void default_teardown_msi_irqs(struct pci_dev *dev); @@ -77,8 +76,6 @@ struct msi_chip { int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev, struct msi_desc *desc); void (*teardown_irq)(struct msi_chip *chip, unsigned int irq); - int (*check_device)(struct msi_chip *chip, struct pci_dev *dev, - int
[PATCH v2 1/3] PCI/MSI/PPC: Remove arch_msi_check_device()
Moving MSI checks from arch_msi_check_device() function to arch_setup_msi_irqs() function makes code more compact and allows removing unnecessary hook arch_msi_check_device() from generic MSI code. Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-...@vger.kernel.org Cc: Michael Ellerman Signed-off-by: Alexander Gordeev --- arch/powerpc/include/asm/machdep.h | 2 -- arch/powerpc/kernel/msi.c | 12 +- arch/powerpc/platforms/cell/axon_msi.c | 9 arch/powerpc/platforms/powernv/pci.c | 19 --- arch/powerpc/platforms/pseries/msi.c | 42 +- arch/powerpc/sysdev/fsl_msi.c | 12 +++--- arch/powerpc/sysdev/mpic_pasemi_msi.c | 11 ++--- arch/powerpc/sysdev/mpic_u3msi.c | 28 +-- arch/powerpc/sysdev/ppc4xx_hsta_msi.c | 18 +-- arch/powerpc/sysdev/ppc4xx_msi.c | 19 +-- 10 files changed, 50 insertions(+), 122 deletions(-) diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index b125cea..3af7216 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -136,8 +136,6 @@ struct machdep_calls { int (*pci_setup_phb)(struct pci_controller *host); #ifdef CONFIG_PCI_MSI - int (*msi_check_device)(struct pci_dev* dev, - int nvec, int type); int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type); void(*teardown_msi_irqs)(struct pci_dev *dev); diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c index 8bbc12d..71bd161 100644 --- a/arch/powerpc/kernel/msi.c +++ b/arch/powerpc/kernel/msi.c @@ -13,7 +13,7 @@ #include -int arch_msi_check_device(struct pci_dev* dev, int nvec, int type) +int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) { pr_debug("msi: Platform doesn't provide MSI callbacks.\n"); @@ -24,16 +24,6 @@ int arch_msi_check_device(struct pci_dev* dev, int nvec, int type) if (type == PCI_CAP_ID_MSI && nvec > 1) return 1; - if (ppc_md.msi_check_device) { - pr_debug("msi: Using platform check routine.\n"); - return ppc_md.msi_check_device(dev, nvec, type); - } - -return 0; -} - -int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) -{ return ppc_md.setup_msi_irqs(dev, nvec, type); } diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 85825b5..862b327 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -199,14 +199,6 @@ out_error: return msic; } -static int axon_msi_check_device(struct pci_dev *dev, int nvec, int type) -{ - if (!find_msi_translator(dev)) - return -ENODEV; - - return 0; -} - static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg) { struct device_node *dn; @@ -416,7 +408,6 @@ static int axon_msi_probe(struct platform_device *device) ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs; ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs; - ppc_md.msi_check_device = axon_msi_check_device; axon_msi_debug_setup(dn, msic); diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index b854b57..b45c492 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -46,29 +46,21 @@ //#define cfg_dbg(fmt...) printk(fmt) #ifdef CONFIG_PCI_MSI -static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type) -{ - struct pci_controller *hose = pci_bus_to_host(pdev->bus); - struct pnv_phb *phb = hose->private_data; - struct pci_dn *pdn = pci_get_pdn(pdev); - - if (pdn && pdn->force_32bit_msi && !phb->msi32_support) - return -ENODEV; - - return (phb && phb->msi_bmp.bitmap) ? 0 : -ENODEV; -} - static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) { struct pci_controller *hose = pci_bus_to_host(pdev->bus); struct pnv_phb *phb = hose->private_data; + struct pci_dn *pdn = pci_get_pdn(pdev); struct msi_desc *entry; struct msi_msg msg; int hwirq; unsigned int virq; int rc; - if (WARN_ON(!phb)) + if (WARN_ON(!phb) || !phb->msi_bmp.bitmap) + return -ENODEV; + + if (pdn && pdn->force_32bit_msi && !phb->msi32_support) return -ENODEV; list_for_each_entry(entry, &pdev->msi_list, list) { @@ -860,7 +852,6 @@ void __init pnv_pci_init(void) /* Configure MSI
[PATCH v2 0/3] PCI/MSI: Remove arch_msi_check_device()
Hello, This is a cleanup effort to get rid of arch_msi_check_device() function. I am sending v2 series, since kbuild for v1 reports compile errors on ppc4xx and Armada 370. Still, I have not checked the fixes on these platforms. Changes since v1: - patch 1: 'pdev' undeclared compile error fixed on ppc4xx. I updated changelog and removed ACK from this patch in case there are any objections; - patch 2: 'struct msi_chip' has no 'check_device' error fixed on Armada 370 - armada_370_xp_check_msi_device() hook removed; - patch 3: msi_check_device() renamed to pci_msi_supported(). This is the very same patch I sent earlier; Thanks! Cc: Thomas Gleixner Cc: Jason Cooper Cc: Michael Ellerman Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-...@vger.kernel.org Alexander Gordeev (3): patch 1 - PCI/MSI/PPC: Remove arch_msi_check_device() patch 2 - PCI/MSI/Armada-370-xp: Remove arch_msi_check_device() patch 3 - PCI/MSI: Remove arch_msi_check_device() arch/powerpc/include/asm/machdep.h | 2 -- arch/powerpc/kernel/msi.c | 12 + arch/powerpc/platforms/cell/axon_msi.c | 9 --- arch/powerpc/platforms/powernv/pci.c | 19 - arch/powerpc/platforms/pseries/msi.c | 42 +++-- arch/powerpc/sysdev/fsl_msi.c | 12 +++-- arch/powerpc/sysdev/mpic_pasemi_msi.c | 11 ++-- arch/powerpc/sysdev/mpic_u3msi.c | 28 --- arch/powerpc/sysdev/ppc4xx_hsta_msi.c | 18 + arch/powerpc/sysdev/ppc4xx_msi.c | 19 + drivers/irqchip/irq-armada-370-xp.c| 14 +++--- drivers/pci/msi.c | 49 +- include/linux/msi.h| 3 --- 13 files changed, 67 insertions(+), 171 deletions(-) -- 1.9.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 1/3] PCI/MSI/PPC: Remove arch_msi_check_device()
On Mon, Sep 15, 2014 at 12:42:50PM +1000, Michael Ellerman wrote: > On Sun, 2014-09-07 at 20:57 +0200, Alexander Gordeev wrote: > > Moving MSI checks from arch_msi_check_device() function to > > arch_setup_msi_irqs() function makes code more compact and > > allows removing unnecessary hook arch_msi_check_device() > > from generic MSI code. > > > > Cc: linuxppc-dev@lists.ozlabs.org > > Cc: linux-...@vger.kernel.org > > Cc: Michael Ellerman > > I already acked the previous version, but if you didn't want it that's fine :) I do want it, but I thought you may not agree with the new changelog ;) > cheers > > -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 0/1] powerpc: Fix irq_set_affinity() return values
Hi Ben, This fix is trivial. Just compile-tested it. Alexander Gordeev (1): powerpc: Fix irq_set_affinity() return values arch/powerpc/platforms/wsp/ics.c|2 +- arch/powerpc/sysdev/ehv_pic.c |2 +- arch/powerpc/sysdev/mpic.c |2 +- arch/powerpc/sysdev/xics/ics-opal.c |2 +- 4 files changed, 4 insertions(+), 4 deletions(-) -- 1.7.7.6 -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/1] powerpc: Fix irq_set_affinity() return values
Signed-off-by: Alexander Gordeev --- arch/powerpc/platforms/wsp/ics.c|2 +- arch/powerpc/sysdev/ehv_pic.c |2 +- arch/powerpc/sysdev/mpic.c |2 +- arch/powerpc/sysdev/xics/ics-opal.c |2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/wsp/ics.c b/arch/powerpc/platforms/wsp/ics.c index 97fe82e..2d3b1dd 100644 --- a/arch/powerpc/platforms/wsp/ics.c +++ b/arch/powerpc/platforms/wsp/ics.c @@ -361,7 +361,7 @@ static int wsp_chip_set_affinity(struct irq_data *d, xive = xive_set_server(xive, get_irq_server(ics, hw_irq)); wsp_ics_set_xive(ics, hw_irq, xive); - return 0; + return IRQ_SET_MASK_OK; } static struct irq_chip wsp_irq_chip = { diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c index 6e0e100..9cd0e60 100644 --- a/arch/powerpc/sysdev/ehv_pic.c +++ b/arch/powerpc/sysdev/ehv_pic.c @@ -81,7 +81,7 @@ int ehv_pic_set_affinity(struct irq_data *d, const struct cpumask *dest, ev_int_set_config(src, config, prio, cpuid); spin_unlock_irqrestore(&ehv_pic_lock, flags); - return 0; + return IRQ_SET_MASK_OK; } static unsigned int ehv_pic_type_to_vecpri(unsigned int type) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index d30e6a6..20f6625 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -836,7 +836,7 @@ int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, mpic_physmask(mask)); } - return 0; + return IRQ_SET_MASK_OK; } static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type) diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c index f7e8609..39d7221 100644 --- a/arch/powerpc/sysdev/xics/ics-opal.c +++ b/arch/powerpc/sysdev/xics/ics-opal.c @@ -148,7 +148,7 @@ static int ics_opal_set_affinity(struct irq_data *d, __func__, d->irq, hw_irq, server, rc); return -1; } - return 0; + return IRQ_SET_MASK_OK; } static struct irq_chip ics_opal_irq_chip = { -- 1.7.7.6 -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 0/3] Enable multiple MSI feature in pSeries
On Tue, Jan 15, 2013 at 03:38:53PM +0800, Mike Qiu wrote: > The test results is shown by 'cat /proc/interrups': > CPU0 CPU1 CPU2 CPU3 > 16: 240458 261601 226310 200425 XICS Level IPI > 17: 0 0 0 0 XICS Level RAS_EPOW > 18: 10 0 3 2 XICS Level > hvc_console > 19: 122182 28481 28527 28864 XICS Level ibmvscsi > 20:5067388226108118 XICS Level eth0 > 21: 6 5 5 5 XICS Level host1-0 > 22:817814816813 XICS Level host1-1 Hi Mike, I am curious if pSeries firmware allows changing affinity masks independently for multiple MSIs? I.e. in your example, would it be possible to assign IRQ21 and IRQ22 to different CPUs? Thanks! > LOC: 398077 316725 231882 203049 Local timer interrupts > SPU: 1659919961903 Spurious interrupts > CNT: 0 0 0 0 Performance > monitoring interrupts > MCE: 0 0 0 0 Machine check exceptions -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
On Mon, Sep 09, 2013 at 05:20:44PM +0200, Alexander Gordeev wrote: > On Fri, Sep 06, 2013 at 05:32:05PM -0600, Bjorn Helgaas wrote: > > I propose that you rework it that way, and at least find out what > > (if anything) would break if we do that. Or maybe we just give up > > some optimization; it would be nice to quantify that, too. > > Hi Bjorn, > > The series is what it seems a direction to take. > > Looks like we need PPC folks to agree on the quota check update > for pSeries (yes, they do bail out with a positive return value > from arch_msi_check_device()): Hi Ben, An initiative to simplify MSI/MSI-X allocation interface is brewing. It seems pSeries quota thing is an obstacle. If it could be given up (patch 2/9). Thanks! -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
On Wed, Sep 18, 2013 at 12:30:23AM +1000, Michael Ellerman wrote: > How about no? > > We have a small number of MSIs available, limited by hardware & > firmware, if we don't impose a quota then the first device that probes > will get most/all of the MSIs and other devices miss out. Out of curiosity - how pSeries has had done it without quotas before 448e2ca ("powerpc/pseries: Implement a quota system for MSIs")? > Anyway I don't see what problem you're trying to solve? I agree the > -ve/0/+ve return value pattern is ugly, but it's hardly the end of the > world. Well, the interface recently has been re-classified from "ugly" to "unnecessarily complex and actively harmful" in Tejun's words ;) Indeed, I checked most of the drivers and it is incredible how people are creative in misusing the interface: from innocent pci_disable_msix() calls when if pci_enable_msix() failed to assuming MSI-Xs were enabled if pci_enable_msix() returned a positive value (apparently untested). Roughly third of the drivers just do not care and bail out once pci_enable_msix() has not succeeded. Not sure how many of these are mandated by the hardware. Another quite common pattern is a call to pci_enable_msix() to figure out the number of MSI-Xs available and a repeated call of pci_enable_msix() to enable those MSI-Xs, this time. The last pattern makes most of sense to me and could be updated with a more clear sequence - a call to (bit modified) pci_msix_table_size() followed by a call to pci_enable_msix(). I think this pattern can effectively supersede the currently recommended "loop" practice. But as pSeries quota is still required I propose to introduce a new interface pci_get_msix_limit() that combines pci_msix_table_size() and (also new) arch_get_msix_limit(). The latter would check the quota thing in case of pSeries and none in case of all other architectures. The recommended practice would be: /* * Retrieving 'nvec' by means other than pci_msix_table_size() */ rc = pci_get_msix_limit(pdev); if (rc < 0) return rc; /* * nvec = min(rc, nvec); */ for (i = 0; i < nvec; i++) msix_entry[i].entry = i; rc = pci_enable_msix(pdev, msix_entry, nvec); if (rc) return rc; Thoughts? > cheers -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
On Wed, Sep 18, 2013 at 09:22:31AM -0500, Tejun Heo wrote: > > > We have a small number of MSIs available, limited by hardware & > > > firmware, if we don't impose a quota then the first device that probes > > > will get most/all of the MSIs and other devices miss out. > > > > Out of curiosity - how pSeries has had done it without quotas before > > 448e2ca ("powerpc/pseries: Implement a quota system for MSIs")? > > Hmmm... do we need to treat this any differently? If the platform > can't allocate full range of requested MSIs, just failing should be > enough regardless of why such allocation can't be met, no? That depends from what "full range of requested MSIs" is. If that is a maximum number of MSIs the controller advertised, then no. As MSI design essentially allows devices to operate in lower-than-maximum modes it is responsibility of a caller to decide how many vectors to request. So in case of pSeries I think it is completely legitimate to request lessers to overcome the platform limitation and let all devices work. > I really think what we should do is > > * Determine the number of MSIs the controller wants. Don't worry > about quotas or limits or anything. Just determine the number > necessary to enable enhanced interrupt handling. Actually, I do not see much contradiction with what I proposed. The key words here "determine the number of MSIs the controller wants". In general case it is not what pci_msix_table_size() returns (or at least we should not limit ourselves to it) - there could be non- standard means to report number of MSIs: hardcoded, version-dependant, device-specific registers etc. Next, if we opt to determine the number of MSIs by non-MSI standard means then there is no reason not to call pci_get_msix_limit() (or whatever) at this step. The question how I see it - do we want pci_get_msix_limit() interface as part of the MSI framework or do we want it pSeries-specific? > * Try allocating that number of MSIs. If it fails, then just revert > to single interrupt mode. It's not the end of the world and mostly > guaranteed to work. Let's please not even try to do partial > multiple interrupts. I really don't think it's worth the risk or > complexity. Being Captain Obvious here, but it is up to the device driver to handle a failure. There could be no such option as single MSI mode after all :) > Thanks. > > -- > tejun -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
Michael et al. The identifiable options sounded so far were: * Do not change anything * Make pci_enable_msix() return 0/-errno * Make pci_enable_msix() return 0/-errno and introduce arch_get_msix_limit()/ arch_get_msi_limit() * Make pci_enable_msix() return 0/-errno and introduce pci_get_msix_limit()/ pci_get_msi_limit() and arch_get_msix_limit()/arch_get_msi_limit() so that: pci_get_msix_limit() = min(arch_get_msix_limit(), pci_msix_table_size()) pci_get_msi_limit() = min(arch_get_msi_limit(), pci_get_msi_cap()) Can we have a conclusion here? Thanks! -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
On Wed, Sep 25, 2013 at 12:02:20PM -0600, Bjorn Helgaas wrote: > On Fri, Sep 20, 2013 at 07:27:36AM -0500, Tejun Heo wrote: > > On Fri, Sep 20, 2013 at 10:24:59AM +0200, Alexander Gordeev wrote: > > > * Make pci_enable_msix() return 0/-errno > > > > My choice would be this one. > > I agree; it sounds like you've identified several bugs related to the > current confusing interface, so fixing that seems like the first step. Yeah, I am trying to. Turns out to be a nice exercise ;) > I hope we can avoid adding a plethora of interfaces to address unusual > corner cases. But if we do the above and it turns out not to be enough, > we can always extend it later. Unfortunately, pSeries is a shows-topper here :( It seems we have to introduce pci_get_msi{,x}_limit() interfaces to honour the quota thing. I just hope the hardware set for pSeries is limited and we won't need to use it for all drivers. > Bjorn -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
On Wed, Sep 25, 2013 at 05:00:16PM -0400, Tejun Heo wrote: > Hello, > > On Wed, Sep 25, 2013 at 10:58:05PM +0200, Alexander Gordeev wrote: > > Unfortunately, pSeries is a shows-topper here :( It seems we have to > > introduce pci_get_msi{,x}_limit() interfaces to honour the quota > > thing. I just hope the hardware set for pSeries is limited and we > > won't need to use it for all drivers. > > Can you please go into a bit of detail on that? Why does it matter? Because otherwise we will re-introduce a problem described by Michael: "We have a small number of MSIs available, limited by hardware & firmware, if we don't impose a quota then the first device that probes will get most/all of the MSIs and other devices miss out." > Is it because you're worried you might cause performance regression by > forcing prevoius partial multiple allocations to single interrupt > operation? Well, not really. I think it won't be possible to force people not to use partial allocations anyway. Some controllers just do not care how many MSIs they are configured with. Some drivers derive the number of MSIs desired from the number of CPUs online - in such cases allocating more MSIs (i.e. a number the controller advertised) could cause a performance degradation even. So when driver authors will know/measure/believe their hardware performs better with partial allocations they will stand for it. What we can do is to prevent those try-and-decrease fallbacks. > Thanks. > > -- > tejun -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
On Thu, Sep 26, 2013 at 09:58:53AM +0100, David Laight wrote: > Would it be possible to do some kind of 2-stage allocation. > In the first pass the driver would pass a minimum and desired > number of MSI-X interrupts, but not actually be given any. Repeated calls to msi_enable_msi/msix() is what we are trying to avoid. > Interrupts could then be allocated after it is known how many > are required and how many are available. Yep, that what we are heading to. So basic pattern I see would be like this: int foo_driver_enable_msix(struct pci_dev *pdev, int nvec) { ... rc = pci_msix_table_size(pdev); if (rc < 0) return rc; nvec = min(nvec, rc); if (nvec < FOO_DRIVER_MINIMUM_NVEC) goto single_msi; for (i = 0; i < nvec; i++) entries[i].entry = i; rc = pci_enable_msix(pdev, entries, nvec); if (rc) goto single_msi; return 0; single_msi: ... } But this will break pSeries and we might end up with something like this: int foo_driver_enable_msix(struct pci_dev *pdev, int nvec) { ... rc = pci_msix_table_size(pdev); if (rc < 0) return rc; nvec = min(nvec, rc); if (nvec < FOO_DRIVER_MINIMUM_NVEC) goto single_msi; rc = pci_get_msix_limit(pdev, nvec); if (rc < 0) return rc; nvec = min(nvec, rc); if (nvec < FOO_DRIVER_MINIMUM_NVEC) goto single_msi; for (i = 0; i < nvec; i++) entries[i].entry = i; rc = pci_enable_msix(pdev, entries, nvec); if (rc) goto single_msi; return 0; single_msi: ... } > David -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
On Thu, Sep 26, 2013 at 12:34:36PM +0100, David Laight wrote: > I was thinking that the first call would be done during driver probe > (assuming such a time exists) so that the subsystem could determine > how many interrupts all the drivers would like, so it can then > hand out a smaller number to some of the early drivers in order > to have some left to satisfy the minimum requirement of later > ones. > > So all it would do is sum the requirements of all the drivers. It is already implemented - please see commit 448e2ca ("powerpc/pseries: Implement a quota system for MSIs") All other archs do not have MSI vector space limitations. > David -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
On Thu, Sep 26, 2013 at 08:32:53AM -0400, Mark Lord wrote: > On 13-09-18 05:48 AM, Alexander Gordeev wrote: > > The last pattern makes most of sense to me and could be updated with a more > > clear sequence - a call to (bit modified) pci_msix_table_size() followed > > by a call to pci_enable_msix(). I think this pattern can effectively > > supersede the currently recommended "loop" practice. > > The loop is still necessary, because there's a race between those two calls, > so that pci_enable_msix() can still fail due to lack of MSIX slots. Moreover, the existing loop pattern is racy and could fail just as easily ;) But (1) that is something drivers should expect and (2) there is basically nothing to race against - that is probably the reason it has not been a problem for pSeries. So I think we should not care about this. -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
On Thu, Sep 26, 2013 at 09:11:47AM -0400, Tejun Heo wrote: > > Because otherwise we will re-introduce a problem described by Michael: > > "We have a small number of MSIs available, limited by hardware & > > firmware, if we don't impose a quota then the first device that probes > > will get most/all of the MSIs and other devices miss out." > > Still not following. Why wouldn't just letting the drivers request > the optimal number they want and falling back to single interrupt mode > work? ie. why can't we just have an all or nothing interface? I can imagine a scenario where the first device probes in, requests its optimal number, acquires that number and exhausts MSIs in pSeries firmware. The next few devices possibly end up with single MSI, since no MSIs left to satisfy their optimal numbers. If one of those single-MSI'ed devices happened to be a high-performance HBA hitting a degraded performance that alone would force (IBM) to introduce the quotas. Now, if the same/another device happened does not support the legacy interrupt mode and no MSI resources have left in the platform firmware at all... > tejun -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
On Tue, Oct 01, 2013 at 05:51:33PM +1000, Michael Ellerman wrote: > The disadvantage is that any restriction imposed on us above the quota > can only be reported as an error from pci_enable_msix(). > > The quota code, called from pci_get_msix_limit(), can only do so much to > interogate firmware about the limitations. The ultimate way to check if > firmware will give us enough MSIs is to try and allocate them. But we > can't do that from pci_get_msix_limit() because the driver is not asking > us to enable MSIs, just query them. If things are this way then pci_enable_msix() already exposed to this problem internally on pSeries. I see that even successful quota checks in rtas_msi_check_device() and rtas_setup_msi_irqs() do not guarantee (as you say) that firmware will give enough MSIs. Hence, pci_enable_msix() might fail even though the its quota checks succeeded. Therefore, nothing will really change if we make pci_get_msix_limit() check quota and hope the follow-up call to pci_enable_msix() succeeded. (Of course, we could allocate-deallocate MSIs at check time, but I think it is an overkill). > You'll also need to add another arch hook, for the quota check, and > we'll have to add it to our per-platform indirection as well. Already, in a branch, hidden from Bjorn & Tejun eyes ;) > All a lot of bother for no real gain IMHO. Well, I do not have a strong opinion here. I leave it to the ones who have :) But few drivers have became clearer as result of this change (and messy ones are still messy). > cheers -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
On Wed, Oct 02, 2013 at 12:43:24PM +1000, Michael Ellerman wrote: > On Tue, Oct 01, 2013 at 12:35:27PM +0200, Alexander Gordeev wrote: > > On Tue, Oct 01, 2013 at 05:51:33PM +1000, Michael Ellerman wrote: > > > The disadvantage is that any restriction imposed on us above the quota > > > can only be reported as an error from pci_enable_msix(). > > > > > > The quota code, called from pci_get_msix_limit(), can only do so much to > > > interogate firmware about the limitations. The ultimate way to check if > > > firmware will give us enough MSIs is to try and allocate them. But we > > > can't do that from pci_get_msix_limit() because the driver is not asking > > > us to enable MSIs, just query them. > > > > If things are this way then pci_enable_msix() already exposed to this > > problem internally on pSeries. > > > > I see that even successful quota checks in rtas_msi_check_device() and > > rtas_setup_msi_irqs() do not guarantee (as you say) that firmware will > > give enough MSIs. Hence, pci_enable_msix() might fail even though the > > its quota checks succeeded. > > Yes, but it can report that failure to the caller, which can then retry. If a driver wants to retry after a failure it is up to the driver (but why?). The current guidlines state: "If this function returns a negative number, it indicates an error and the driver should not attempt to allocate any more MSI-X interrupts for this device." Anyway, what number could the driver retry with after it got a negative errno? > > Therefore, nothing will really change if we make pci_get_msix_limit() check > > quota and hope the follow-up call to pci_enable_msix() succeeded. > > No that's not equivalent. Under your scheme if pci_enable_msix() fails > then the caller just bails, it will never try again with a lower number. Currently under the very same circumstances (the quota check within rtas_setup_msi_irqs() returned Q vectors while the firmware has only F vectors to allocate and Q > F) rtas_setup_msi_irqs() fails, pci_enable_msix() fails, the caller bails and never try again with a lower number. Am I missing something here? > cheers -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface
On Tue, Oct 01, 2013 at 10:46:32PM -0400, Mark Lord wrote: > >>> The last pattern makes most of sense to me and could be updated with a > >>> more > >>> clear sequence - a call to (bit modified) pci_msix_table_size() followed > >>> by a call to pci_enable_msix(). I think this pattern can effectively > >>> supersede the currently recommended "loop" practice. > >> > >> The loop is still necessary, because there's a race between those two > >> calls, > >> so that pci_enable_msix() can still fail due to lack of MSIX slots. > > > > Moreover, the existing loop pattern is racy and could fail just as easily ;) > > Yes, but it then loops again to correct things. No. If it failed it should exit the loop. -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 52/77] niu: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/sun/niu.c | 20 +++- 1 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index f28460c..54c41b9 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -9051,26 +9051,28 @@ static void niu_try_msix(struct niu *np, u8 *ldg_num_map) (np->port == 0 ? 3 : 1)); BUG_ON(num_irqs > (NIU_NUM_LDG / parent->num_ports)); -retry: + err = pci_msix_table_size(pdev); + if (err < 0) + goto fail; + + num_irqs = min(num_irqs, err); for (i = 0; i < num_irqs; i++) { msi_vec[i].vector = 0; msi_vec[i].entry = i; } err = pci_enable_msix(pdev, msi_vec, num_irqs); - if (err < 0) { - np->flags &= ~NIU_FLAGS_MSIX; - return; - } - if (err > 0) { - num_irqs = err; - goto retry; - } + if (err) + goto fail; np->flags |= NIU_FLAGS_MSIX; for (i = 0; i < num_irqs; i++) np->ldg[i].irq = msi_vec[i].vector; np->num_ldg = num_irqs; + return; + +fail: + np->flags &= ~NIU_FLAGS_MSIX; } static int niu_n2_irq_init(struct niu *np, u8 *ldg_num_map) -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 51/77] mthca: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/infiniband/hw/mthca/mthca_main.c | 16 +++- 1 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 87897b9..3d44ca4 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c @@ -854,17 +854,23 @@ static int mthca_enable_msi_x(struct mthca_dev *mdev) struct msix_entry entries[3]; int err; + err = pci_msix_table_size(mdev->pdev); + if (err < 0) + return err; + if (err < ARRAY_SIZE(entries)) { + mthca_info(mdev, "Only %d MSI-X vectors available, " + "not using MSI-X\n", err); + + return -ENOSPC; + } + entries[0].entry = 0; entries[1].entry = 1; entries[2].entry = 2; err = pci_enable_msix(mdev->pdev, entries, ARRAY_SIZE(entries)); - if (err) { - if (err > 0) - mthca_info(mdev, "Only %d MSI-X vectors available, " - "not using MSI-X\n", err); + if (err) return err; - } mdev->eq_table.eq[MTHCA_EQ_COMP ].msi_x_vector = entries[0].vector; mdev->eq_table.eq[MTHCA_EQ_ASYNC].msi_x_vector = entries[1].vector; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 70/77] vmci: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/misc/vmw_vmci/vmci_guest.c | 22 +++--- 1 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c index b3a2b76..af5caf8 100644 --- a/drivers/misc/vmw_vmci/vmci_guest.c +++ b/drivers/misc/vmw_vmci/vmci_guest.c @@ -377,19 +377,27 @@ static int vmci_enable_msix(struct pci_dev *pdev, { int i; int result; + int nvec; - for (i = 0; i < VMCI_MAX_INTRS; ++i) { + result = pci_msix_table_size(pdev); + if (result < 0) + return result; + + nvec = min(result, VMCI_MAX_INTRS); + if (nvec < VMCI_MAX_INTRS) + nvec = 1; + + for (i = 0; i < nvec; ++i) { vmci_dev->msix_entries[i].entry = i; vmci_dev->msix_entries[i].vector = i; } - result = pci_enable_msix(pdev, vmci_dev->msix_entries, VMCI_MAX_INTRS); - if (result == 0) - vmci_dev->exclusive_vectors = true; - else if (result > 0) - result = pci_enable_msix(pdev, vmci_dev->msix_entries, 1); + result = pci_enable_msix(pdev, vmci_dev->msix_entries, nvec); + if (result) + return result; - return result; + vmci_dev->exclusive_vectors = true; + return 0; } /* -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 59/77] qla2xxx: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/scsi/qla2xxx/qla_isr.c | 18 +++--- 1 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index df1b30b..6c11ab9 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -2836,16 +2836,20 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) for (i = 0; i < ha->msix_count; i++) entries[i].entry = i; - ret = pci_enable_msix(ha->pdev, entries, ha->msix_count); - if (ret) { + ret = pci_msix_table_size(ha->pdev); + if (ret < 0) { + goto msix_failed; + } else { if (ret < MIN_MSIX_COUNT) goto msix_failed; - ql_log(ql_log_warn, vha, 0x00c6, - "MSI-X: Failed to enable support " - "-- %d/%d\n Retry with %d vectors.\n", - ha->msix_count, ret, ret); - ha->msix_count = ret; + if (ret < ha->msix_count) { + ql_log(ql_log_warn, vha, 0x00c6, + "MSI-X: Failed to enable support " + "-- %d/%d\n Retry with %d vectors.\n", + ha->msix_count, ret, ret); + ha->msix_count = ret; + } ret = pci_enable_msix(ha->pdev, entries, ha->msix_count); if (ret) { msix_failed: -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 45/77] megaraid: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/scsi/megaraid/megaraid_sas_base.c | 20 +--- 1 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 3020921..b5973e4 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -3727,18 +3727,16 @@ static int megasas_init_fw(struct megasas_instance *instance) (unsigned int)num_online_cpus()); for (i = 0; i < instance->msix_vectors; i++) instance->msixentry[i].entry = i; - i = pci_enable_msix(instance->pdev, instance->msixentry, - instance->msix_vectors); - if (i >= 0) { - if (i) { - if (!pci_enable_msix(instance->pdev, -instance->msixentry, i)) - instance->msix_vectors = i; - else - instance->msix_vectors = 0; - } - } else + i = pci_msix_table_size(instance->pdev); + if (i < 0) { instance->msix_vectors = 0; + } else { + if (!pci_enable_msix(instance->pdev, +instance->msixentry, i)) + instance->msix_vectors = i; + else + instance->msix_vectors = 0; + } dev_info(&instance->pdev->dev, "[scsi%d]: FW supports" "<%d> MSIX vector,Online CPUs: <%d>," -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 15/77] bnx2: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/broadcom/bnx2.c | 27 ++- 1 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index e838a3f..c902627 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -6202,25 +6202,26 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs) * is setup properly */ BNX2_RD(bp, BNX2_PCI_MSIX_CONTROL); - for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) { - msix_ent[i].entry = i; - msix_ent[i].vector = 0; - } - total_vecs = msix_vecs; #ifdef BCM_CNIC total_vecs++; #endif - rc = -ENOSPC; - while (total_vecs >= BNX2_MIN_MSIX_VEC) { - rc = pci_enable_msix(bp->pdev, msix_ent, total_vecs); - if (rc <= 0) - break; - if (rc > 0) - total_vecs = rc; + rc = pci_msix_table_size(bp->pdev); + if (rc < 0) + return; + + total_vecs = min(total_vecs, rc); + if (total_vecs < BNX2_MIN_MSIX_VEC) + return; + + BUG_ON(total_vecs > ARRAY_SIZE(msix_ent)); + for (i = 0; i < total_vecs; i++) { + msix_ent[i].entry = i; + msix_ent[i].vector = 0; } - if (rc != 0) + rc = pci_enable_msix(bp->pdev, msix_ent, total_vecs); + if (rc) return; msix_vecs = total_vecs; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 46/77] mlx4: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/mellanox/mlx4/main.c | 17 - 1 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 60c9f4f..377a5ea 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1852,8 +1852,16 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) int i; if (msi_x) { + err = pci_msix_table_size(dev->pdev); + if (err < 0) + goto no_msi; + + /* Try if at least 2 vectors are available */ nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs, nreq); + nreq = min_t(int, nreq, err); + if (nreq < 2) + goto no_msi; entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL); if (!entries) @@ -1862,17 +1870,8 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) for (i = 0; i < nreq; ++i) entries[i].entry = i; - retry: err = pci_enable_msix(dev->pdev, entries, nreq); if (err) { - /* Try again if at least 2 vectors are available */ - if (err > 1) { - mlx4_info(dev, "Requested %d vectors, " - "but only %d MSI-X vectors available, " - "trying again\n", nreq, err); - nreq = err; - goto retry; - } kfree(entries); goto no_msi; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 16/77] cciss: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/block/cciss.c | 17 +++-- 1 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index d2d95ff..80068a0 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4079,7 +4079,11 @@ static void cciss_interrupt_mode(ctlr_info_t *h) goto default_int_mode; if (pci_find_capability(h->pdev, PCI_CAP_ID_MSIX)) { - err = pci_enable_msix(h->pdev, cciss_msix_entries, 4); + err = pci_msix_table_size(h->pdev); + if (err < ARRAY_SIZE(cciss_msix_entries)) + goto default_int_mode; + err = pci_enable_msix(h->pdev, cciss_msix_entries, + ARRAY_SIZE(cciss_msix_entries)); if (!err) { h->intr[0] = cciss_msix_entries[0].vector; h->intr[1] = cciss_msix_entries[1].vector; @@ -4088,15 +4092,8 @@ static void cciss_interrupt_mode(ctlr_info_t *h) h->msix_vector = 1; return; } - if (err > 0) { - dev_warn(&h->pdev->dev, - "only %d MSI-X vectors available\n", err); - goto default_int_mode; - } else { - dev_warn(&h->pdev->dev, - "MSI-X init failed %d\n", err); - goto default_int_mode; - } + dev_warn(&h->pdev->dev, "MSI-X init failed %d\n", err); + goto default_int_mode; } if (pci_find_capability(h->pdev, PCI_CAP_ID_MSI)) { if (!pci_enable_msi(h->pdev)) -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 57/77] pmcraid: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/scsi/pmcraid.c | 23 +++ 1 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 1eb7b028..5c62d22 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -4680,24 +4680,23 @@ pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance) if ((pmcraid_enable_msix) && (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) { - int num_hrrq = PMCRAID_NUM_MSIX_VECTORS; struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS]; + int num_hrrq = ARRAY_SIZE(entries); int i; - for (i = 0; i < PMCRAID_NUM_MSIX_VECTORS; i++) - entries[i].entry = i; - - rc = pci_enable_msix(pdev, entries, num_hrrq); - if (rc < 0) - goto pmcraid_isr_legacy; /* Check how many MSIX vectors are allocated and register * msi-x handlers for each of them giving appropriate buffer */ - if (rc > 0) { - num_hrrq = rc; - if (pci_enable_msix(pdev, entries, num_hrrq)) - goto pmcraid_isr_legacy; - } + rc = pci_msix_table_size(pdev); + if (rc < 0) + goto pmcraid_isr_legacy; + + num_hrrq = min(num_hrrq, rc); + for (i = 0; i < num_hrrq; i++) + entries[i].entry = i; + + if (pci_enable_msix(pdev, entries, num_hrrq)) + goto pmcraid_isr_legacy; for (i = 0; i < num_hrrq; i++) { pinstance->hrrq_vector[i].hrrq_id = i; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 21/77] csiostor: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/scsi/csiostor/csio_isr.c | 18 -- 1 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/csiostor/csio_isr.c b/drivers/scsi/csiostor/csio_isr.c index abf20ab..b8a840e 100644 --- a/drivers/scsi/csiostor/csio_isr.c +++ b/drivers/scsi/csiostor/csio_isr.c @@ -512,6 +512,16 @@ csio_enable_msix(struct csio_hw *hw) if (hw->flags & CSIO_HWF_USING_SOFT_PARAMS || !csio_is_hw_master(hw)) cnt = min_t(uint8_t, hw->cfg_niq, cnt); + rv = pci_msix_table_size(hw->pdev); + if (rv < 0) + return rv; + + cnt = min(cnt, rv); + if (cnt < min) { + csio_info(hw, "Not using MSI-X, remainder:%d\n", rv); + return -ENOSPC; + } + entries = kzalloc(sizeof(struct msix_entry) * cnt, GFP_KERNEL); if (!entries) return -ENOMEM; @@ -521,19 +531,15 @@ csio_enable_msix(struct csio_hw *hw) csio_dbg(hw, "FW supp #niq:%d, trying %d msix's\n", hw->cfg_niq, cnt); - while ((rv = pci_enable_msix(hw->pdev, entries, cnt)) >= min) - cnt = rv; + rv = pci_enable_msix(hw->pdev, entries, cnt); if (!rv) { if (cnt < (hw->num_sqsets + extra)) { csio_dbg(hw, "Reducing sqsets to %d\n", cnt - extra); csio_reduce_sqsets(hw, cnt - extra); } } else { - if (rv > 0) - csio_info(hw, "Not using MSI-X, remainder:%d\n", rv); - kfree(entries); - return -ENOSPC; + return rv; } /* Save off vectors */ -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 24/77] cxgb3: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 29 --- 1 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 915729c..bf14fd6 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -3090,25 +3090,26 @@ static int cxgb_enable_msix(struct adapter *adap) int vectors; int i, err; - vectors = ARRAY_SIZE(entries); + err = pci_msix_table_size(adap->pdev); + if (err < 0) + return err; + + vectors = min_t(int, err, ARRAY_SIZE(entries)); + if (vectors < (adap->params.nports + 1)) + return -ENOSPC; + for (i = 0; i < vectors; ++i) entries[i].entry = i; - while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0) - vectors = err; - - if (!err && vectors < (adap->params.nports + 1)) { - pci_disable_msix(adap->pdev); - err = -ENOSPC; - } + err = pci_enable_msix(adap->pdev, entries, vectors); + if (err) + return err; - if (!err) { - for (i = 0; i < vectors; ++i) - adap->msix_info[i].vec = entries[i].vector; - adap->msix_nvectors = vectors; - } + for (i = 0; i < vectors; ++i) + adap->msix_info[i].vec = entries[i].vector; + adap->msix_nvectors = vectors; - return err; + return 0; } static void print_port_info(struct adapter *adap, const struct adapter_info *ai) -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 42/77] lpfc: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Note, in case just one MSI-X vector was available the error message "0484 PCI enable MSI-X failed 1" is preserved to not break tools which might depend on it. Also, not sure why in case of multiple MSI-Xs mode failed the driver skips the single MSI-X mode and falls back to single MSI mode. Signed-off-by: Alexander Gordeev --- drivers/scsi/lpfc/lpfc_init.c | 18 +++--- 1 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 0803b84..d83a1a3 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -8639,13 +8639,17 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) /* Configure MSI-X capability structure */ vectors = phba->cfg_fcp_io_channel; -enable_msix_vectors: - rc = pci_enable_msix(phba->pcidev, phba->sli4_hba.msix_entries, -vectors); - if (rc > 1) { - vectors = rc; - goto enable_msix_vectors; - } else if (rc) { + + rc = pci_msix_table_size(phba->pcidev); + if (rc < 0) + goto msg_fail_out; + + vectors = min(vectors, rc); + if (vectors > 1) + rc = pci_enable_msix(phba->pcidev, phba->sli4_hba.msix_entries, +vectors); + if (rc) { +msg_fail_out: lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0484 PCI enable MSI-X failed (%d)\n", rc); goto vec_fail_out; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 50/77] mlx5: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 18 +- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index adf0e5d..5c21e50 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -119,8 +119,13 @@ static int mlx5_enable_msix(struct mlx5_core_dev *dev) int err; int i; + err = pci_msix_table_size(dev->pdev); + if (err < 0) + return err; + nvec = dev->caps.num_ports * num_online_cpus() + MLX5_EQ_VEC_COMP_BASE; nvec = min_t(int, nvec, num_eqs); + nvec = min_t(int, nvec, err); if (nvec <= MLX5_EQ_VEC_COMP_BASE) return -ENOSPC; @@ -131,20 +136,15 @@ static int mlx5_enable_msix(struct mlx5_core_dev *dev) for (i = 0; i < nvec; i++) table->msix_arr[i].entry = i; -retry: - table->num_comp_vectors = nvec - MLX5_EQ_VEC_COMP_BASE; err = pci_enable_msix(dev->pdev, table->msix_arr, nvec); - if (err <= 0) { + if (err) { + kfree(table->msix_arr); return err; - } else if (err > MLX5_EQ_VEC_COMP_BASE) { - nvec = err; - goto retry; } - mlx5_core_dbg(dev, "received %d MSI vectors out of %d requested\n", err, nvec); - kfree(table->msix_arr); + table->num_comp_vectors = nvec - MLX5_EQ_VEC_COMP_BASE; - return -ENOSPC; + return 0; } static void mlx5_disable_msix(struct mlx5_core_dev *dev) -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 10/77] ahci: Check MRSM bit when multiple MSIs enabled
Do not trust the hardware and always check if MSI Revert to Single Message mode was enforced. Fall back to the single MSI mode in case it did. Not doing so might screw up the interrupt handling. Signed-off-by: Alexander Gordeev --- drivers/ata/ahci.c | 17 + drivers/ata/ahci.h |1 + 2 files changed, 18 insertions(+), 0 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index f1c8838..3a39cc8 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1091,6 +1091,14 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) {} #endif +static int ahci_get_mrsm(struct ahci_host_priv *hpriv) +{ + void __iomem *mmio = hpriv->mmio; + u32 ctl = readl(mmio + HOST_CTL); + + return ctl & HOST_MRSM; +} + int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, struct ahci_host_priv *hpriv) { @@ -1116,6 +1124,15 @@ int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, if (rc) goto intx; + /* +* Fallback to single MSI mode if the controller enforced MRSM mode +*/ + if (ahci_get_mrsm(hpriv)) { + pci_disable_msi(pdev); + printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n"); + goto single_msi; + } + return nvec; single_msi: diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 1145637..19bc846 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -91,6 +91,7 @@ enum { /* HOST_CTL bits */ HOST_RESET = (1 << 0), /* reset controller; self-clear */ HOST_IRQ_EN = (1 << 1), /* global IRQ enable */ + HOST_MRSM = (1 << 2), /* MSI Revert to Single Message */ HOST_AHCI_EN= (1 << 31), /* AHCI enabled */ /* HOST_CAP bits */ -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 40/77] ixgbevf: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 18 +++--- 1 files changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index fa0537a..d506a01 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -1749,8 +1749,7 @@ void ixgbevf_reset(struct ixgbevf_adapter *adapter) static int ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter, int vectors) { - int err = 0; - int vector_threshold; + int err, vector_threshold; /* We'll want at least 2 (vector_threshold): * 1) TxQ[0] + RxQ[0] handler @@ -1763,18 +1762,15 @@ static int ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter, * Right now, we simply care about how many we'll get; we'll * set them up later while requesting irq's. */ - while (vectors >= vector_threshold) { - err = pci_enable_msix(adapter->pdev, adapter->msix_entries, - vectors); - if (!err || err < 0) /* Success or a nasty failure. */ - break; - else /* err == number of vectors we should try again with */ - vectors = err; - } + err = pci_msix_table_size(adapter->pdev); + if (err < 0) + return err; + vectors = min(vectors, err); if (vectors < vector_threshold) - err = -ENOSPC; + return -ENOSPC; + err = pci_enable_msix(adapter->pdev, adapter->msix_entries, vectors); if (err) { dev_err(&adapter->pdev->dev, "Unable to allocate MSI-X interrupts\n"); -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 67/77] rapidio: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/rapidio/devices/tsi721.c | 27 +-- 1 files changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index ff7cbf2..5edd920 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c @@ -734,6 +734,16 @@ static int tsi721_enable_msix(struct tsi721_device *priv) int err; int i; + err = pci_msix_table_size(priv->pdev); + if (err < 0) + goto err_out; + if (err < ARRAY_SIZE(entries)) { + dev_info(&priv->pdev->dev, +"Only %d MSI-X vectors available, not using MSI-X\n", +err); + return -ENOSPC; + } + entries[TSI721_VECT_IDB].entry = TSI721_MSIX_SR2PC_IDBQ_RCV(IDB_QUEUE); entries[TSI721_VECT_PWRX].entry = TSI721_MSIX_SRIO_MAC_INT; @@ -769,16 +779,8 @@ static int tsi721_enable_msix(struct tsi721_device *priv) #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ err = pci_enable_msix(priv->pdev, entries, ARRAY_SIZE(entries)); - if (err) { - if (err > 0) - dev_info(&priv->pdev->dev, -"Only %d MSI-X vectors available, " -"not using MSI-X\n", err); - else - dev_err(&priv->pdev->dev, - "Failed to enable MSI-X (err=%d)\n", err); - return err; - } + if (err) + goto err_out; /* * Copy MSI-X vector information into tsi721 private structure @@ -833,6 +835,11 @@ static int tsi721_enable_msix(struct tsi721_device *priv) #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ return 0; + +err_out: + dev_err(&priv->pdev->dev, + "Failed to enable MSI-X (err=%d)\n", err); + return err; } #endif /* CONFIG_PCI_MSI */ -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 68/77] sfc: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/sfc/efx.c | 18 +++--- 1 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 07c9bc4..184ef9f 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1261,21 +1261,24 @@ static int efx_probe_interrupts(struct efx_nic *efx) n_channels += extra_channels; n_channels = min(n_channels, efx->max_channels); - for (i = 0; i < n_channels; i++) - xentries[i].entry = i; - rc = pci_enable_msix(efx->pci_dev, xentries, n_channels); - if (rc > 0) { + rc = pci_msix_table_size(efx->pci_dev); + if (rc < 0) + goto msi; + + if (rc < n_channels) { netif_err(efx, drv, efx->net_dev, "WARNING: Insufficient MSI-X vectors" " available (%d < %u).\n", rc, n_channels); netif_err(efx, drv, efx->net_dev, "WARNING: Performance may be reduced.\n"); - EFX_BUG_ON_PARANOID(rc >= n_channels); n_channels = rc; - rc = pci_enable_msix(efx->pci_dev, xentries, -n_channels); } + EFX_BUG_ON_PARANOID(n_channels > ARRAY_SIZE(xentries)); + for (i = 0; i < n_channels; i++) + xentries[i].entry = i; + + rc = pci_enable_msix(efx->pci_dev, xentries, n_channels); if (rc == 0) { efx->n_channels = n_channels; if (n_channels > extra_channels) @@ -1293,6 +1296,7 @@ static int efx_probe_interrupts(struct efx_nic *efx) efx_get_channel(efx, i)->irq = xentries[i].vector; } else { +msi: /* Fall back to single channel MSI */ efx->interrupt_mode = EFX_INT_MODE_MSI; netif_err(efx, drv, efx->net_dev, -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 56/77] nvme: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/block/nvme-core.c | 48 +++- 1 files changed, 25 insertions(+), 23 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index da52092..f69d7af 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1774,34 +1774,36 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) /* Deregister the admin queue's interrupt */ free_irq(dev->entry[0].vector, dev->queues[0]); - vecs = nr_io_queues; + result = pci_msix_table_size(pdev); + if (result < 0) + goto msi; + + vecs = min(result, nr_io_queues); for (i = 0; i < vecs; i++) dev->entry[i].entry = i; - for (;;) { - result = pci_enable_msix(pdev, dev->entry, vecs); - if (result <= 0) - break; - vecs = result; - } - if (result < 0) { - vecs = nr_io_queues; - if (vecs > 32) - vecs = 32; - for (;;) { - result = pci_enable_msi_block(pdev, vecs); - if (result == 0) { - for (i = 0; i < vecs; i++) - dev->entry[i].vector = i + pdev->irq; - break; - } else if (result < 0) { - vecs = 1; - break; - } - vecs = result; - } + result = pci_enable_msix(pdev, dev->entry, vecs); + if (result == 0) + goto irq; + + msi: + result = pci_get_msi_cap(pdev); + if (result < 0) + goto no_msi; + + vecs = min(result, nr_io_queues); + + result = pci_enable_msi_block(pdev, vecs); + if (result == 0) { + for (i = 0; i < vecs; i++) + dev->entry[i].vector = i + pdev->irq; + goto irq; } + no_msi: + vecs = 1; + + irq: /* * Should investigate if there's a performance win from allocating * more queues than interrupt vectors; it might allow the submission -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 77/77] vxge: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/neterion/vxge/vxge-main.c | 36 ++- 1 files changed, 16 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index b81ff8b..b4d40dd 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c @@ -2297,7 +2297,21 @@ static int vxge_alloc_msix(struct vxgedev *vdev) int msix_intr_vect = 0, temp; vdev->intr_cnt = 0; -start: + ret = pci_msix_table_size(vdev->pdev); + if (ret < 0) + goto alloc_entries_failed; + + if (ret < (vdev->no_of_vpath * 2 + 1)) { + if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3)) { + ret = -ENOSPC; + goto alloc_entries_failed; + } + /* Try with less no of vector by reducing no of vpaths count */ + temp = (ret - 1)/2; + vxge_close_vpaths(vdev, temp); + vdev->no_of_vpath = temp; + } + /* Tx/Rx MSIX Vectors count */ vdev->intr_cnt = vdev->no_of_vpath * 2; @@ -2347,25 +2361,7 @@ start: vdev->vxge_entries[j].in_use = 0; ret = pci_enable_msix(vdev->pdev, vdev->entries, vdev->intr_cnt); - if (ret > 0) { - vxge_debug_init(VXGE_ERR, - "%s: MSI-X enable failed for %d vectors, ret: %d", - VXGE_DRIVER_NAME, vdev->intr_cnt, ret); - if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3)) { - ret = -ENOSPC; - goto enable_msix_failed; - } - - kfree(vdev->entries); - kfree(vdev->vxge_entries); - vdev->entries = NULL; - vdev->vxge_entries = NULL; - /* Try with less no of vector by reducing no of vpaths count */ - temp = (ret - 1)/2; - vxge_close_vpaths(vdev, temp); - vdev->no_of_vpath = temp; - goto start; - } else if (ret < 0) + if (ret) goto enable_msix_failed; return 0; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 31/77] hpsa: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/scsi/hpsa.c | 28 +--- 1 files changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 393c8db..eb17b3d 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -4103,34 +4103,32 @@ static void hpsa_interrupt_mode(struct ctlr_info *h) int err, i; struct msix_entry hpsa_msix_entries[MAX_REPLY_QUEUES]; - for (i = 0; i < MAX_REPLY_QUEUES; i++) { - hpsa_msix_entries[i].vector = 0; - hpsa_msix_entries[i].entry = i; - } - /* Some boards advertise MSI but don't really support it */ if ((h->board_id == 0x40700E11) || (h->board_id == 0x40800E11) || (h->board_id == 0x40820E11) || (h->board_id == 0x40830E11)) goto default_int_mode; if (pci_find_capability(h->pdev, PCI_CAP_ID_MSIX)) { dev_info(&h->pdev->dev, "MSIX\n"); + + err = pci_msix_table_size(h->pdev); + if (err < ARRAY_SIZE(hpsa_msix_entries)) + goto default_int_mode; + + for (i = 0; i < ARRAY_SIZE(hpsa_msix_entries); i++) { + hpsa_msix_entries[i].vector = 0; + hpsa_msix_entries[i].entry = i; + } + err = pci_enable_msix(h->pdev, hpsa_msix_entries, - MAX_REPLY_QUEUES); + ARRAY_SIZE(hpsa_msix_entries)); if (!err) { for (i = 0; i < MAX_REPLY_QUEUES; i++) h->intr[i] = hpsa_msix_entries[i].vector; h->msix_vector = 1; return; } - if (err > 0) { - dev_warn(&h->pdev->dev, "only %d MSI-X vectors " - "available\n", err); - goto default_int_mode; - } else { - dev_warn(&h->pdev->dev, "MSI-X init failed %d\n", - err); - goto default_int_mode; - } + dev_warn(&h->pdev->dev, "MSI-X init failed %d\n", err); + goto default_int_mode; } if (pci_find_capability(h->pdev, PCI_CAP_ID_MSI)) { dev_info(&h->pdev->dev, "MSI\n"); -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 13/77] bna: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/brocade/bna/bnad.c | 34 -- 1 files changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index b78e69e..d41257c 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -2469,21 +2469,11 @@ bnad_enable_msix(struct bnad *bnad) if (bnad->msix_table) return; - bnad->msix_table = - kcalloc(bnad->msix_num, sizeof(struct msix_entry), GFP_KERNEL); - - if (!bnad->msix_table) + ret = pci_msix_table_size(bnad->pcidev); + if (ret < 0) goto intx_mode; - for (i = 0; i < bnad->msix_num; i++) - bnad->msix_table[i].entry = i; - - ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, bnad->msix_num); - if (ret > 0) { - /* Not enough MSI-X vectors. */ - pr_warn("BNA: %d MSI-X vectors allocated < %d requested\n", - ret, bnad->msix_num); - + if (ret < bnad->msix_num) { spin_lock_irqsave(&bnad->bna_lock, flags); /* ret = #of vectors that we got */ bnad_q_num_adjust(bnad, (ret - BNAD_MAILBOX_MSIX_VECTORS) / 2, @@ -2495,15 +2485,19 @@ bnad_enable_msix(struct bnad *bnad) if (bnad->msix_num > ret) goto intx_mode; + } - /* Try once more with adjusted numbers */ - /* If this fails, fall back to INTx */ - ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, - bnad->msix_num); - if (ret) - goto intx_mode; + bnad->msix_table = + kcalloc(bnad->msix_num, sizeof(struct msix_entry), GFP_KERNEL); + + if (!bnad->msix_table) + goto intx_mode; - } else if (ret < 0) + for (i = 0; i < bnad->msix_num; i++) + bnad->msix_table[i].entry = i; + + ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, bnad->msix_num); + if (ret) goto intx_mode; pci_intx(bnad->pcidev, 0); -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 69/77] tg3: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/broadcom/tg3.c | 24 +--- 1 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 12d961c..2e842ef3 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -11241,6 +11241,10 @@ static bool tg3_enable_msix(struct tg3 *tp) int i, rc; struct msix_entry msix_ent[TG3_IRQ_MAX_VECS]; + rc = pci_msix_table_size(tp->pdev); + if (rc < 0) + return false; + tp->txq_cnt = tp->txq_req; tp->rxq_cnt = tp->rxq_req; if (!tp->rxq_cnt) @@ -11256,6 +11260,14 @@ static bool tg3_enable_msix(struct tg3 *tp) tp->txq_cnt = 1; tp->irq_cnt = tg3_irq_count(tp); + if (tp->irq_cnt > rc) { + netdev_notice(tp->dev, "Requested %d MSI-Xs, available %d\n", + tp->irq_cnt, rc); + tp->irq_cnt = rc; + tp->rxq_cnt = max(rc - 1, 1); + if (tp->txq_cnt) + tp->txq_cnt = min(tp->rxq_cnt, tp->txq_max); + } for (i = 0; i < tp->irq_max; i++) { msix_ent[i].entry = i; @@ -11263,18 +11275,8 @@ static bool tg3_enable_msix(struct tg3 *tp) } rc = pci_enable_msix(tp->pdev, msix_ent, tp->irq_cnt); - if (rc < 0) { + if (rc) return false; - } else if (rc != 0) { - if (pci_enable_msix(tp->pdev, msix_ent, rc)) - return false; - netdev_notice(tp->dev, "Requested %d MSI-X vectors, received %d\n", - tp->irq_cnt, rc); - tp->irq_cnt = rc; - tp->rxq_cnt = max(rc - 1, 1); - if (tp->txq_cnt) - tp->txq_cnt = min(tp->rxq_cnt, tp->txq_max); - } for (i = 0; i < tp->irq_max; i++) tp->napi[i].irq_vec = msix_ent[i].vector; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 12/77] benet: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/emulex/benet/be_main.c | 38 ++ 1 files changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 3e2c834..84d560d 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2366,29 +2366,23 @@ static int be_msix_enable(struct be_adapter *adapter) else num_vec = adapter->cfg_num_qs; - for (i = 0; i < num_vec; i++) - adapter->msix_entries[i].entry = i; + status = pci_msix_table_size(adapter->pdev); + if (status < 0) + goto fail; - status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec); - if (status == 0) { - goto done; - } else if (status >= MIN_MSIX_VECTORS) { - num_vec = status; - status = pci_enable_msix(adapter->pdev, adapter->msix_entries, -num_vec); - if (!status) - goto done; - } else (status > 0) { + num_vec = min(num_vec, status); + if (num_vec < MIN_MSIX_VECTORS) { status = -ENOSPC; + goto fail; } - dev_warn(dev, "MSIx enable failed\n"); + for (i = 0; i < num_vec; i++) + adapter->msix_entries[i].entry = i; + + status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec); + if (status) + goto fail; - /* INTx is not supported in VFs, so fail probe if enable_msix fails */ - if (!be_physfn(adapter)) - return status; - return 0; -done: if (be_roce_supported(adapter) && num_vec > MIN_MSIX_VECTORS) { adapter->num_msix_roce_vec = num_vec / 2; dev_info(dev, "enabled %d MSI-x vector(s) for RoCE\n", @@ -2400,6 +2394,14 @@ done: dev_info(dev, "enabled %d MSI-x vector(s) for NIC\n", adapter->num_msix_vec); return 0; + +fail: + dev_warn(dev, "MSIx enable failed\n"); + + /* INTx is not supported in VFs, so fail probe if enable_msix fails */ + if (!be_physfn(adapter)) + return status; + return 0; } static inline int be_msix_vec_get(struct be_adapter *adapter, -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 37/77] ipr: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/scsi/ipr.c | 46 +++--- 1 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 762a93e..86ed0a2 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -9247,45 +9247,45 @@ static int ipr_enable_msix(struct ipr_ioa_cfg *ioa_cfg) struct msix_entry entries[IPR_MAX_MSIX_VECTORS]; int i, err, vectors; - for (i = 0; i < ARRAY_SIZE(entries); ++i) - entries[i].entry = i; + err = pci_msix_table_size(ioa_cfg->pdev); + if (err < 0) + return err; - vectors = ipr_number_of_msix; + vectors = min_t(int, err, ipr_number_of_msix); - while ((err = pci_enable_msix(ioa_cfg->pdev, entries, vectors)) > 0) - vectors = err; + BUG_ON(vectors > ARRAY_SIZE(entries)); + for (i = 0; i < vectors; ++i) + entries[i].entry = i; - if (err < 0) + err = pci_enable_msix(ioa_cfg->pdev, entries, vectors); + if (err) return err; - if (!err) { - for (i = 0; i < vectors; i++) - ioa_cfg->vectors_info[i].vec = entries[i].vector; - ioa_cfg->nvectors = vectors; - } + for (i = 0; i < vectors; i++) + ioa_cfg->vectors_info[i].vec = entries[i].vector; + ioa_cfg->nvectors = vectors; - return err; + return 0; } static int ipr_enable_msi(struct ipr_ioa_cfg *ioa_cfg) { int i, err, vectors; - vectors = ipr_number_of_msix; - - while ((err = pci_enable_msi_block(ioa_cfg->pdev, vectors)) > 0) - vectors = err; - + err = pci_get_msi_cap(ioa_cfg->pdev); if (err < 0) return err; - if (!err) { - for (i = 0; i < vectors; i++) - ioa_cfg->vectors_info[i].vec = ioa_cfg->pdev->irq + i; - ioa_cfg->nvectors = vectors; - } + vectors = min_t(int, err, ipr_number_of_msix); + err = pci_enable_msi_block(ioa_cfg->pdev, vectors); + if (err) + return err; + + for (i = 0; i < vectors; i++) + ioa_cfg->vectors_info[i].vec = ioa_cfg->pdev->irq + i; + ioa_cfg->nvectors = vectors; - return err; + return 0; } static void name_msi_vectors(struct ipr_ioa_cfg *ioa_cfg) -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 66/77] qlge: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/qlogic/qlge/qlge_main.c | 39 +++-- 1 files changed, 17 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index ac54cb0..d6fdd93 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -3258,45 +3258,40 @@ static void ql_enable_msix(struct ql_adapter *qdev) /* Get the MSIX vectors. */ if (qlge_irq_type == MSIX_IRQ) { + err = pci_msix_table_size(qdev->pdev); + if (err < 0) + goto msix_fail; + + qdev->intr_count = min_t(u32, qdev->intr_count, err); + /* Try to alloc space for the msix struct, * if it fails then go to MSI/legacy. */ qdev->msi_x_entry = kcalloc(qdev->intr_count, sizeof(struct msix_entry), GFP_KERNEL); - if (!qdev->msi_x_entry) { - qlge_irq_type = MSI_IRQ; - goto msi; - } + if (!qdev->msi_x_entry) + goto msix_fail; for (i = 0; i < qdev->intr_count; i++) qdev->msi_x_entry[i].entry = i; - /* Loop to get our vectors. We start with -* what we want and settle for what we get. -*/ - do { - err = pci_enable_msix(qdev->pdev, - qdev->msi_x_entry, qdev->intr_count); - if (err > 0) - qdev->intr_count = err; - } while (err > 0); - - if (err < 0) { - kfree(qdev->msi_x_entry); - qdev->msi_x_entry = NULL; - netif_warn(qdev, ifup, qdev->ndev, - "MSI-X Enable failed, trying MSI.\n"); - qlge_irq_type = MSI_IRQ; - } else if (err == 0) { + if (!pci_enable_msix(qdev->pdev, +qdev->msi_x_entry, qdev->intr_count)) { set_bit(QL_MSIX_ENABLED, &qdev->flags); netif_info(qdev, ifup, qdev->ndev, "MSI-X Enabled, got %d vectors.\n", qdev->intr_count); return; } + + kfree(qdev->msi_x_entry); + qdev->msi_x_entry = NULL; +msix_fail: + netif_warn(qdev, ifup, qdev->ndev, + "MSI-X Enable failed, trying MSI.\n"); + qlge_irq_type = MSI_IRQ; } -msi: qdev->intr_count = 1; if (qlge_irq_type == MSI_IRQ) { if (!pci_enable_msi(qdev->pdev)) { -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 09/77] ahci: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/ata/ahci.c | 56 --- 1 files changed, 35 insertions(+), 21 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 9d715ae..f1c8838 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1091,26 +1091,40 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) {} #endif -int ahci_init_interrupts(struct pci_dev *pdev, struct ahci_host_priv *hpriv) +int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, +struct ahci_host_priv *hpriv) { - int rc; - unsigned int maxvec; + int rc, nvec; - if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) { - rc = pci_enable_msi_block_auto(pdev, &maxvec); - if (rc > 0) { - if ((rc == maxvec) || (rc == 1)) - return rc; - /* -* Assume that advantage of multipe MSIs is negated, -* so fallback to single MSI mode to save resources -*/ - pci_disable_msi(pdev); - if (!pci_enable_msi(pdev)) - return 1; - } - } + if (hpriv->flags & AHCI_HFLAG_NO_MSI) + goto intx; + + rc = pci_get_msi_cap(pdev); + if (rc < 0) + goto intx; + + /* +* If number of MSIs is less than number of ports then Sharing Last +* Message mode could be enforced. In this case assume that advantage +* of multipe MSIs is negated and use single MSI mode instead. +*/ + if (rc < n_ports) + goto single_msi; + + nvec = rc; + rc = pci_enable_msi_block(pdev, nvec); + if (rc) + goto intx; + return nvec; + +single_msi: + rc = pci_enable_msi(pdev); + if (rc) + goto intx; + return 1; + +intx: pci_intx(pdev, 1); return 0; } @@ -1277,10 +1291,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar]; - n_msis = ahci_init_interrupts(pdev, hpriv); - if (n_msis > 1) - hpriv->flags |= AHCI_HFLAG_MULTI_MSI; - /* save initial config */ ahci_pci_save_initial_config(pdev, hpriv); @@ -1335,6 +1345,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) */ n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); + n_msis = ahci_init_interrupts(pdev, n_ports, hpriv); + if (n_msis > 1) + hpriv->flags |= AHCI_HFLAG_MULTI_MSI; + host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); if (!host) return -ENOMEM; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 55/77] ntb: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/ntb/ntb_hw.c | 41 + drivers/ntb/ntb_hw.h |2 -- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c index eccd5e5..7776429 100644 --- a/drivers/ntb/ntb_hw.c +++ b/drivers/ntb/ntb_hw.c @@ -1032,23 +1032,26 @@ static int ntb_setup_msix(struct ntb_device *ndev) struct msix_entry *msix; int msix_entries; int rc, i; - u16 val; - if (!pdev->msix_cap) { - rc = -EIO; + rc = pci_msix_table_size(pdev); + if (rc < 0) goto err; - } - rc = pci_read_config_word(pdev, pdev->msix_cap + PCI_MSIX_FLAGS, &val); - if (rc) + /* +* On SNB, the link interrupt is always tied to 4th vector. If +* we can't get all 4, then we can't use MSI-X. +*/ + if ((rc < SNB_MSIX_CNT) && (ndev->hw_type != BWD_HW)) { + rc = -ENOSPC; goto err; - - msix_entries = msix_table_size(val); - if (msix_entries > ndev->limits.msix_cnt) { + } + if (rc > ndev->limits.msix_cnt) { rc = -EINVAL; goto err; } + msix_entries = rc; + ndev->msix_entries = kmalloc(sizeof(struct msix_entry) * msix_entries, GFP_KERNEL); if (!ndev->msix_entries) { @@ -1060,26 +1063,8 @@ static int ntb_setup_msix(struct ntb_device *ndev) ndev->msix_entries[i].entry = i; rc = pci_enable_msix(pdev, ndev->msix_entries, msix_entries); - if (rc < 0) + if (rc) goto err1; - if (rc > 0) { - /* On SNB, the link interrupt is always tied to 4th vector. If -* we can't get all 4, then we can't use MSI-X. -*/ - if ((rc < SNB_MSIX_CNT) && (ndev->hw_type != BWD_HW)) { - rc = -EIO; - goto err1; - } - - dev_warn(&pdev->dev, -"Only %d MSI-X vectors. Limiting the number of queues to that number.\n", -rc); - msix_entries = rc; - - rc = pci_enable_msix(pdev, ndev->msix_entries, msix_entries); - if (rc) - goto err1; - } for (i = 0; i < msix_entries; i++) { msix = &ndev->msix_entries[i]; diff --git a/drivers/ntb/ntb_hw.h b/drivers/ntb/ntb_hw.h index 0a31ced..50bd760 100644 --- a/drivers/ntb/ntb_hw.h +++ b/drivers/ntb/ntb_hw.h @@ -60,8 +60,6 @@ #define PCI_DEVICE_ID_INTEL_NTB_SS_HSX 0x2F0F #define PCI_DEVICE_ID_INTEL_NTB_B2B_BWD0x0C4E -#define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) - #ifndef readq static inline u64 readq(void __iomem *addr) { -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 63/77] qlcnic: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 56 - 1 files changed, 32 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index b94e679..a137c14 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -590,7 +590,37 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED); if (adapter->ahw->msix_supported) { - enable_msix: + err = pci_msix_table_size(pdev); + if (err < 0) + goto fail; + + if (err < num_msix) { + dev_info(&pdev->dev, +"Unable to allocate %d MSI-X interrupt vectors\n", +num_msix); + if (qlcnic_83xx_check(adapter)) { + if (err < (QLC_83XX_MINIMUM_VECTOR - tx_vector)) + return -ENOSPC; + err -= (max_tx_rings + 1); + num_msix = rounddown_pow_of_two(err); + num_msix += (max_tx_rings + 1); + } else { + num_msix = rounddown_pow_of_two(err); + if (qlcnic_check_multi_tx(adapter)) + num_msix += max_tx_rings; + } + + if (!num_msix) { + err = -ENOSPC; + goto fail; + } + + dev_info(&pdev->dev, +"Trying to allocate %d MSI-X interrupt vectors\n", +num_msix); + } + } + for (i = 0; i < num_msix; i++) adapter->msix_entries[i].entry = i; err = pci_enable_msix(pdev, adapter->msix_entries, num_msix); @@ -613,30 +643,8 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) adapter->max_sds_rings = max_sds_rings; } dev_info(&pdev->dev, "using msi-x interrupts\n"); - } else if (err > 0) { - dev_info(&pdev->dev, -"Unable to allocate %d MSI-X interrupt vectors\n", -num_msix); - if (qlcnic_83xx_check(adapter)) { - if (err < (QLC_83XX_MINIMUM_VECTOR - tx_vector)) - return -ENOSPC; - err -= (max_tx_rings + 1); - num_msix = rounddown_pow_of_two(err); - num_msix += (max_tx_rings + 1); - } else { - num_msix = rounddown_pow_of_two(err); - if (qlcnic_check_multi_tx(adapter)) - num_msix += max_tx_rings; - } - - if (num_msix) { - dev_info(&pdev->dev, -"Trying to allocate %d MSI-X interrupt vectors\n", -num_msix); - goto enable_msix; - } - err = -ENOSPC; } else { +fail: dev_info(&pdev->dev, "Unable to allocate %d MSI-X interrupt vectors\n", num_msix); -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 29/77] cxgb4vf: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c| 49 1 files changed, 29 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 11cbce1..48bb33b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2437,13 +2437,10 @@ static void reduce_ethqs(struct adapter *adapter, int n) */ static int enable_msix(struct adapter *adapter) { - int i, err, want, need; + int i, err, want, need, nqsets; struct msix_entry entries[MSIX_ENTRIES]; struct sge *s = &adapter->sge; - for (i = 0; i < MSIX_ENTRIES; ++i) - entries[i].entry = i; - /* * We _want_ enough MSI-X interrupts to cover all of our "Queue Sets" * plus those needed for our "extras" (for example, the firmware @@ -2453,26 +2450,38 @@ static int enable_msix(struct adapter *adapter) */ want = s->max_ethqsets + MSIX_EXTRAS; need = adapter->params.nports + MSIX_EXTRAS; - while ((err = pci_enable_msix(adapter->pdev, entries, want)) >= need) - want = err; - if (err == 0) { - int nqsets = want - MSIX_EXTRAS; - if (nqsets < s->max_ethqsets) { - dev_warn(adapter->pdev_dev, "only enough MSI-X vectors" -" for %d Queue Sets\n", nqsets); - s->max_ethqsets = nqsets; - if (nqsets < s->ethqsets) - reduce_ethqs(adapter, nqsets); - } - for (i = 0; i < want; ++i) - adapter->msix_info[i].vec = entries[i].vector; - } else if (err > 0) { + err = pci_msix_table_size(adapter->pdev); + if (err < 0) + return err; + + want = min(want, err); + if (want < need) { dev_info(adapter->pdev_dev, "only %d MSI-X vectors left," " not using MSI-X\n", err); - err = -ENOSPC; + return -ENOSPC; } - return err; + + BUG_ON(want > ARRAY_SIZE(entries)); + for (i = 0; i < want; ++i) + entries[i].entry = i; + + err = pci_enable_msix(adapter->pdev, entries, want); + if (err) + return err; + + nqsets = want - MSIX_EXTRAS; + if (nqsets < s->max_ethqsets) { + dev_warn(adapter->pdev_dev, "only enough MSI-X vectors" +" for %d Queue Sets\n", nqsets); + s->max_ethqsets = nqsets; + if (nqsets < s->ethqsets) + reduce_ethqs(adapter, nqsets); + } + for (i = 0; i < want; ++i) + adapter->msix_info[i].vec = entries[i].vector; + + return 0; } static const struct net_device_ops cxgb4vf_netdev_ops = { -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 26/77] cxgb4: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 62 +-- 1 files changed, 35 insertions(+), 27 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 9425bc6..e5fbbd3 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -5699,9 +5699,6 @@ static int enable_msix(struct adapter *adap) unsigned int nchan = adap->params.nports; struct msix_entry entries[MAX_INGQ + 1]; - for (i = 0; i < ARRAY_SIZE(entries); ++i) - entries[i].entry = i; - want = s->max_ethqsets + EXTRA_VECS; if (is_offload(adap)) { want += s->rdmaqs + s->ofldqsets; @@ -5710,34 +5707,45 @@ static int enable_msix(struct adapter *adap) } need = adap->params.nports + EXTRA_VECS + ofld_need; - while ((err = pci_enable_msix(adap->pdev, entries, want)) >= need) - want = err; + err = pci_msix_table_size(adap->pdev); + if (err < 0) + return err; - if (!err) { - /* -* Distribute available vectors to the various queue groups. -* Every group gets its minimum requirement and NIC gets top -* priority for leftovers. -*/ - i = want - EXTRA_VECS - ofld_need; - if (i < s->max_ethqsets) { - s->max_ethqsets = i; - if (i < s->ethqsets) - reduce_ethqs(adap, i); - } - if (is_offload(adap)) { - i = want - EXTRA_VECS - s->max_ethqsets; - i -= ofld_need - nchan; - s->ofldqsets = (i / nchan) * nchan; /* round down */ - } - for (i = 0; i < want; ++i) - adap->msix_info[i].vec = entries[i].vector; - } else if (err > 0) { + want = min(want, err); + if (want < need) { dev_info(adap->pdev_dev, "only %d MSI-X vectors left, not using MSI-X\n", err); - err = -ENOSPC; + return -ENOSPC; } - return err; + + BUG_ON(want > ARRAY_SIZE(entries)); + for (i = 0; i < want; ++i) + entries[i].entry = i; + + err = pci_enable_msix(adap->pdev, entries, want); + if (err) + return err; + + /* +* Distribute available vectors to the various queue groups. +* Every group gets its minimum requirement and NIC gets top +* priority for leftovers. +*/ + i = want - EXTRA_VECS - ofld_need; + if (i < s->max_ethqsets) { + s->max_ethqsets = i; + if (i < s->ethqsets) + reduce_ethqs(adap, i); + } + if (is_offload(adap)) { + i = want - EXTRA_VECS - s->max_ethqsets; + i -= ofld_need - nchan; + s->ofldqsets = (i / nchan) * nchan; /* round down */ + } + for (i = 0; i < want; ++i) + adap->msix_info[i].vec = entries[i].vector; + + return 0; } #undef EXTRA_VECS -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 05/77] PCI/MSI: Convert pci_msix_table_size() to a public interface
Make pci_msix_table_size() to return a error code if the device does not support MSI-X. This update is needed to facilitate a forthcoming re-design MSI/MSI-X interrupts enabling pattern. Device drivers will use this interface to obtain maximum number of MSI-X interrupts the device supports and use that value in the following call to pci_enable_msix() interface. Signed-off-by: Alexander Gordeev --- Documentation/PCI/MSI-HOWTO.txt | 13 + drivers/pci/msi.c |5 - drivers/pci/pcie/portdrv_core.c |2 ++ 3 files changed, 19 insertions(+), 1 deletions(-) diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index a091780..35b2d64 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt @@ -255,6 +255,19 @@ MSI-X Table. This address is mapped by the PCI subsystem, and should not be accessed directly by the device driver. If the driver wishes to mask or unmask an interrupt, it should call disable_irq() / enable_irq(). +4.3.4 pci_msix_table_size + +int pci_msix_table_size(struct pci_dev *dev) + +This function could be used to retrieve number of entries in the device +MSI-X table. + +If this function returns a negative number, it indicates the device is +not capable of sending MSI-Xs. + +If this function returns a positive number, it indicates the maximum +number of MSI-X interrupt vectors that could be allocated. + 4.4 Handling devices implementing both MSI and MSI-X capabilities If a device implements both MSI and MSI-X capabilities, it can diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index b43f391..875c353 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -928,11 +928,12 @@ int pci_msix_table_size(struct pci_dev *dev) u16 control; if (!dev->msix_cap) - return 0; + return -EINVAL; pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); return msix_table_size(control); } +EXPORT_SYMBOL(pci_msix_table_size); /** * pci_enable_msix - configure device's MSI-X capability structure @@ -962,6 +963,8 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) return status; nr_entries = pci_msix_table_size(dev); + if (nr_entries < 0) + return nr_entries; if (nvec > nr_entries) return nr_entries; diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 31063ac..b4d86eb 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -80,6 +80,8 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) u32 reg32; nr_entries = pci_msix_table_size(dev); + if (nr_entries < 0) + return nr_entries; if (!nr_entries) return -EINVAL; if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES) -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 75/77] vmxnet3: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/vmxnet3/vmxnet3_drv.c | 68 ++--- 1 files changed, 33 insertions(+), 35 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 00dc0d0..8d3321b 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2724,49 +2724,47 @@ vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac) #ifdef CONFIG_PCI_MSI -/* - * Enable MSIx vectors. - * Returns : - * 0 on successful enabling of required vectors, - * VMXNET3_LINUX_MIN_MSIX_VECT when only minimum number of vectors required - * could be enabled. - * number of vectors which can be enabled otherwise (this number is smaller - * than VMXNET3_LINUX_MIN_MSIX_VECT) - */ - static int vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, int vectors) { - int err = -EINVAL, vector_threshold; + int err, vector_threshold; + vector_threshold = VMXNET3_LINUX_MIN_MSIX_VECT; + if (vectors < vector_threshold) + return -EINVAL; - while (vectors >= vector_threshold) { - err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries, - vectors); - if (!err) { - adapter->intr.num_intrs = vectors; - return 0; - } else if (err < 0) { - dev_err(&adapter->netdev->dev, - "Failed to enable MSI-X, error: %d\n", err); - return err; - } else if (err < vector_threshold) { - dev_info(&adapter->pdev->dev, -"Number of MSI-Xs which can be allocated " -"is lower than min threshold required.\n"); - return -ENOSPC; - } else { - /* If fails to enable required number of MSI-x vectors -* try enabling minimum number of vectors required. -*/ - dev_err(&adapter->netdev->dev, - "Failed to enable %d MSI-X, trying %d instead\n", - vectors, vector_threshold); - vectors = vector_threshold; - } + err = pci_msix_table_size(adapter->pdev); + if (err < 0) + goto err_msix; + if (err < vector_threshold) { + dev_info(&adapter->pdev->dev, +"Number of MSI-X interrupts which can be allocated " +"is lower than min threshold required.\n"); + return -ENOSPC; + } + if (err < vectors) { + /* +* If fails to enable required number of MSI-x vectors +* try enabling minimum number of vectors required. +*/ + dev_err(&adapter->netdev->dev, + "Failed to enable %d MSI-X, trying %d instead\n", + vectors, vector_threshold); + vectors = vector_threshold; } + err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries, + vectors); + if (err) + goto err_msix; + + adapter->intr.num_intrs = vectors; + return 0; + +err_msix: + dev_err(&adapter->netdev->dev, + "Failed to enable MSI-X, error: %d\n", err); return err; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 38/77] ixgbe: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c | 62 + 1 files changed, 32 insertions(+), 30 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index 90b4e10..2444a4d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -711,37 +711,39 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, * Right now, we simply care about how many we'll get; we'll * set them up later while requesting irq's. */ - while (vectors >= vector_threshold) { - err = pci_enable_msix(adapter->pdev, adapter->msix_entries, - vectors); - if (!err) /* Success in acquiring all requested vectors. */ - break; - else if (err < 0) - vectors = 0; /* Nasty failure, quit now */ - else /* err == number of vectors we should try again with */ - vectors = err; - } + err = pci_msix_table_size(adapter->pdev); + if (err < 0) + goto err_alloc_msix; - if (vectors < vector_threshold) { - /* Can't allocate enough MSI-X interrupts? Oh well. -* This just means we'll go with either a single MSI -* vector or fall back to legacy interrupts. -*/ - netif_printk(adapter, hw, KERN_DEBUG, adapter->netdev, -"Unable to allocate MSI-X interrupts\n"); - adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED; - kfree(adapter->msix_entries); - adapter->msix_entries = NULL; - } else { - adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */ - /* -* Adjust for only the vectors we'll use, which is minimum -* of max_msix_q_vectors + NON_Q_VECTORS, or the number of -* vectors we were allocated. -*/ - vectors -= NON_Q_VECTORS; - adapter->num_q_vectors = min(vectors, adapter->max_q_vectors); - } + vectors = min(vectors, err); + if (vectors < vector_threshold) + goto err_alloc_msix; + + err = pci_enable_msix(adapter->pdev, adapter->msix_entries, vectors); + if (err) + goto err_alloc_msix; + + adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */ + /* +* Adjust for only the vectors we'll use, which is minimum +* of max_msix_q_vectors + NON_Q_VECTORS, or the number of +* vectors we were allocated. +*/ + vectors -= NON_Q_VECTORS; + adapter->num_q_vectors = min(vectors, adapter->max_q_vectors); + + return; + +err_alloc_msix: + /* Can't allocate enough MSI-X interrupts? Oh well. +* This just means we'll go with either a single MSI +* vector or fall back to legacy interrupts. +*/ + netif_printk(adapter, hw, KERN_DEBUG, adapter->netdev, +"Unable to allocate MSI-X interrupts\n"); + adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED; + kfree(adapter->msix_entries); + adapter->msix_entries = NULL; } static void ixgbe_add_ring(struct ixgbe_ring *ring, -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 14/77] bnx2x: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 54 ++- 1 files changed, 23 insertions(+), 31 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 61726af..edf31d2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1564,7 +1564,7 @@ void bnx2x_free_irq(struct bnx2x *bp) int bnx2x_enable_msix(struct bnx2x *bp) { - int msix_vec = 0, i, rc; + int msix_vec = 0, nvec, i, rc; /* VFs don't have a default status block */ if (IS_PF(bp)) { @@ -1590,60 +1590,52 @@ int bnx2x_enable_msix(struct bnx2x *bp) msix_vec++; } + rc = pci_msix_table_size(bp->pdev); + if (rc < 0) + goto no_msix; + + nvec = min(msix_vec, rc); + if (nvec < BNX2X_MIN_MSIX_VEC_CNT(bp)) + nvec = 1; + DP(BNX2X_MSG_SP, "about to request enable msix with %d vectors\n", msix_vec); - rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], msix_vec); + rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], nvec); + if (rc) + goto no_msix; /* * reconfigure number of tx/rx queues according to available * MSI-X vectors */ - if (rc >= BNX2X_MIN_MSIX_VEC_CNT(bp)) { - /* how less vectors we will have? */ - int diff = msix_vec - rc; - - BNX2X_DEV_INFO("Trying to use less MSI-X vectors: %d\n", rc); + if (nvec == 1) { + bp->flags |= USING_SINGLE_MSIX_FLAG; - rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], rc); + bp->num_ethernet_queues = 1; + bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues; + } else if (nvec < msix_vec) { + /* how less vectors we will have? */ + int diff = msix_vec - nvec; - if (rc) { - BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc); - goto no_msix; - } /* * decrease number of queues by number of unallocated entries */ bp->num_ethernet_queues -= diff; bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues; + } + if (nvec != msix_vec) BNX2X_DEV_INFO("New queue configuration set: %d\n", bp->num_queues); - } else if (rc > 0) { - /* Get by with single vector */ - rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], 1); - if (rc) { - BNX2X_DEV_INFO("Single MSI-X is not attainable rc %d\n", - rc); - goto no_msix; - } - - BNX2X_DEV_INFO("Using single MSI-X vector\n"); - bp->flags |= USING_SINGLE_MSIX_FLAG; - - BNX2X_DEV_INFO("set number of queues to 1\n"); - bp->num_ethernet_queues = 1; - bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues; - } else if (rc < 0) { - BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc); - goto no_msix; - } bp->flags |= USING_MSIX_FLAG; return 0; no_msix: + BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc); + /* fall to INTx if not enough memory */ if (rc == -ENOMEM) bp->flags |= DISABLE_MSI_FLAG; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 06/77] PCI/MSI: Factor out pci_get_msi_cap() interface
This update is needed to facilitate a forthcoming re-design MSI/MSI-X interrupts enabling pattern. Device drivers will use this interface to obtain maximum number of MSI interrupts the device supports and use that value in the following call to pci_enable_msi_block() interface. Signed-off-by: Alexander Gordeev --- Documentation/PCI/MSI-HOWTO.txt | 15 +++ drivers/pci/msi.c | 33 + include/linux/pci.h |6 ++ 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index 35b2d64..1f37ce2 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt @@ -169,6 +169,21 @@ on any interrupt for which it previously called request_irq(). Failure to do so results in a BUG_ON(), leaving the device with MSI enabled and thus leaking its vector. +4.2.5 pci_get_msi_cap + +int pci_get_msi_cap(struct pci_dev *dev) + +This function could be used to retrieve the number of MSI vectors the +device requested (via the Multiple Message Capable register). The MSI +specification only allows the returned value to be a power of two, +up to a maximum of 2^5 (32). + +If this function returns a negative number, it indicates the device is +not capable of sending MSIs. + +If this function returns a positive number, it indicates the maximum +number of MSI interrupt vectors that could be allocated. + 4.3 Using MSI-X The MSI-X capability is much more flexible than the MSI capability. diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 875c353..ca59bfc 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -812,6 +812,21 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) return 0; } +int pci_get_msi_cap(struct pci_dev *dev) +{ + int ret; + u16 msgctl; + + if (!dev->msi_cap) + return -EINVAL; + + pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); + ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); + + return ret; +} +EXPORT_SYMBOL(pci_get_msi_cap); + /** * pci_enable_msi_block - configure device's MSI capability structure * @dev: device to configure @@ -828,13 +843,10 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) { int status, maxvec; - u16 msgctl; - if (!dev->msi_cap) - return -EINVAL; - - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); - maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); + maxvec = pci_get_msi_cap(dev); + if (maxvec < 0) + return maxvec; if (nvec > maxvec) return maxvec; @@ -859,13 +871,10 @@ EXPORT_SYMBOL(pci_enable_msi_block); int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec) { int ret, nvec; - u16 msgctl; - if (!dev->msi_cap) - return -EINVAL; - - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); - ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); + ret = pci_get_msi_cap(dev); + if (ret < 0) + return ret; if (maxvec) *maxvec = ret; diff --git a/include/linux/pci.h b/include/linux/pci.h index da172f9..2fa92ef 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1144,6 +1144,11 @@ struct msix_entry { #ifndef CONFIG_PCI_MSI +static inline int pci_get_msi_cap(struct pci_dev *dev) +{ + return -1; +} + static inline int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) { return -1; @@ -1185,6 +1190,7 @@ static inline int pci_msi_enabled(void) return 0; } #else +int pci_get_msi_cap(struct pci_dev *dev); int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec); void pci_msi_shutdown(struct pci_dev *dev); -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 64/77] qlcnic: Make MSI-X initialization routine bit more readable
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 112 +++--- 1 files changed, 56 insertions(+), 56 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index a137c14..8510457 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -568,7 +568,7 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) { struct pci_dev *pdev = adapter->pdev; int max_tx_rings, max_sds_rings, tx_vector; - int err = -EINVAL, i; + int err, i; if (adapter->flags & QLCNIC_TX_INTR_SHARED) { max_tx_rings = 0; @@ -589,68 +589,68 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) adapter->max_sds_rings = 1; adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED); - if (adapter->ahw->msix_supported) { - err = pci_msix_table_size(pdev); - if (err < 0) + if (!adapter->ahw->msix_supported) + return -EINVAL; + + err = pci_msix_table_size(pdev); + if (err < 0) + goto fail; + + if (err < num_msix) { + dev_info(&pdev->dev, +"Unable to allocate %d MSI-X interrupt vectors\n", +num_msix); + if (qlcnic_83xx_check(adapter)) { + if (err < (QLC_83XX_MINIMUM_VECTOR - tx_vector)) + return -ENOSPC; + err -= (max_tx_rings + 1); + num_msix = rounddown_pow_of_two(err); + num_msix += (max_tx_rings + 1); + } else { + num_msix = rounddown_pow_of_two(err); + if (qlcnic_check_multi_tx(adapter)) + num_msix += max_tx_rings; + } + + if (!num_msix) { + err = -ENOSPC; goto fail; + } - if (err < num_msix) { - dev_info(&pdev->dev, -"Unable to allocate %d MSI-X interrupt vectors\n", -num_msix); - if (qlcnic_83xx_check(adapter)) { - if (err < (QLC_83XX_MINIMUM_VECTOR - tx_vector)) - return -ENOSPC; - err -= (max_tx_rings + 1); - num_msix = rounddown_pow_of_two(err); - num_msix += (max_tx_rings + 1); - } else { - num_msix = rounddown_pow_of_two(err); - if (qlcnic_check_multi_tx(adapter)) - num_msix += max_tx_rings; - } + dev_info(&pdev->dev, +"Trying to allocate %d MSI-X interrupt vectors\n", +num_msix); + } - if (!num_msix) { - err = -ENOSPC; - goto fail; - } + for (i = 0; i < num_msix; i++) + adapter->msix_entries[i].entry = i; - dev_info(&pdev->dev, -"Trying to allocate %d MSI-X interrupt vectors\n", -num_msix); - } - } + err = pci_enable_msix(pdev, adapter->msix_entries, num_msix); + if (err) + goto fail; - for (i = 0; i < num_msix; i++) - adapter->msix_entries[i].entry = i; - err = pci_enable_msix(pdev, adapter->msix_entries, num_msix); - if (err == 0) { - adapter->flags |= QLCNIC_MSIX_ENABLED; - if (qlcnic_83xx_check(adapter)) { - adapter->ahw->num_msix = num_msix; - /* subtract mail box and tx ring vectors */ - adapter->max_sds_rings = num_msix - -max_tx_rings - 1; - } else { - adapter->ahw->num_msix = num_msix; - if (qlcnic_check_multi_tx(adapter) && - !adapter->ahw->diag_test && - (adapter->max_drv_tx_rings > 1)) - max_sds_rings = num_msix - max_tx_rings; - else - m
[PATCH RFC 08/77] PCI/MSI: Get rid of pci_enable_msi_block_auto() interface
As result of recent re-design of MSI/MSI-X interrupts enabling pattern pci_enable_msi_block_auto() interface became obsolete. To enable maximum number of MSI interrupts for a device the driver will first obtain that number from pci_get_msi_cap() function and then call pci_enable_msi_block() interface. Signed-off-by: Alexander Gordeev --- Documentation/PCI/MSI-HOWTO.txt | 30 ++ drivers/pci/msi.c | 20 include/linux/pci.h |7 --- 3 files changed, 2 insertions(+), 55 deletions(-) diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index 40abcfb..4d0525f 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt @@ -133,33 +133,7 @@ static int foo_driver_enable_msi(struct foo_adapter *adapter, int nvec) return rc; } -4.2.3 pci_enable_msi_block_auto - -int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *count) - -This variation on pci_enable_msi() call allows a device driver to request -the maximum possible number of MSIs. The MSI specification only allows -interrupts to be allocated in powers of two, up to a maximum of 2^5 (32). - -If this function returns a positive number, it indicates that it has -succeeded and the returned value is the number of allocated interrupts. In -this case, the function enables MSI on this device and updates dev->irq to -be the lowest of the new interrupts assigned to it. The other interrupts -assigned to the device are in the range dev->irq to dev->irq + returned -value - 1. - -If this function returns a negative number, it indicates an error and -the driver should not attempt to request any more MSI interrupts for -this device. - -If the device driver needs to know the number of interrupts the device -supports it can pass the pointer count where that number is stored. The -device driver must decide what action to take if pci_enable_msi_block_auto() -succeeds, but returns a value less than the number of interrupts supported. -If the device driver does not need to know the number of interrupts -supported, it can set the pointer count to NULL. - -4.2.4 pci_disable_msi +4.2.3 pci_disable_msi void pci_disable_msi(struct pci_dev *dev) @@ -175,7 +149,7 @@ on any interrupt for which it previously called request_irq(). Failure to do so results in a BUG_ON(), leaving the device with MSI enabled and thus leaking its vector. -4.2.5 pci_get_msi_cap +4.2.4 pci_get_msi_cap int pci_get_msi_cap(struct pci_dev *dev) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 583ace1..1934519 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -849,26 +849,6 @@ int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) } EXPORT_SYMBOL(pci_enable_msi_block); -int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec) -{ - int ret, nvec; - - ret = pci_get_msi_cap(dev); - if (ret < 0) - return ret; - - if (maxvec) - *maxvec = ret; - - nvec = ret; - ret = pci_enable_msi_block(dev, nvec); - if (ret) - return ret; - - return nvec; -} -EXPORT_SYMBOL(pci_enable_msi_block_auto); - void pci_msi_shutdown(struct pci_dev *dev) { struct msi_desc *desc; diff --git a/include/linux/pci.h b/include/linux/pci.h index 2fa92ef..13bf88d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1154,12 +1154,6 @@ static inline int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) return -1; } -static inline int -pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec) -{ - return -1; -} - static inline void pci_msi_shutdown(struct pci_dev *dev) { } static inline void pci_disable_msi(struct pci_dev *dev) @@ -1192,7 +1186,6 @@ static inline int pci_msi_enabled(void) #else int pci_get_msi_cap(struct pci_dev *dev); int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); -int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec); void pci_msi_shutdown(struct pci_dev *dev); void pci_disable_msi(struct pci_dev *dev); int pci_msix_table_size(struct pci_dev *dev); -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 00/77] Re-design MSI/MSI-X interrupts enablement pattern
This series is against "next" branch in Bjorn's repo: git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git Currently pci_enable_msi_block() and pci_enable_msix() interfaces return a error code in case of failure, 0 in case of success and a positive value which indicates the number of MSI-X/MSI interrupts that could have been allocated. The latter value should be passed to a repeated call to the interfaces until a failure or success: for (i = 0; i < FOO_DRIVER_MAXIMUM_NVEC; i++) adapter->msix_entries[i].entry = i; while (nvec >= FOO_DRIVER_MINIMUM_NVEC) { rc = pci_enable_msix(adapter->pdev, adapter->msix_entries, nvec); if (rc > 0) nvec = rc; else return rc; } return -ENOSPC; This technique proved to be confusing and error-prone. Vast share of device drivers simply fail to follow the described guidelines. This update converts pci_enable_msix() and pci_enable_msi_block() interfaces to canonical kernel functions and makes them return a error code in case of failure or 0 in case of success. As result, device drivers will cease to use the overcomplicated repeated fallbacks technique and resort to a straightforward pattern - determine the number of MSI/MSI-X interrupts required before calling pci_enable_msi_block() and pci_enable_msix() interfaces: rc = pci_msix_table_size(adapter->pdev); if (rc < 0) return rc; nvec = min(nvec, rc); if (nvec < FOO_DRIVER_MINIMUM_NVEC) { return -ENOSPC; for (i = 0; i < nvec; i++) adapter->msix_entries[i].entry = i; rc = pci_enable_msix(adapter->pdev, adapter->msix_entries, nvec); return rc; Device drivers will use their knowledge of underlying hardware to determine the number of MSI/MSI-X interrupts required. The simplest case would be requesting all available interrupts - to obtain that value device drivers will use pci_get_msi_cap() interface for MSI and pci_msix_table_size() for MSI-X. More complex cases would entail matching device capabilities to the system environment, i.e. limiting number of hardware queues (and hence associated MSI/MSI-X interrupts) to the number of online CPUs. Device drivers using MSI/MSI-X could be divided in three groups: - drivers that request a hardcoded number of interrupts; - drivers that request a number of interrupts using one call to pci_enable_msix() and then enable MSI/MSI-X using a follow-up to pci_enable_msix(); - drivers that fully follow the guidelines and repeatedly call pci_enable_msix() in a loop; This series converts to the new technique second and third groups. To simplify device drivers code review I tried to make as little changes as possible - the scope of this series is an introduction of the new technique rather than clean-up effort for all drivers affected. The testing was very limited - I ensured successful booting on all affected architectures except MIPS and operation of few devices with and without pci=nomsi kernel parameter. There is a ongoing discussion about impact of this update on PowerPC pSeries platform. I am going to incorporate the outcome of this discussion into the next version. Yet, the rest of the platforms and the vast majority of device drivers already can start getting initial reviews. Patches 5,6,8 - update of the generic MSI code Patch 7 - update of architectures affected Patches 9-77- bugfixes and updates of device drivers affected The tree could be found in "pci-next-msi-v1" branch in repo: https://github.com/a-gordeev/linux.git Alexander Gordeev (77): PCI/MSI: Fix return value when populate_msi_sysfs() failed PCI/MSI/PPC: Fix wrong RTAS error code reporting PCI/MSI/s390: Fix single MSI only check PCI/MSI/s390: Remove superfluous check of MSI type PCI/MSI: Convert pci_msix_table_size() to a public interface PCI/MSI: Factor out pci_get_msi_cap() interface PCI/MSI: Re-design MSI/MSI-X interrupts enablement pattern PCI/MSI: Get rid of pci_enable_msi_block_auto() interface ahci: Update MSI/MSI-X interrupts enablement code ahci: Check MRSM bit when multiple MSIs enabled benet: Return -ENOSPC when not enough MSI-Xs available benet: Update MSI/MSI-X interrupts enablement code bna: Update MSI/MSI-X interrupts enablement code bnx2x: Update MSI/MSI-X interrupts enablement code bnx2: Update MSI/MSI-X interrupts enablement code cciss: Update MSI/MSI-X interrupts enablement code cciss: Update a misleading comment on interrupt usage cciss: Fallback to single MSI mode in case MSI-X failed csiostor: Do not call pci_disable_msix() if pci_enable_msix() failed csiostor: Return -ENOSPC when not enough MSI-X vectors available csiostor: Update MSI/MSI-X inter
[PATCH RFC 33/77] ioat: Disable MSI-X in case request of IRQ failed
Signed-off-by: Alexander Gordeev --- drivers/dma/ioat/dma.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 5ff6fc1..acee3b2 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -937,6 +937,7 @@ msix: chan = ioat_chan_by_index(device, j); devm_free_irq(dev, msix->vector, chan); } + pci_disable_msix(pdev); goto msix_single_vector; } } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 20/77] csiostor: Return -ENOSPC when not enough MSI-X vectors available
Signed-off-by: Alexander Gordeev --- drivers/scsi/csiostor/csio_isr.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/csiostor/csio_isr.c b/drivers/scsi/csiostor/csio_isr.c index 91ba91d..abf20ab 100644 --- a/drivers/scsi/csiostor/csio_isr.c +++ b/drivers/scsi/csiostor/csio_isr.c @@ -533,7 +533,7 @@ csio_enable_msix(struct csio_hw *hw) csio_info(hw, "Not using MSI-X, remainder:%d\n", rv); kfree(entries); - return -ENOMEM; + return -ENOSPC; } /* Save off vectors */ -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 47/77] mlx5: Fix memory leak in case not enough MSI-X vectors available
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/mellanox/mlx5/core/main.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index b47739b..3573ba4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -142,6 +142,7 @@ retry: } mlx5_core_dbg(dev, "received %d MSI vectors out of %d requested\n", err, nvec); + kfree(table->msix_arr); return 0; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 72/77] vmxnet3: Fixup a weird loop exit
Signed-off-by: Alexander Gordeev --- drivers/net/vmxnet3/vmxnet3_drv.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 5b8ea71..3518173 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2750,7 +2750,7 @@ vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, } else if (err < 0) { dev_err(&adapter->netdev->dev, "Failed to enable MSI-X, error: %d\n", err); - vectors = 0; + return err; } else if (err < vector_threshold) { break; } else { -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 30/77] hpsa: Update a misleading comment on interrupt usage
Signed-off-by: Alexander Gordeev --- drivers/scsi/hpsa.c |6 +- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 891c86b..393c8db 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -4141,7 +4141,11 @@ static void hpsa_interrupt_mode(struct ctlr_info *h) } default_int_mode: #endif /* CONFIG_PCI_MSI */ - /* if we get here we're going to use the default interrupt mode */ + /* +* If we get here we're going to use either the +* default interrupt mode or single MSI mode +*/ + h->intr[h->intr_mode] = h->pdev->irq; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 54/77] ntb: Ensure number of MSIs on SNB is enough for the link interrupt
Signed-off-by: Alexander Gordeev --- drivers/ntb/ntb_hw.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c index de2062c..eccd5e5 100644 --- a/drivers/ntb/ntb_hw.c +++ b/drivers/ntb/ntb_hw.c @@ -1066,7 +1066,7 @@ static int ntb_setup_msix(struct ntb_device *ndev) /* On SNB, the link interrupt is always tied to 4th vector. If * we can't get all 4, then we can't use MSI-X. */ - if (ndev->hw_type != BWD_HW) { + if ((rc < SNB_MSIX_CNT) && (ndev->hw_type != BWD_HW)) { rc = -EIO; goto err1; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 19/77] csiostor: Do not call pci_disable_msix() if pci_enable_msix() failed
Signed-off-by: Alexander Gordeev --- drivers/scsi/csiostor/csio_isr.c |4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/csiostor/csio_isr.c b/drivers/scsi/csiostor/csio_isr.c index 7ee9777..91ba91d 100644 --- a/drivers/scsi/csiostor/csio_isr.c +++ b/drivers/scsi/csiostor/csio_isr.c @@ -529,10 +529,8 @@ csio_enable_msix(struct csio_hw *hw) csio_reduce_sqsets(hw, cnt - extra); } } else { - if (rv > 0) { - pci_disable_msix(hw->pdev); + if (rv > 0) csio_info(hw, "Not using MSI-X, remainder:%d\n", rv); - } kfree(entries); return -ENOMEM; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 23/77] cxgb3: Return -ENOSPC when not enough MSI-X vectors available
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 9bd3099..915729c 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -3099,7 +3099,7 @@ static int cxgb_enable_msix(struct adapter *adap) if (!err && vectors < (adap->params.nports + 1)) { pci_disable_msix(adap->pdev); - err = -1; + err = -ENOSPC; } if (!err) { -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 02/77] PCI/MSI/PPC: Fix wrong RTAS error code reporting
Signed-off-by: Alexander Gordeev --- arch/powerpc/platforms/pseries/msi.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 6d2f0ab..009ec73 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -467,7 +467,7 @@ again: list_for_each_entry(entry, &pdev->msi_list, list) { hwirq = rtas_query_irq_number(pdn, i++); if (hwirq < 0) { - pr_debug("rtas_msi: error (%d) getting hwirq\n", rc); + pr_debug("rtas_msi: error (%d) getting hwirq\n", hwirq); return hwirq; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 36/77] ipr: Enable MSI-X when IPR_USE_MSIX type is set, not IPR_USE_MSI
Signed-off-by: Alexander Gordeev --- drivers/scsi/ipr.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index fb57e21..762a93e 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -9527,7 +9527,7 @@ static int ipr_probe_ioa(struct pci_dev *pdev, ipr_number_of_msix = IPR_MAX_MSIX_VECTORS; } - if (ioa_cfg->ipr_chip->intr_type == IPR_USE_MSI && + if (ioa_cfg->ipr_chip->intr_type == IPR_USE_MSIX && ipr_enable_msix(ioa_cfg) == 0) ioa_cfg->intr_flag = IPR_USE_MSIX; else if (ioa_cfg->ipr_chip->intr_type == IPR_USE_MSI && -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 71/77] vmxnet3: Return -EINVAL if number of requested MSI-Xs is not enough
Signed-off-by: Alexander Gordeev --- drivers/net/vmxnet3/vmxnet3_drv.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 7e2788c..5b8ea71 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2738,7 +2738,7 @@ static int vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, int vectors) { - int err = 0, vector_threshold; + int err = -EINVAL, vector_threshold; vector_threshold = VMXNET3_LINUX_MIN_MSIX_VECT; while (vectors >= vector_threshold) { -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 17/77] cciss: Update a misleading comment on interrupt usage
Signed-off-by: Alexander Gordeev --- drivers/block/cciss.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 80068a0..bf11540 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4103,7 +4103,10 @@ static void cciss_interrupt_mode(ctlr_info_t *h) } default_int_mode: #endif /* CONFIG_PCI_MSI */ - /* if we get here we're going to use the default interrupt mode */ + /* +* If we get here we're going to use either the +* default interrupt mode or single MSI mode +*/ h->intr[h->intr_mode] = h->pdev->irq; return; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 28/77] cxgb4vf: Return -ENOSPC when not enough MSI-X vectors available
Signed-off-by: Alexander Gordeev --- .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c|1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 87a82fc..11cbce1 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2470,6 +2470,7 @@ static int enable_msix(struct adapter *adapter) } else if (err > 0) { dev_info(adapter->pdev_dev, "only %d MSI-X vectors left," " not using MSI-X\n", err); + err = -ENOSPC; } return err; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 39/77] ixgbevf: Return -ENOSPC when not enough MSI-X vectors available
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 59a62bb..fa0537a 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -1773,7 +1773,7 @@ static int ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter, } if (vectors < vector_threshold) - err = -ENOMEM; + err = -ENOSPC; if (err) { dev_err(&adapter->pdev->dev, -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 61/77] qlogic: Return -EINVAL in case MSI-X is not supported
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index c6018bb..ff6a78b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -568,7 +568,7 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) { struct pci_dev *pdev = adapter->pdev; int max_tx_rings, max_sds_rings, tx_vector; - int err = -1, i; + int err = -EINVAL, i; if (adapter->flags & QLCNIC_TX_INTR_SHARED) { max_tx_rings = 0; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 65/77] qlge: Remove a redundant assignment
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/qlogic/qlge/qlge_main.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 2553cf4..ac54cb0 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -3287,7 +3287,6 @@ static void ql_enable_msix(struct ql_adapter *qdev) qdev->msi_x_entry = NULL; netif_warn(qdev, ifup, qdev->ndev, "MSI-X Enable failed, trying MSI.\n"); - qdev->intr_count = 1; qlge_irq_type = MSI_IRQ; } else if (err == 0) { set_bit(QL_MSIX_ENABLED, &qdev->flags); -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 04/77] PCI/MSI/s390: Remove superfluous check of MSI type
arch_setup_msi_irqs() hook can only be called from the generic MSI code which ensures correct MSI type parameter. Signed-off-by: Alexander Gordeev --- arch/s390/pci/pci.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index c79c6e4..61a3c2c 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -425,8 +425,6 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) int rc; pr_debug("%s: requesting %d MSI-X interrupts...", __func__, nvec); - if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI) - return -EINVAL; if (type == PCI_CAP_ID_MSI && nvec > 1) return 1; msi_vecs = min(nvec, ZPCI_MSI_VEC_MAX); -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 62/77] qlcnic: Remove redundant return operator
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index ff6a78b..b94e679 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -613,7 +613,6 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) adapter->max_sds_rings = max_sds_rings; } dev_info(&pdev->dev, "using msi-x interrupts\n"); - return err; } else if (err > 0) { dev_info(&pdev->dev, "Unable to allocate %d MSI-X interrupt vectors\n", -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 25/77] cxgb4: Return -ENOSPC when not enough MSI-X vectors available
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index c73cabd..9425bc6 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -5732,9 +5732,11 @@ static int enable_msix(struct adapter *adap) } for (i = 0; i < want; ++i) adap->msix_info[i].vec = entries[i].vector; - } else if (err > 0) + } else if (err > 0) { dev_info(adap->pdev_dev, "only %d MSI-X vectors left, not using MSI-X\n", err); + err = -ENOSPC; + } return err; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 22/77] cxgb3: Do not call pci_disable_msix() if pci_enable_msix() failed
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c |3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index b650951..9bd3099 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -3097,9 +3097,6 @@ static int cxgb_enable_msix(struct adapter *adap) while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0) vectors = err; - if (err < 0) - pci_disable_msix(adap->pdev); - if (!err && vectors < (adap->params.nports + 1)) { pci_disable_msix(adap->pdev); err = -1; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 27/77] cxgb4vf: Do not call pci_disable_msix() if pci_enable_msix() failed
Signed-off-by: Alexander Gordeev --- .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c|1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 40c22e7..87a82fc 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2468,7 +2468,6 @@ static int enable_msix(struct adapter *adapter) for (i = 0; i < want; ++i) adapter->msix_info[i].vec = entries[i].vector; } else if (err > 0) { - pci_disable_msix(adapter->pdev); dev_info(adapter->pdev_dev, "only %d MSI-X vectors left," " not using MSI-X\n", err); } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 03/77] PCI/MSI/s390: Fix single MSI only check
Multiple MSIs have never been supported on s390 architecture, but the platform code fails to report single MSI only. Signed-off-by: Alexander Gordeev --- arch/s390/pci/pci.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index f17a834..c79c6e4 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -427,6 +427,8 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) pr_debug("%s: requesting %d MSI-X interrupts...", __func__, nvec); if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI) return -EINVAL; + if (type == PCI_CAP_ID_MSI && nvec > 1) + return 1; msi_vecs = min(nvec, ZPCI_MSI_VEC_MAX); msi_vecs = min_t(unsigned int, msi_vecs, CONFIG_PCI_NR_MSI); -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 49/77] mlx5: Fix minimum number of MSI-Xs
The minimum number of MSI-Xs is (MLX5_EQ_VEC_COMP_BASE + 1) in one check and 2 in another check. Make the checks consistent and assume the minimum number is (MLX5_EQ_VEC_COMP_BASE + 1). Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/mellanox/mlx5/core/main.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 5e5c9a3..adf0e5d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -136,7 +136,7 @@ retry: err = pci_enable_msix(dev->pdev, table->msix_arr, nvec); if (err <= 0) { return err; - } else if (err > 2) { + } else if (err > MLX5_EQ_VEC_COMP_BASE) { nvec = err; goto retry; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 43/77] lpfc: Return -ENOSPC when not enough MSI-X vectors available
Signed-off-by: Alexander Gordeev --- drivers/scsi/lpfc/lpfc_init.c | 10 +++--- 1 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d83a1a3..0ec8008 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -8645,9 +8645,13 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) goto msg_fail_out; vectors = min(vectors, rc); - if (vectors > 1) - rc = pci_enable_msix(phba->pcidev, phba->sli4_hba.msix_entries, -vectors); + if (vectors < 2) { + rc = -ENOSPC; + goto msg_fail_out; + } + + rc = pci_enable_msix(phba->pcidev, phba->sli4_hba.msix_entries, +vectors); if (rc) { msg_fail_out: lpfc_printf_log(phba, KERN_INFO, LOG_INIT, -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 53/77] ntb: Fix missed call to pci_enable_msix()
Current MSI-X enablement code assumes MSI-Xs were successfully allocated in case less than requested vectors were available. That assumption is wrong, since MSI-Xs should be enabled with a repeated call to pci_enable_msix(). This update fixes this. Signed-off-by: Alexander Gordeev --- drivers/ntb/ntb_hw.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c index 1cb6e51..de2062c 100644 --- a/drivers/ntb/ntb_hw.c +++ b/drivers/ntb/ntb_hw.c @@ -1075,6 +1075,10 @@ static int ntb_setup_msix(struct ntb_device *ndev) "Only %d MSI-X vectors. Limiting the number of queues to that number.\n", rc); msix_entries = rc; + + rc = pci_enable_msix(pdev, ndev->msix_entries, msix_entries); + if (rc) + goto err1; } for (i = 0; i < msix_entries; i++) { -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 35/77] ipr: Do not call pci_disable_msi/msix() if pci_enable_msi/msix() failed
Signed-off-by: Alexander Gordeev --- drivers/scsi/ipr.c |8 ++-- 1 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 36ac1c3..fb57e21 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -9255,10 +9255,8 @@ static int ipr_enable_msix(struct ipr_ioa_cfg *ioa_cfg) while ((err = pci_enable_msix(ioa_cfg->pdev, entries, vectors)) > 0) vectors = err; - if (err < 0) { - pci_disable_msix(ioa_cfg->pdev); + if (err < 0) return err; - } if (!err) { for (i = 0; i < vectors; i++) @@ -9278,10 +9276,8 @@ static int ipr_enable_msi(struct ipr_ioa_cfg *ioa_cfg) while ((err = pci_enable_msi_block(ioa_cfg->pdev, vectors)) > 0) vectors = err; - if (err < 0) { - pci_disable_msi(ioa_cfg->pdev); + if (err < 0) return err; - } if (!err) { for (i = 0; i < vectors; i++) -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 32/77] hpsa: Fallback to single MSI mode in case MSI-X failed
Signed-off-by: Alexander Gordeev --- drivers/scsi/hpsa.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index eb17b3d..252b65d 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -4112,7 +4112,7 @@ static void hpsa_interrupt_mode(struct ctlr_info *h) err = pci_msix_table_size(h->pdev); if (err < ARRAY_SIZE(hpsa_msix_entries)) - goto default_int_mode; + goto single_msi_mode; for (i = 0; i < ARRAY_SIZE(hpsa_msix_entries); i++) { hpsa_msix_entries[i].vector = 0; @@ -4128,8 +4128,9 @@ static void hpsa_interrupt_mode(struct ctlr_info *h) return; } dev_warn(&h->pdev->dev, "MSI-X init failed %d\n", err); - goto default_int_mode; + goto single_msi_mode; } +single_msi_mode: if (pci_find_capability(h->pdev, PCI_CAP_ID_MSI)) { dev_info(&h->pdev->dev, "MSI\n"); if (!pci_enable_msi(h->pdev)) -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 76/77] vxge: Sanitize MSI-X allocation routine error codes
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/neterion/vxge/vxge-main.c |6 ++ 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index 5a20eaf..b81ff8b 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c @@ -2352,7 +2352,7 @@ start: "%s: MSI-X enable failed for %d vectors, ret: %d", VXGE_DRIVER_NAME, vdev->intr_cnt, ret); if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3)) { - ret = -ENODEV; + ret = -ENOSPC; goto enable_msix_failed; } @@ -2365,10 +2365,8 @@ start: vxge_close_vpaths(vdev, temp); vdev->no_of_vpath = temp; goto start; - } else if (ret < 0) { - ret = -ENODEV; + } else if (ret < 0) goto enable_msix_failed; - } return 0; enable_msix_failed: -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 48/77] mlx5: Return -ENOSPC when not enough MSI-X vectors available
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/mellanox/mlx5/core/main.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 3573ba4..5e5c9a3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -122,7 +122,7 @@ static int mlx5_enable_msix(struct mlx5_core_dev *dev) nvec = dev->caps.num_ports * num_online_cpus() + MLX5_EQ_VEC_COMP_BASE; nvec = min_t(int, nvec, num_eqs); if (nvec <= MLX5_EQ_VEC_COMP_BASE) - return -ENOMEM; + return -ENOSPC; table->msix_arr = kzalloc(nvec * sizeof(*table->msix_arr), GFP_KERNEL); if (!table->msix_arr) @@ -144,7 +144,7 @@ retry: mlx5_core_dbg(dev, "received %d MSI vectors out of %d requested\n", err, nvec); kfree(table->msix_arr); - return 0; + return -ENOSPC; } static void mlx5_disable_msix(struct mlx5_core_dev *dev) -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 18/77] cciss: Fallback to single MSI mode in case MSI-X failed
Signed-off-by: Alexander Gordeev --- drivers/block/cciss.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index bf11540..0eea035 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4081,7 +4081,7 @@ static void cciss_interrupt_mode(ctlr_info_t *h) if (pci_find_capability(h->pdev, PCI_CAP_ID_MSIX)) { err = pci_msix_table_size(h->pdev); if (err < ARRAY_SIZE(cciss_msix_entries)) - goto default_int_mode; + goto single_msi_mode; err = pci_enable_msix(h->pdev, cciss_msix_entries, ARRAY_SIZE(cciss_msix_entries)); if (!err) { @@ -4093,8 +4093,8 @@ static void cciss_interrupt_mode(ctlr_info_t *h) return; } dev_warn(&h->pdev->dev, "MSI-X init failed %d\n", err); - goto default_int_mode; } +single_msi_mode: if (pci_find_capability(h->pdev, PCI_CAP_ID_MSI)) { if (!pci_enable_msi(h->pdev)) h->msi_vector = 1; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 73/77] vmxnet3: Return -ENOSPC when not enough MSI-X vectors available
Signed-off-by: Alexander Gordeev --- drivers/net/vmxnet3/vmxnet3_drv.c |8 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 3518173..3df7f32 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2752,7 +2752,10 @@ vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, "Failed to enable MSI-X, error: %d\n", err); return err; } else if (err < vector_threshold) { - break; + dev_info(&adapter->pdev->dev, +"Number of MSI-Xs which can be allocated " +"is lower than min threshold required.\n"); + return -ENOSPC; } else { /* If fails to enable required number of MSI-x vectors * try enabling minimum number of vectors required. @@ -2764,9 +2767,6 @@ vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, } } - dev_info(&adapter->pdev->dev, -"Number of MSI-X interrupts which can be allocated " -"is lower than min threshold required.\n"); return err; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 60/77] qlcnic: Return -ENOSPC when not enough MSI-X vectors available
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index c4c5023..c6018bb 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -620,7 +620,7 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) num_msix); if (qlcnic_83xx_check(adapter)) { if (err < (QLC_83XX_MINIMUM_VECTOR - tx_vector)) - return err; + return -ENOSPC; err -= (max_tx_rings + 1); num_msix = rounddown_pow_of_two(err); num_msix += (max_tx_rings + 1); @@ -636,6 +636,7 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) num_msix); goto enable_msix; } + err = -ENOSPC; } else { dev_info(&pdev->dev, "Unable to allocate %d MSI-X interrupt vectors\n", -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 41/77] lpfc: Do not call pci_disable_msix() if pci_enable_msix() failed
Signed-off-by: Alexander Gordeev --- drivers/scsi/lpfc/lpfc_init.c |9 ++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 647f5bf..0803b84 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -8080,7 +8080,7 @@ lpfc_sli_enable_msix(struct lpfc_hba *phba) if (rc) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0420 PCI enable MSI-X failed (%d)\n", rc); - goto msi_fail_out; + goto vec_fail_out; } for (i = 0; i < LPFC_MSIX_VECTORS; i++) lpfc_printf_log(phba, KERN_INFO, LOG_INIT, @@ -8158,6 +8158,8 @@ irq_fail_out: msi_fail_out: /* Unconfigure MSI-X capability structure */ pci_disable_msix(phba->pcidev); + +vec_fail_out: return rc; } @@ -8646,7 +8648,7 @@ enable_msix_vectors: } else if (rc) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0484 PCI enable MSI-X failed (%d)\n", rc); - goto msi_fail_out; + goto vec_fail_out; } /* Log MSI-X vector assignment */ @@ -8698,9 +8700,10 @@ cfg_fail_out: &phba->sli4_hba.fcp_eq_hdl[index]); } -msi_fail_out: /* Unconfigure MSI-X capability structure */ pci_disable_msix(phba->pcidev); + +vec_fail_out: return rc; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 74/77] vmxnet3: Limit number of rx queues to 1 if per-queue MSI-Xs failed
Signed-off-by: Alexander Gordeev --- drivers/net/vmxnet3/vmxnet3_drv.c | 16 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 3df7f32..00dc0d0 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2814,12 +2814,14 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) err = vmxnet3_acquire_msix_vectors(adapter, adapter->intr.num_intrs); - /* If we cannot allocate one MSIx vector per queue -* then limit the number of rx queues to 1 -*/ - if (err == VMXNET3_LINUX_MIN_MSIX_VECT) { - if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE - || adapter->num_rx_queues != 1) { + if (!err) { + /* If we cannot allocate one MSIx vector per queue +* then limit the number of rx queues to 1 +*/ + if ((adapter->intr.num_intrs == +VMXNET3_LINUX_MIN_MSIX_VECT) && + ((adapter->share_intr != VMXNET3_INTR_BUDDYSHARE) || +(adapter->num_rx_queues != 1))) { adapter->share_intr = VMXNET3_INTR_TXSHARE; netdev_err(adapter->netdev, "Number of rx queues : 1\n"); @@ -2829,8 +2831,6 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) } return; } - if (!err) - return; /* If we cannot allocate MSIx vectors use only one rx queue */ dev_info(&adapter->pdev->dev, -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 44/77] lpfc: Make MSI-X initialization routine more readable
Signed-off-by: Alexander Gordeev --- drivers/scsi/lpfc/lpfc_init.c | 23 +++ 1 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 0ec8008..0cfaf20 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -8633,10 +8633,6 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) { int vectors, rc, index; - /* Set up MSI-X multi-message vectors */ - for (index = 0; index < phba->cfg_fcp_io_channel; index++) - phba->sli4_hba.msix_entries[index].entry = index; - /* Configure MSI-X capability structure */ vectors = phba->cfg_fcp_io_channel; @@ -8650,14 +8646,14 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) goto msg_fail_out; } + /* Set up MSI-X multi-message vectors */ + for (index = 0; index < vectors; index++) + phba->sli4_hba.msix_entries[index].entry = index; + rc = pci_enable_msix(phba->pcidev, phba->sli4_hba.msix_entries, vectors); - if (rc) { -msg_fail_out: - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0484 PCI enable MSI-X failed (%d)\n", rc); - goto vec_fail_out; - } + if (rc) + goto msg_fail_out; /* Log MSI-X vector assignment */ for (index = 0; index < vectors; index++) @@ -8697,7 +8693,7 @@ msg_fail_out: } lpfc_sli4_set_affinity(phba, vectors); - return rc; + return 0; cfg_fail_out: /* free the irq already requested */ @@ -8710,8 +8706,11 @@ cfg_fail_out: /* Unconfigure MSI-X capability structure */ pci_disable_msix(phba->pcidev); + return rc; -vec_fail_out: +msg_fail_out: + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "0484 PCI enable MSI-X failed (%d)\n", rc); return rc; } -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 07/77] PCI/MSI: Re-design MSI/MSI-X interrupts enablement pattern
Currently pci_enable_msi_block() and pci_enable_msix() interfaces return a error code in case of failure, 0 in case of success and a positive value which indicates the number of MSI-X/MSI interrupts that could have been allocated. The latter value should be passed to a repeated call to the interfaces until a failure or success. This technique proved to be confusing and error-prone. Vast share of device drivers simply fail to follow the described guidelines. This update converts pci_enable_msix() and pci_enable_msi_block() interfaces to canonical kernel functions and makes them return a error code in case of failure or 0 in case of success. As result, device drivers will cease to use the overcomplicated repeated fallbacks technique and resort to a straightforward pattern - determine the number of MSI/MSI-X interrupts required before calling pci_enable_msix() and pci_enable_msi_block() interfaces. Device drivers will use their knowledge of underlying hardware to determine the number of MSI/MSI-X interrupts required. The simplest case would be requesting all available interrupts - to obtain that value device drivers will use pci_get_msi_cap() interface for MSI and pci_msix_table_size() for MSI-X. More complex cases would entail matching device capabilities with the system environment, i.e. limiting number of hardware queues (and hence associated MSI/MSI-X interrupts) to the number of online CPUs. Suggested-by: Tejun Heo Signed-off-by: Alexander Gordeev --- Documentation/PCI/MSI-HOWTO.txt | 71 ++--- arch/mips/pci/msi-octeon.c |2 +- arch/powerpc/kernel/msi.c|2 +- arch/powerpc/platforms/pseries/msi.c |2 +- arch/s390/pci/pci.c |2 +- arch/x86/kernel/apic/io_apic.c |2 +- drivers/pci/msi.c| 52 +++-- 7 files changed, 58 insertions(+), 75 deletions(-) diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index 1f37ce2..40abcfb 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt @@ -111,21 +111,27 @@ the device are in the range dev->irq to dev->irq + count - 1. If this function returns a negative number, it indicates an error and the driver should not attempt to request any more MSI interrupts for -this device. If this function returns a positive number, it is -less than 'count' and indicates the number of interrupts that could have -been allocated. In neither case is the irq value updated or the device -switched into MSI mode. - -The device driver must decide what action to take if -pci_enable_msi_block() returns a value less than the number requested. -For instance, the driver could still make use of fewer interrupts; -in this case the driver should call pci_enable_msi_block() -again. Note that it is not guaranteed to succeed, even when the -'count' has been reduced to the value returned from a previous call to -pci_enable_msi_block(). This is because there are multiple constraints -on the number of vectors that can be allocated; pci_enable_msi_block() -returns as soon as it finds any constraint that doesn't allow the -call to succeed. +this device. + +Device drivers should normally call pci_get_msi_cap() function before +calling this function to determine maximum number of MSI interrupts +a device can send. + +A sequence to achieve that might look like: + +static int foo_driver_enable_msi(struct foo_adapter *adapter, int nvec) +{ + rc = pci_get_msi_cap(adapter->pdev); + if (rc < 0) + return rc; + + nvec = min(nvec, rc); + if (nvec < FOO_DRIVER_MINIMUM_NVEC) { + return -ENOSPC; + + rc = pci_enable_msi_block(adapter->pdev, nvec); + return rc; +} 4.2.3 pci_enable_msi_block_auto @@ -218,9 +224,7 @@ interrupts assigned to the MSI-X vectors so it can free them again later. If this function returns a negative number, it indicates an error and the driver should not attempt to allocate any more MSI-X interrupts for -this device. If it returns a positive number, it indicates the maximum -number of interrupt vectors that could have been allocated. See example -below. +this device. This function, in contrast with pci_enable_msi(), does not adjust dev->irq. The device will not generate interrupts for this interrupt @@ -229,24 +233,27 @@ number once MSI-X is enabled. Device drivers should normally call this function once per device during the initialization phase. -It is ideal if drivers can cope with a variable number of MSI-X interrupts; -there are many reasons why the platform may not be able to provide the -exact number that a driver asks for. +Device drivers should normally call pci_msix_table_size() function before +calling this function to determine maximum number of MSI-X interrupts +a device can send. -A request loop to achieve that might look like: +A sequence
[PATCH RFC 11/77] benet: Return -ENOSPC when not enough MSI-Xs available
Signed-off-by: Alexander Gordeev --- drivers/net/ethernet/emulex/benet/be_main.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 100b528..3e2c834 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2378,6 +2378,8 @@ static int be_msix_enable(struct be_adapter *adapter) num_vec); if (!status) goto done; + } else (status > 0) { + status = -ENOSPC; } dev_warn(dev, "MSIx enable failed\n"); -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 58/77] qib: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/infiniband/hw/qib/qib_pcie.c |4 1 files changed, 0 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c index 3f14009..9580903 100644 --- a/drivers/infiniband/hw/qib/qib_pcie.c +++ b/drivers/infiniband/hw/qib/qib_pcie.c @@ -218,10 +218,6 @@ static void qib_msix_setup(struct qib_devdata *dd, int pos, u32 *msixcnt, if (tabsize > *msixcnt) tabsize = *msixcnt; ret = pci_enable_msix(dd->pcidev, msix_entry, tabsize); - if (ret > 0) { - tabsize = ret; - ret = pci_enable_msix(dd->pcidev, msix_entry, tabsize); - } do_intx: if (ret) { qib_dev_err(dd, -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 34/77] ioat: Update MSI/MSI-X interrupts enablement code
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev --- drivers/dma/ioat/dma.c | 10 +++--- 1 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index acee3b2..b352ee6 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -915,15 +915,19 @@ int ioat_dma_setup_interrupts(struct ioatdma_device *device) msix: /* The number of MSI-X vectors should equal the number of channels */ + err = pci_msix_table_size(pdev); + if (err < 0) + goto msi; + if (err < device->common.chancnt) + goto msix_single_vector; + msixcnt = device->common.chancnt; for (i = 0; i < msixcnt; i++) device->msix_entries[i].entry = i; err = pci_enable_msix(pdev, device->msix_entries, msixcnt); - if (err < 0) + if (err) goto msi; - if (err > 0) - goto msix_single_vector; for (i = 0; i < msixcnt; i++) { msix = &device->msix_entries[i]; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH RFC 01/77] PCI/MSI: Fix return value when populate_msi_sysfs() failed
Signed-off-by: Alexander Gordeev --- drivers/pci/msi.c | 11 +-- 1 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index d5f90d6..b43f391 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -719,7 +719,7 @@ static int msix_capability_init(struct pci_dev *dev, ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX); if (ret) - goto error; + goto out_avail; /* * Some devices require MSI-X to be enabled before we can touch the @@ -732,10 +732,8 @@ static int msix_capability_init(struct pci_dev *dev, msix_program_entries(dev, entries); ret = populate_msi_sysfs(dev); - if (ret) { - ret = 0; - goto error; - } + if (ret) + goto out_free; /* Set MSI-X enabled bits and unmask the function */ pci_intx_for_msi(dev, 0); @@ -746,7 +744,7 @@ static int msix_capability_init(struct pci_dev *dev, return 0; -error: +out_avail: if (ret < 0) { /* * If we had some success, report the number of irqs @@ -763,6 +761,7 @@ error: ret = avail; } +out_free: free_msi_irqs(dev); return ret; -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH RFC 50/77] mlx5: Update MSI/MSI-X interrupts enablement code
On Thu, Oct 03, 2013 at 10:14:33AM +0300, Eli Cohen wrote: > On Wed, Oct 02, 2013 at 12:49:06PM +0200, Alexander Gordeev wrote: > > > > + err = pci_msix_table_size(dev->pdev); > > + if (err < 0) > > + return err; > > + > > nvec = dev->caps.num_ports * num_online_cpus() + MLX5_EQ_VEC_COMP_BASE; > > nvec = min_t(int, nvec, num_eqs); > > + nvec = min_t(int, nvec, err); > > if (nvec <= MLX5_EQ_VEC_COMP_BASE) > > return -ENOSPC; > > Making sure we don't request more vectors then the device's is capable > of -- looks good. > > > > @@ -131,20 +136,15 @@ static int mlx5_enable_msix(struct mlx5_core_dev *dev) > > for (i = 0; i < nvec; i++) > > table->msix_arr[i].entry = i; > > > > -retry: > > - table->num_comp_vectors = nvec - MLX5_EQ_VEC_COMP_BASE; > > err = pci_enable_msix(dev->pdev, table->msix_arr, nvec); > > - if (err <= 0) { > > + if (err) { > > + kfree(table->msix_arr); > > return err; > > - } else if (err > MLX5_EQ_VEC_COMP_BASE) { > > - nvec = err; > > - goto retry; > > } > > > > According to latest sources, pci_enable_msix() may still fail so why > do you want to remove this code? pci_enable_msix() may fail, but it can not return a positive number. We first calculate how many MSI-Xs we need, adjust to what we can get, check if that is enough and only then go for it. > > - mlx5_core_dbg(dev, "received %d MSI vectors out of %d requested\n", > > err, nvec); > > - kfree(table->msix_arr); > > + table->num_comp_vectors = nvec - MLX5_EQ_VEC_COMP_BASE; > > > > - return -ENOSPC; > > + return 0; > > } > > > > static void mlx5_disable_msix(struct mlx5_core_dev *dev) -- Regards, Alexander Gordeev agord...@redhat.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev