Re: [PATCH v2 2/6] PCI/MSI: Factor out pci_get_msi_cap() interface

2013-10-02 Thread Alexander Gordeev
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] Revert "powerpc: 52xx: provide a default in mpc52xx_irqhost_map()"

2013-10-02 Thread Sebastian Andrzej Siewior
On 10/01/2013 09:03 PM, Wolfram Sang wrote:
> 
> Yup. But I just remembered a better solution:
> 
> From: Wolfram Sang  Subject: [PATCH] ppc:
> mpc52xx: silence false positive from old GCC
> 
> So people can compile with -Werror.
> 
> Signed-off-by: Wolfram Sang  --- 
> arch/powerpc/platforms/52xx/mpc52xx_pic.c |2 +- 1 file changed,
> 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index b89ef65..2898b73
> 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++
> b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -340,7 +340,7 @@
> static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int
> virq, { int l1irq; int l2irq; -   struct irq_chip *irqchip; + struct
> irq_chip *uninitialized_var(irqchip); void *hndlr; int type; u32
> reg;
> 
> 
> uninitialized_var was created for exactly that purpose IIRC.

Yup, looks good, thanks.

> 
> Thanks,
> 
> Wolfram
> 

Sebastian
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/2] powerpc/tm: Remove interrupt disable in __switch_to()

2013-10-02 Thread Michael Neuling
We currently turn IRQs off in __switch_to(0 but this is unnecessary as it's
already disabled in the caller.

This removes the IRQ disable but adds a check to make sure it is really off
in case this changes in future.

Signed-off-by: Michael Neuling 
---
 arch/powerpc/kernel/process.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 96d2fdf..384c27e 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -596,12 +596,13 @@ struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *new)
 {
struct thread_struct *new_thread, *old_thread;
-   unsigned long flags;
struct task_struct *last;
 #ifdef CONFIG_PPC_BOOK3S_64
struct ppc64_tlb_batch *batch;
 #endif
 
+   WARN_ON(!irqs_disabled());
+
/* Back up the TAR across context switches.
 * Note that the TAR is not available for use in the kernel.  (To
 * provide this, the TAR should be backed up/restored on exception
@@ -721,8 +722,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
}
 #endif /* CONFIG_PPC_BOOK3S_64 */
 
-   local_irq_save(flags);
-
/*
 * We can't take a PMU exception inside _switch() since there is a
 * window where the kernel stack SLB and the kernel stack are out
@@ -742,8 +741,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
}
 #endif /* CONFIG_PPC_BOOK3S_64 */
 
-   local_irq_restore(flags);
-
return last;
 }
 
-- 
1.8.1.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/2] powerpc/tm: Turn interrupts hard off in tm_reclaim()

2013-10-02 Thread Michael Neuling
We can't take IRQs in tm_reclaim as we might have a bogus r13 and r1.

This turns IRQs hard off in this function.

Signed-off-by: Michael Neuling 
---
 arch/powerpc/kernel/tm.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S
index 7b60b98..8ece190 100644
--- a/arch/powerpc/kernel/tm.S
+++ b/arch/powerpc/kernel/tm.S
@@ -123,6 +123,7 @@ _GLOBAL(tm_reclaim)
mr  r15, r14
ori r15, r15, MSR_FP
li  r16, MSR_RI
+   ori r16, r16, MSR_EE /* IRQs hard off */
andcr15, r15, r16
orisr15, r15, MSR_VEC@h
 #ifdef CONFIG_VSX
-- 
1.8.1.2

___
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

2013-10-02 Thread Alexander Gordeev
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] powerpc/perf: Fix handling of FAB events

2013-10-02 Thread Michael Ellerman
Commit 4df4899 "Add power8 EBB support" included a bug in the handling
of the FAB_CRESP_MATCH and FAB_TYPE_MATCH fields.

These values are pulled out of the event code using EVENT_THR_CTL_SHIFT,
however we were then or'ing that value directly into MMCR1.

This meant we were failing to set the FAB fields correctly, and also
potentially corrupting the value for PMC4SEL. Leading to no counts for
the FAB events and incorrect counts for PMC4.

The fix is simply to shift left the FAB value correctly before or'ing it
with MMCR1.

Reported-by: Sooraj Ravindran Nair 
Signed-off-by: Michael Ellerman 
Cc:  # 3.10+
---
 arch/powerpc/perf/power8-pmu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Ben for 3.13 please.

diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 2ee4a70..a3f7abd 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -199,6 +199,7 @@
 #define MMCR1_UNIT_SHIFT(pmc)  (60 - (4 * ((pmc) - 1)))
 #define MMCR1_COMBINE_SHIFT(pmc)   (35 - ((pmc) - 1))
 #define MMCR1_PMCSEL_SHIFT(pmc)(24 - (((pmc) - 1)) * 8)
+#define MMCR1_FAB_SHIFT36
 #define MMCR1_DC_QUAL_SHIFT47
 #define MMCR1_IC_QUAL_SHIFT46
 
@@ -388,8 +389,8 @@ static int power8_compute_mmcr(u64 event[], int n_ev,
 * the threshold bits are used for the match value.
 */
if (event_is_fab_match(event[i])) {
-   mmcr1 |= (event[i] >> EVENT_THR_CTL_SHIFT) &
- EVENT_THR_CTL_MASK;
+   mmcr1 |= ((event[i] >> EVENT_THR_CTL_SHIFT) &
+ EVENT_THR_CTL_MASK) << MMCR1_FAB_SHIFT;
} else {
val = (event[i] >> EVENT_THR_CTL_SHIFT) & 
EVENT_THR_CTL_MASK;
mmcra |= val << MMCRA_THR_CTL_SHIFT;
-- 
1.8.1.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Paolo Bonzini
Il 01/10/2013 23:44, Benjamin Herrenschmidt ha scritto:
> On Tue, 2013-10-01 at 13:19 +0200, Paolo Bonzini wrote:
>> Il 01/10/2013 11:38, Benjamin Herrenschmidt ha scritto:
>>> So for the sake of that dogma you are going to make us do something that
>>> is about 100 times slower ? (and possibly involves more lines of code)
>>
>> If it's 100 times slower there is something else that's wrong.  It's
>> most likely not 100 times slower, and this makes me wonder if you or
>> Michael actually timed the code at all.
> 
> So no we haven't measured. But it is going to be VERY VERY VERY much
> slower. Our exit latencies are bad with our current MMU *and* any exit
> is going to cause all secondary threads on the core to have to exit as
> well (remember P7 is 4 threads, P8 is 8)

Ok, this is indeed the main difference between Power and x86.

>>   100 cyclesbare metal rdrand
>>   2000 cycles   guest->hypervisor->guest
>>   15000 cycles  guest->userspace->guest
>>
>> (100 cycles = 40 ns = 200 MB/sec; 2000 cycles = ~1 microseconds; 15000
>> cycles = ~7.5 microseconds).  Even on 5 year old hardware, a userspace
>> roundtrip is around a dozen microseconds.
> 
> So in your case going to qemu to "emulate" rdrand would indeed be 150
> times slower, I don't see in what universe that would be considered a
> good idea.

rdrand is not privileged on x86, guests can use it.  But my point is
that going to the kernel is already 20 times slower.  Getting entropy
(not just a pseudo-random number seeded by the HWRNG) with rdrand is
~1000 times slower according to Intel's recommendations, so the
roundtrip to userspace is entirely invisible in that case.

The numbers for PPC seem to be a bit different though (it's faster to
read entropy, and slower to do a userspace exit).

> It's a random number obtained from sampling a set of oscillators. It's
> slightly biased but we have very simple code (I believe shared with the
> host kernel implementation) for whitening it as is required by PAPR.

Good.  Actually, passing the dieharder tests does not mean much (an
AES-encrypted counter should also pass them with flashing colors), but
if it's specified by the architecture gods it's likely to have received
some scrutiny.

>> 2) If the hwrng returns entropy, a read from the hwrng is going to even
>> more expensive than an x86 rdrand (perhaps ~2000 cycles).
> 
> Depends how often you read, the HW I think is sampling asynchronously so
> you only block on the MMIO if you already consumed the previous sample
> but I'll let Paulus provide more details here.

Given Paul's description, there's indeed very little extra cost compared
to a "nop" hypercall.  That's nice.

Still, considering that QEMU code has to be there anyway for
compatibility, kernel emulation is not particularly necessary IMHO.  I
would of course like to see actual performance numbers, but besides that
are you ever going to ever see this in the profile except if you run "dd
if=/dev/hwrng of=/dev/null"?

Can you instrument pHyp to find out how many times per second is this
hypercall called by a "normal" Linux or AIX guest?

>> 3) If the hypercall returns random numbers, then it is a pretty
>> braindead interface since returning 8 bytes at a time limits the
>> throughput to a handful of MB/s (compare to 200 MB/sec for x86 rdrand).
>>  But more important: in this case drivers/char/hw_random/pseries-rng.c
>> is completely broken and insecure, just like patch 2 in case (1) above.
> 
> How so ?

Paul confirmed that it returns real entropy so this is moot.

Paolo
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Paolo Bonzini
Il 02/10/2013 07:09, Paul Mackerras ha scritto:
> On Tue, Oct 01, 2013 at 01:19:06PM +0200, Paolo Bonzini wrote:
> 
>> Anyhow, I would like to know more about this hwrng and hypercall.
>>
>> Does the hwrng return random numbers (like rdrand) or real entropy (like
>> rdseed that Intel will add in Broadwell)?  What about the hypercall?
> 
> Well, firstly, your terminology is inaccurate.  Real entropy will give
> you random numbers.  I think when you say "random numbers" you
> actually mean "pseudo-random numbers".

Yes---I meant pseudo-random numbers where the generator is periodically
seeded by a random number.

> Secondly, the RNG produces real entropy.

Good to know, thanks.

> Not sure why they are particularly "precious"; we get 64 bits per
> microsecond whether we use them or not.  What are you suggesting
> arch_get_random_long() should do instead?

If you are running rngd, there is no need to have arch_get_random_long()
at all.

>> 3) If the hypercall returns random numbers, then it is a pretty
>> braindead interface since returning 8 bytes at a time limits the
>> throughput to a handful of MB/s (compare to 200 MB/sec for x86 rdrand).
>>  But more important: in this case drivers/char/hw_random/pseries-rng.c
>> is completely broken and insecure, just like patch 2 in case (1) above.
> 
> Assuming that by "random numbers" you actually mean "pseudo-random
> numbers", then this doesn't apply.

Indeed.

>> 4) If the hypercall returns entropy (same as virtio-rng), the same
>> considerations on speed apply.  If you can only produce entropy at say 1
>> MB/s (so reading 8 bytes take 8 microseconds---which is actually very
>> fast), it doesn't matter that much to spend 7 microseconds on a
>> userspace roundtrip.  It's going to be only half the speed of bare
>> metal, not 100 times slower.
> 
> 8 bytes takes at most 1 microsecond, so the round-trip to userspace is
> definitely noticeable.

Thanks.  Any chance you can give some numbers of a kernel hypercall and
a userspace hypercall on Power, so we have actual data?  For example a
hypercall that returns H_PARAMETER as soon as possible.

Paolo
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: linux-next: build failure after merge of the akpm tree

2013-10-02 Thread Frederic Weisbecker
On Wed, Sep 25, 2013 at 02:43:28PM -0700, Andrew Morton wrote:
> On Wed, 25 Sep 2013 14:32:14 -0700 (PDT) Hugh Dickins  
> wrote:
> 
> > On Wed, 25 Sep 2013, Andrew Morton wrote:
> > > On Wed, 25 Sep 2013 11:06:43 +1000 Stephen Rothwell 
> > >  wrote:
> > > > Hi Andrew,
> > > > 
> > > > After merging the akpm tree, linux-next builds (powerpc allmodconfig)
> > > > fail like this:
> > > 
> > > I can't get powerpc to build at all at present:
> > > 
> > >   CHK include/config/kernel.release
> > >   CHK include/generated/uapi/linux/version.h
> > >   CHK include/generated/utsrelease.h
> > >   CC  arch/powerpc/kernel/asm-offsets.s
> > > In file included from include/linux/vtime.h:6,
> > >  from include/linux/hardirq.h:7,
> > >  from include/linux/memcontrol.h:24,
> > >  from include/linux/swap.h:8,
> > >  from include/linux/suspend.h:4,
> > >  from arch/powerpc/kernel/asm-offsets.c:24:
> > > arch/powerpc/include/generated/asm/vtime.h:1:31: error: 
> > > asm-generic/vtime.h: No such file or directory
> > 
> > That caught me too: include/asm-generic/vtime.h is a patch-unfriendly
> > 0-length file in the git tree;
> 
> hm, this?
> 
> 
> From: Andrew Morton 
> Subject: include/asm-generic/vtime.h: avoid zero-length file
> 
> patch(1) can't handle zero-length files - it appears to simply not create
> the file, so my powerpc build fails.
> 
> Put something in here to make life easier.
> 
> Cc: Hugh Dickins 
> Signed-off-by: Andrew Morton 
> ---
> 
>  include/asm-generic/vtime.h |1 +
>  1 file changed, 1 insertion(+)
> 
> diff -puN /dev/null include/asm-generic/vtime.h
> --- /dev/null
> +++ a/include/asm-generic/vtime.h
> @@ -0,0 +1 @@
> +/* no content, but patch(1) dislikes empty files */
> _
> 
> 
> 
> > I wonder what use it's supposed to have.
> 
> Frederic, can you please confirm that include/asm-generic/vtime.h is
> supposed to be empty?

Yep. I use  to let archs override some CPP symbols. And if they
don't override these, they simply return the generic vtime.h file that is empty
and as such doesn't override anything.

May be that's an ugly way to handle this kind of override scenario but I
couldn't find a better mechanism.

Actually, a Kconfig symbol would do the trick. It just seemed to me like
an overkill at that time. But it may be better.

Thanks.

> 
> > (And I'm not very keen on the growing trend for symlinks in the git tree.)
> 
> ooh, that explains why I lost my arch/microblaze/boot/dts/system.dts.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Benjamin Herrenschmidt
On Wed, 2013-10-02 at 10:46 +0200, Paolo Bonzini wrote:

> 
> Thanks.  Any chance you can give some numbers of a kernel hypercall and
> a userspace hypercall on Power, so we have actual data?  For example a
> hypercall that returns H_PARAMETER as soon as possible.

I don't have (yet) numbers at hand but we have basically 3 places where
we can handle hypercalls:

 - Kernel real mode. This is where most of our MMU stuff goes for
example unless it needs to trigger a page fault in Linux. This is
executed with translation disabled and the MMU still in guest context.
This is the fastest path since we don't take out the other threads nor
perform any expensive context change. This is where we put the
"accelerated" H_RANDOM as well.

 - Kernel virtual mode. That's a full exit, so all threads are out and
MMU switched back to host Linux. Things like vhost MMIO emulation goes
there, page faults, etc...

 - Qemu. This adds the round trip to userspace on top of the above.

Cheers,
Ben.


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Alexander Graf

On 02.10.2013, at 11:06, Benjamin Herrenschmidt wrote:

> On Wed, 2013-10-02 at 10:46 +0200, Paolo Bonzini wrote:
> 
>> 
>> Thanks.  Any chance you can give some numbers of a kernel hypercall and
>> a userspace hypercall on Power, so we have actual data?  For example a
>> hypercall that returns H_PARAMETER as soon as possible.
> 
> I don't have (yet) numbers at hand but we have basically 3 places where
> we can handle hypercalls:
> 
> - Kernel real mode. This is where most of our MMU stuff goes for
> example unless it needs to trigger a page fault in Linux. This is
> executed with translation disabled and the MMU still in guest context.
> This is the fastest path since we don't take out the other threads nor
> perform any expensive context change. This is where we put the
> "accelerated" H_RANDOM as well.
> 
> - Kernel virtual mode. That's a full exit, so all threads are out and
> MMU switched back to host Linux. Things like vhost MMIO emulation goes
> there, page faults, etc...
> 
> - Qemu. This adds the round trip to userspace on top of the above.

Right, and the difference for the patch in question is really whether we handle 
in in kernel virtual mode or in QEMU, so the bulk of the overhead (kicking 
threads out of  guest context, switching MMU context, etc) happens either way.

So the additional overhead when handling it in QEMU here really boils down to 
the user space roundtrip (plus another random number read roundtrip).


Alex

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Alexander Graf

On 02.10.2013, at 11:11, Alexander Graf wrote:

> 
> On 02.10.2013, at 11:06, Benjamin Herrenschmidt wrote:
> 
>> On Wed, 2013-10-02 at 10:46 +0200, Paolo Bonzini wrote:
>> 
>>> 
>>> Thanks.  Any chance you can give some numbers of a kernel hypercall and
>>> a userspace hypercall on Power, so we have actual data?  For example a
>>> hypercall that returns H_PARAMETER as soon as possible.
>> 
>> I don't have (yet) numbers at hand but we have basically 3 places where
>> we can handle hypercalls:
>> 
>> - Kernel real mode. This is where most of our MMU stuff goes for
>> example unless it needs to trigger a page fault in Linux. This is
>> executed with translation disabled and the MMU still in guest context.
>> This is the fastest path since we don't take out the other threads nor
>> perform any expensive context change. This is where we put the
>> "accelerated" H_RANDOM as well.
>> 
>> - Kernel virtual mode. That's a full exit, so all threads are out and
>> MMU switched back to host Linux. Things like vhost MMIO emulation goes
>> there, page faults, etc...
>> 
>> - Qemu. This adds the round trip to userspace on top of the above.
> 
> Right, and the difference for the patch in question is really whether we 
> handle in in kernel virtual mode or in QEMU, so the bulk of the overhead 
> (kicking threads out of  guest context, switching MMU context, etc) happens 
> either way.
> 
> So the additional overhead when handling it in QEMU here really boils down to 
> the user space roundtrip (plus another random number read roundtrip).

Ah, sorry, I misread the patch. You're running the handler in real mode of 
course :).

So how do you solve live migration between a kernel that has this patch and one 
that doesn't?


Alex

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Gleb Natapov
On Wed, Oct 02, 2013 at 11:50:50AM +0200, Alexander Graf wrote:
> 
> On 02.10.2013, at 11:11, Alexander Graf wrote:
> 
> > 
> > On 02.10.2013, at 11:06, Benjamin Herrenschmidt wrote:
> > 
> >> On Wed, 2013-10-02 at 10:46 +0200, Paolo Bonzini wrote:
> >> 
> >>> 
> >>> Thanks.  Any chance you can give some numbers of a kernel hypercall and
> >>> a userspace hypercall on Power, so we have actual data?  For example a
> >>> hypercall that returns H_PARAMETER as soon as possible.
> >> 
> >> I don't have (yet) numbers at hand but we have basically 3 places where
> >> we can handle hypercalls:
> >> 
> >> - Kernel real mode. This is where most of our MMU stuff goes for
> >> example unless it needs to trigger a page fault in Linux. This is
> >> executed with translation disabled and the MMU still in guest context.
> >> This is the fastest path since we don't take out the other threads nor
> >> perform any expensive context change. This is where we put the
> >> "accelerated" H_RANDOM as well.
> >> 
> >> - Kernel virtual mode. That's a full exit, so all threads are out and
> >> MMU switched back to host Linux. Things like vhost MMIO emulation goes
> >> there, page faults, etc...
> >> 
> >> - Qemu. This adds the round trip to userspace on top of the above.
> > 
> > Right, and the difference for the patch in question is really whether we 
> > handle in in kernel virtual mode or in QEMU, so the bulk of the overhead 
> > (kicking threads out of  guest context, switching MMU context, etc) happens 
> > either way.
> > 
> > So the additional overhead when handling it in QEMU here really boils down 
> > to the user space roundtrip (plus another random number read roundtrip).
> 
> Ah, sorry, I misread the patch. You're running the handler in real mode of 
> course :).
> 
> So how do you solve live migration between a kernel that has this patch and 
> one that doesn't?
> 
Yes, I alluded to it in my email to Paul and Paolo asked also. How this
interface is disabled? Also hwrnd is MMIO in a host why guest needs to
use hypercall instead of emulating the device (in kernel or somewhere
else?). Another things is that on a host hwrnd is protected from
direct userspace access by virtue of been a device, but guest code (event
kernel mode) is userspace as far as hosts security model goes, so by
implementing this hypercall in a way that directly access hwrnd you
expose hwrnd to a userspace unconditionally. Why is this a good idea? 

--
Gleb.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] powerpc/iommu: use GFP_KERNEL instead of GFP_ATOMIC in iommu_init_table()

2013-10-02 Thread Thadeu Lima de Souza Cascardo
On Tue, Oct 01, 2013 at 02:04:53PM -0700, Nishanth Aravamudan wrote:
> Under heavy (DLPAR?) stress, we tripped this panic() in
> arch/powerpc/kernel/iommu.c::iommu_init_table():
> 
>   page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz));
>   if (!page)
>   panic("iommu_init_table: Can't allocate %ld bytes\n",
> sz);
> 
> Before the panic() we got a page allocation failure for an order-2
> allocation. There appears to be memory free, but perhaps not in the
> ATOMIC context. I looked through all the call-sites of
> iommu_init_table() and didn't see any obvious reason to need an ATOMIC
> allocation. Most call-sites in fact have an explicit GFP_KERNEL
> allocation shortly before the call to iommu_init_table(), indicating we
> are not in an atomic context. There is some indirection for some paths,
> but I didn't see any locks indicating that GFP_KERNEL is inappropriate.
> 
> With this change under the same conditions, we have not been able to
> reproduce the panic.
> 
> Signed-off-by: Nishanth Aravamudan 
> 
> diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
> index 0adab06..572bb5b 100644
> --- a/arch/powerpc/kernel/iommu.c
> +++ b/arch/powerpc/kernel/iommu.c
> @@ -661,7 +661,7 @@ struct iommu_table *iommu_init_table(struct iommu_table 
> *tbl, int nid)
>   /* number of bytes needed for the bitmap */
>   sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long);
> 
> - page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz));
> + page = alloc_pages_node(nid, GFP_KERNEL, get_order(sz));
>   if (!page)
>   panic("iommu_init_table: Can't allocate %ld bytes\n", sz);
>   tbl->it_map = page_address(page);

I didn't respond to the previous message, but also checked if there were
any history on the logs, and found this was as it is from the start. I
also found no other reasons why it needs to be atomic. Therefore,

Acked-by: Thadeu Lima de Souza Cascardo 

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 1/2][v7] powerpc/mpc85xx:Add initial device tree support of T104x

2013-10-02 Thread Prabhakar Kushwaha

On 10/02/2013 01:26 AM, Scott Wood wrote:

On Tue, 2013-10-01 at 08:56 +0530, Prabhakar Kushwaha wrote:

On 10/01/2013 01:17 AM, Scott Wood wrote:

On Mon, 2013-09-30 at 12:24 +0530, Prabhakar Kushwaha wrote:

  - Removed l2switch. It will be added later

Why?

I am not aware of bindings required for l2switch as we are not working
on the driver.
Earlier I thought of putting a place holder. but as you suggested to put
bindings in documentation.
It will be good if it is put by actual driver owner.

Is there a reason to believe the binding will be complicated?

Does any such "driver owner" exist yet?


I don't know, as I am unaware of l2switch driver.




+sata@22 {
+   fsl,iommu-parent = <&pamu0>;
+   fsl,liodn-reg = <&guts 0x550>; /* SATA1LIODNR */
+};
+/include/ "qoriq-sata2-1.dtsi"
+sata@221000 {
+   fsl,iommu-parent = <&pamu0>;
+   fsl,liodn-reg = <&guts 0x554>; /* SATA2LIODNR */
+};

Whitespace

do we have any scripts which check for whitespace as checkpatch never
give any warning/error.
it is a very silly mistake which I am doing continuously :(

checkpatch doesn't check dts files.

Manual check :(


+/include/ "t1040si-post.dtsi"

Should at least have a comment indicating that eventually this should
hold the l2 switch node.

yes. Ideally it should be.
but if I put a comment then I believe this patch will not be completed.
it will think as a RFC.
as I believe putting of TODO is generally for RFC patches.

As is, one would wonder why the separate file exists at all.

The TODO is there whether you have a comment acknowledging it or
not. :-)



I agree. I will add a comments.

Regards,
Prabhakar




___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Michael Ellerman
On Wed, 2013-10-02 at 13:02 +0300, Gleb Natapov wrote:
> On Wed, Oct 02, 2013 at 11:50:50AM +0200, Alexander Graf wrote:
> > 
> > On 02.10.2013, at 11:11, Alexander Graf wrote:
> > 
> > So how do you solve live migration between a kernel that has this patch and 
> > one that doesn't?
> > 
> Yes, I alluded to it in my email to Paul and Paolo asked also. How this
> interface is disabled? 

Yes that is a valid point.

We can't disable the interface at runtime, the guest detects its
presence at boot.

What will happen is the hcall will come through to QEMU, which will
reject it with H_FUNCTION (~= ENOSYS).

The current pseries-rng driver does not handle that case well, which is
exactly why I sent patches to fix it recently.

The only other option would be to feed it with /dev/random.

> Also hwrnd is MMIO in a host why guest needs to
> use hypercall instead of emulating the device (in kernel or somewhere
> else?). 

Because PAPR is a platform specification and it specifies that the
interface is a hypervisor call. We can't just decide we want to do it
differently.

> Another things is that on a host hwrnd is protected from
> direct userspace access by virtue of been a device, but guest code (event
> kernel mode) is userspace as far as hosts security model goes, so by
> implementing this hypercall in a way that directly access hwrnd you
> expose hwrnd to a userspace unconditionally. Why is this a good idea? 

I'm not sure I follow you.

The hwrng is accessible by host userspace via /dev/mem.

cheers

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Alexander Graf

On 02.10.2013, at 15:57, Michael Ellerman wrote:

> On Wed, 2013-10-02 at 13:02 +0300, Gleb Natapov wrote:
>> On Wed, Oct 02, 2013 at 11:50:50AM +0200, Alexander Graf wrote:
>>> 
>>> On 02.10.2013, at 11:11, Alexander Graf wrote:
>>> 
>>> So how do you solve live migration between a kernel that has this patch and 
>>> one that doesn't?
>>> 
>> Yes, I alluded to it in my email to Paul and Paolo asked also. How this
>> interface is disabled? 
> 
> Yes that is a valid point.
> 
> We can't disable the interface at runtime, the guest detects its
> presence at boot.
> 
> What will happen is the hcall will come through to QEMU, which will
> reject it with H_FUNCTION (~= ENOSYS).
> 
> The current pseries-rng driver does not handle that case well, which is
> exactly why I sent patches to fix it recently.
> 
> The only other option would be to feed it with /dev/random.
> 
>> Also hwrnd is MMIO in a host why guest needs to
>> use hypercall instead of emulating the device (in kernel or somewhere
>> else?). 
> 
> Because PAPR is a platform specification and it specifies that the
> interface is a hypervisor call. We can't just decide we want to do it
> differently.
> 
>> Another things is that on a host hwrnd is protected from
>> direct userspace access by virtue of been a device, but guest code (event
>> kernel mode) is userspace as far as hosts security model goes, so by
>> implementing this hypercall in a way that directly access hwrnd you
>> expose hwrnd to a userspace unconditionally. Why is this a good idea? 
> 
> I'm not sure I follow you.
> 
> The hwrng is accessible by host userspace via /dev/mem.

A guest should live on the same permission level as a user space application. 
If you run QEMU as UID 1000 without access to /dev/mem, why should the guest 
suddenly be able to directly access a memory location (MMIO) it couldn't access 
directly through a normal user space interface.

It's basically a layering violation.


Alex

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Gleb Natapov
On Wed, Oct 02, 2013 at 11:57:55PM +1000, Michael Ellerman wrote:
> On Wed, 2013-10-02 at 13:02 +0300, Gleb Natapov wrote:
> > On Wed, Oct 02, 2013 at 11:50:50AM +0200, Alexander Graf wrote:
> > > 
> > > On 02.10.2013, at 11:11, Alexander Graf wrote:
> > > 
> > > So how do you solve live migration between a kernel that has this patch 
> > > and one that doesn't?
> > > 
> > Yes, I alluded to it in my email to Paul and Paolo asked also. How this
> > interface is disabled? 
> 
> Yes that is a valid point.
> 
> We can't disable the interface at runtime, the guest detects its
> presence at boot.
> 
> What will happen is the hcall will come through to QEMU, which will
> reject it with H_FUNCTION (~= ENOSYS).
> 
> The current pseries-rng driver does not handle that case well, which is
> exactly why I sent patches to fix it recently.
> 
> The only other option would be to feed it with /dev/random.
> 
What about other way, if guest migrates from kvm that has no this
hypercall to one that has? We try to not change HW under guest during
migration.

> > Also hwrnd is MMIO in a host why guest needs to
> > use hypercall instead of emulating the device (in kernel or somewhere
> > else?). 
> 
> Because PAPR is a platform specification and it specifies that the
> interface is a hypervisor call. We can't just decide we want to do it
> differently.
Any insights on why it was specified this what. What is special about
hwrnd device that hypercall is needed to access it? I got that you didn't
just decide to implement it that way :) Also what will happen if guest
will find emulated hwrnd device, will it use it?

> 
> > Another things is that on a host hwrnd is protected from
> > direct userspace access by virtue of been a device, but guest code (event
> > kernel mode) is userspace as far as hosts security model goes, so by
> > implementing this hypercall in a way that directly access hwrnd you
> > expose hwrnd to a userspace unconditionally. Why is this a good idea? 
> 
> I'm not sure I follow you.
> 
> The hwrng is accessible by host userspace via /dev/mem.
> 
Regular user has no access to /dev/mem, but he can start kvm guest and
gain access to the device.

--
Gleb.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Paolo Bonzini
Il 02/10/2013 16:08, Alexander Graf ha scritto:
> > The hwrng is accessible by host userspace via /dev/mem.
> 
> A guest should live on the same permission level as a user space
> application. If you run QEMU as UID 1000 without access to /dev/mem, why
> should the guest suddenly be able to directly access a memory location
> (MMIO) it couldn't access directly through a normal user space interface.
> 
> It's basically a layering violation.

With Michael's earlier patch in this series, the hwrng is accessible by
host userspace via /dev/hwrng, no?

Paolo
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Paolo Bonzini
Il 02/10/2013 16:36, Alexander Graf ha scritto:
>> > 
>> > With Michael's earlier patch in this series, the hwrng is accessible by
>> > host userspace via /dev/hwrng, no?
> Yes, but there's not token from user space that gets passed into the
> kernel to check whether access is ok or not. So while QEMU may not have
> permission to open /dev/hwrng it could spawn a guest that opens it,
> drains all entropy out of it and thus stall other processes which try to
> fetch entropy, no?
> 
> Maybe I haven't fully grasped the interface yet though :).

Yes, that's right.  I don't think it's a huge problem, but it's another
point in favor of just doing the hypercall in userspace.

Paolo
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] kvm: powerpc: book3s: Fix build break for BOOK3S_32

2013-10-02 Thread Aneesh Kumar K.V
From: "Aneesh Kumar K.V" 

This was introduced by 85a0d845d8bb5df5d2669416212f56cbe1474c6b

arch/powerpc/kvm/book3s_pr.c: In function 'kvmppc_core_vcpu_create':
arch/powerpc/kvm/book3s_pr.c:1182:30: error: 'struct kvmppc_vcpu_book3s' has no 
member named 'shadow_vcpu'
make[1]: *** [arch/powerpc/kvm/book3s_pr.o] Error 1

Signed-off-by: Aneesh Kumar K.V 
---
 arch/powerpc/kvm/book3s_pr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 8941885..6075dbd 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -1179,7 +1179,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, 
unsigned int id)
 
 #ifdef CONFIG_KVM_BOOK3S_32
vcpu->arch.shadow_vcpu =
-   kzalloc(sizeof(*vcpu_book3s->shadow_vcpu), GFP_KERNEL);
+   kzalloc(sizeof(*vcpu->arch.shadow_vcpu), GFP_KERNEL);
if (!vcpu->arch.shadow_vcpu)
goto free_vcpu3s;
 #endif
-- 
1.8.1.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Alexander Graf

On 02.10.2013, at 16:33, Paolo Bonzini wrote:

> Il 02/10/2013 16:08, Alexander Graf ha scritto:
>>> The hwrng is accessible by host userspace via /dev/mem.
>> 
>> A guest should live on the same permission level as a user space
>> application. If you run QEMU as UID 1000 without access to /dev/mem, why
>> should the guest suddenly be able to directly access a memory location
>> (MMIO) it couldn't access directly through a normal user space interface.
>> 
>> It's basically a layering violation.
> 
> With Michael's earlier patch in this series, the hwrng is accessible by
> host userspace via /dev/hwrng, no?

Yes, but there's not token from user space that gets passed into the kernel to 
check whether access is ok or not. So while QEMU may not have permission to 
open /dev/hwrng it could spawn a guest that opens it, drains all entropy out of 
it and thus stall other processes which try to fetch entropy, no?

Maybe I haven't fully grasped the interface yet though :).


Alex

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: Avoiding the dentry d_lock on final dput(), part deux: transactional memory

2013-10-02 Thread Andi Kleen
Linus Torvalds  writes:

> On Mon, Sep 30, 2013 at 1:01 PM, Waiman Long  wrote:
>>
>> I think this patch is worth a trial if relevant hardware is more widely
>> available. The TSX code certainly need to be moved to an architecture
>> specific area and should be runtime enabled using a static key. We also need
>> more TSX support infrastructure in place first.
>
> I think we can pick that up from Andi's patches, he should have that.
> Although that did have very x86-specific naming (ie "xbegin"). And I
> don't think he used "asm goto" to quite the same advantage as this -
> and I think we do want to make sure that the overhead is minimal.

FWIW my version #0 used asm goto directly, but I later switched to not
using it to support more compilers and higher level abstractions (locks
etc.) and use the same intrinsics as the user level guys are using.

The two extra instructions from not using asm goto for xbegin
don't matter all that much in the end.

That's the old asm goto stuff I wrote originally
(user level version):

https://github.com/andikleen/tsx-tools/blob/master/include/rtm-goto.h

There was also a kernel version of it that patched, right 
now this is done in the main TSX patchkit like this:

https://git.kernel.org/cgit/linux/kernel/git/ak/linux-misc.git/commit/?h=hle312/rtm-base&id=9190346d57a9bc89e746aee774d07e54cd1e6e75

Essentially without RTM it just becomes and unconditional jump
to the abort handler, xabort is a nop, and xtest always returns 0.

-Andi
-- 
a...@linux.intel.com -- Speaking for myself only
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 3/3] KVM: PPC: Book3S: Add support for hwrng found on some powernv systems

2013-10-02 Thread Gleb Natapov
On Wed, Oct 02, 2013 at 04:33:18PM +0200, Paolo Bonzini wrote:
> Il 02/10/2013 16:08, Alexander Graf ha scritto:
> > > The hwrng is accessible by host userspace via /dev/mem.
> > 
> > A guest should live on the same permission level as a user space
> > application. If you run QEMU as UID 1000 without access to /dev/mem, why
> > should the guest suddenly be able to directly access a memory location
> > (MMIO) it couldn't access directly through a normal user space interface.
> > 
> > It's basically a layering violation.
> 
> With Michael's earlier patch in this series, the hwrng is accessible by
> host userspace via /dev/hwrng, no?
> 
Access to which can be controlled by its permission. Permission of
/dev/kvm may be different. If we route hypercall via userspace and
configure qemu to get entropy from /dev/hwrng everything will fall
nicely together (except performance).

--
Gleb.
___
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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
-   max_sds_rings = num_msix;
-
-   adapter->max_sds_rings = max_sds_rings;
-   }
-   dev_info(&pdev->dev, "using msi-x inte

[PATCH RFC 08/77] PCI/MSI: Get rid of pci_enable_msi_block_auto() interface

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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 interrupts enablement code
  cxgb3: Do not call pci_disable_msix() if p

[PATCH RFC 33/77] ioat: Disable MSI-X in case request of IRQ failed

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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()

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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 to achieve that might look like:
 
 static int foo_driv

[PATCH RFC 11/77] benet: Return -ENOSPC when not enough MSI-Xs available

2013-10-02 Thread Alexander Gordeev
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

2013-10-02 Thread Alexander Gordeev
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


  1   2   >