* Re: XSysAce driver cant mount DOS part
From: Grant Likely @ 2007-07-12 19:06 UTC (permalink / raw)
To: Robertson, Joseph M.; +Cc: linuxppc-embedded
In-Reply-To: <939D37AEB47F1F49B88FAB6599B6023501A17206@hsv1dafpew02.das.gov.sanm.corp>
On 7/12/07, Robertson, Joseph M. <joseph.robertson@sanmina-sci.com> wrote:
> RE: Tree.
> Its the mainline 2.6.17.1, with
> denx ppc patches from 4.0.0? IIRC.
> I redid the patch set for the xsysace to get a known baseline.
> Its a custom build system, which I developed over the years, ported to use
> a ppc405 crosscompiler I made from
> CrossTool-0.42. Its very similar to uClinux, but with a simpler config
> system.
> The compiler is gcc.3.4.1 with glibc 2.3.3 (yeah we use glibc).
Heh, so do I. So do a lot of people. glibc *is* for embedded
systems, regardless of what some may say. :-)
> The XsysAce patch is in the normal place, only change I made was to define
> the major number.
> And I moved xbasic_types.c/h to another folder onthe path since xilinx_iic
> drivers uses it too, and I was getting redefine errors.
> One thing I just thought of was I did not run the 'normal' config stuff,
> any deps in there?
> I can go look at the kconfigs and see.
>
> RE: Xilinx SysAce driver
> The HW group used Xilinx env 8.2.02i, and the project shows
> Sysace_compactflash driver: sysace_v1_01_a
Okay, so that's the old driver. There is a new driver that has
considerably better performance which you might want to try; but it
doesn't support insertion/removal yet. It is about to be pulled into
mainline, but you can get it here too:
http://article.gmane.org/gmane.linux.kernel/526293/match=xsysace+c
>
> The HW is a Virtex-4 with the embedded ppc405. The Xsysace chip is
> supposed tobe using irq_intr = 2.
>
> The system actually works fine using the Ext2 fs, but if we want to upgrade
> the fpga code, I need to be able to write to the dos part.
2.6.17 is rather old. You might be hitting an old bug. Virtex
support in the newer kernels is significantly better. Have you
considered upgrading? I've got a bunch of patches in my git tree that
add the TEMAC and other drivers to a more recent kernel. My internal
tree is based on 2.6.22; I'll try to update my external tree to match
in the next day or so:
http://git.secretlab.ca/cgi-bin/gitweb.cgi?h=virtex-dev;p=linux-2.6.git;a=shortlog
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* Re: [PATCH 4/4] Add DMA engine driver for Freescale MPC8xxx processors.
From: Scott Wood @ 2007-07-12 18:57 UTC (permalink / raw)
To: Zhang Wei-r63237; +Cc: linuxppc-dev, paulus
In-Reply-To: <46B96294322F7D458F9648B60E15112C6F3E46@zch01exm26.fsl.freescale.net>
Zhang Wei-r63237 wrote:
>>It'd be much simpler to allocate the entire ring at once. No need for
>>linked lists, DMA pools, etc. Just a single dma_alloc_coherent.
>>
>
>
> I use a flexible ld ring size here. If there is no more free ring, the
> driver can add new ld to the ring.
I don't think that's worth all the complexity that it adds. Most
drivers make do just fine with a fixed-size ring.
>>What benefit do we get out of using extended mode? If the
>>driver can do
>>everything it needs to with basic, with no performance
>>penalty, why not
>>always use basic?
>>
>
> Why there are extended mode in silicon? :)
I've been wondering that myself. :-)
> Since there are here, we use it.
"Because it's there" really isn't a good reason for adding complexity to
the code.
>>It'd be nice if we didn't have to stop the DMA in order to insert new
>>descriptors.
>
>
> Since there is only happen at no more free ld in the ring. We need to
> break the ld-ring and add new ld to it.
Or you could just block until a previous descriptor completes.
>>Why not just use the index into the ring as the cookie?
>
>
> The cookie will record all transfer by increased number. The ring index
> is less for all transfer.
I'm not sure I follow. All you need is a way to identify a currently
used descriptor, right?
>>>+ fsl_chan->id, stat);
>>>+ if (!stat)
>>>+ return IRQ_NONE;
>>>+ busy = stat & (FSL_DMA_SR_CB);
>>>+ stat &= ~(FSL_DMA_SR_CB | FSL_DMA_SR_CH);
>>
>>This masking must happen *before* the IRQ_NONE check.
>
> Really? FSL_DMA_SR_CH is also a stat of event.
Does the IRQ handler always clear the bit? If not, then it doesn't count.
> And I need the FSL_DMA_SR_CB status.
The busy assignment can still happen before the mask... just move the
IRQ_NONE check down.
-Scott
^ permalink raw reply
* RE: XSysAce driver cant mount DOS part
From: Robertson, Joseph M. @ 2007-07-12 18:53 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <fa686aa40707121116l1d76078aq82926eb861720474@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3573 bytes --]
Hi!
Wow, quick replies.
RE: Tree.
Its the mainline 2.6.17.1, with
denx ppc patches from 4.0.0? IIRC.
I redid the patch set for the xsysace to get a known baseline.
Its a custom build system, which I developed over the years, ported to use a ppc405 crosscompiler I made from
CrossTool-0.42. Its very similar to uClinux, but with a simpler config system.
The compiler is gcc.3.4.1 with glibc 2.3.3 (yeah we use glibc).
The XsysAce patch is in the normal place, only change I made was to define the major number.
And I moved xbasic_types.c/h to another folder onthe path since xilinx_iic drivers uses it too, and I was getting redefine errors.
One thing I just thought of was I did not run the 'normal' config stuff, any deps in there?
I can go look at the kconfigs and see.
RE: Xilinx SysAce driver
The HW group used Xilinx env 8.2.02i, and the project shows Sysace_compactflash driver: sysace_v1_01_a
The HW is a Virtex-4 with the embedded ppc405. The Xsysace chip is supposed tobe using irq_intr = 2.
The system actually works fine using the Ext2 fs, but if we want to upgrade the fpga code, I need to be able to write to the dos part.
Thanks so much.
Joe Robertson
Joseph.Robertson@sanmina-sci.com
-----Original Message-----
From: glikely@secretlab.ca on behalf of Grant Likely
Sent: Thu 7/12/2007 1:16 PM
To: Robertson, Joseph M.
Cc: linuxppc-embedded@ozlabs.org
Subject: Re: XSysAce driver cant mount DOS part
On 7/12/07, Robertson, Joseph M. <joseph.robertson@sanmina-sci.com> wrote:
>
> I've been workig with this for a while but have made no progress.
> Today I got the latest XSysAce patch for kernel 2.6.17.1 and applied it to
> get clean code.
> I inherited the previous code from another developer.
Who's tree are you using? Montavistas? Mainline?
Which sysace driver are you using? The old one from Xilinx or the new one?
>
> My problem is that mounting the DOS partition always fails in a short time
> with a kernel oops.
>
> ECAU-9999:# Oops: kernel access of bad area, sig: 11 [#1]
>
> PREEMPT
---8<---snip--->8---
> LR [C0070C18] drain_array+0xb8/0x124
>
> Call Trace:
Did you trim off the call trace? The call trace is pretty useful for
figuring out what happened.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
CONFIDENTIALITY
This e-mail message and any attachments thereto, is intended only for use by the addressee(s) named herein and may contain legally privileged and/or confidential information. If you are not the intended recipient of this e-mail message, you are hereby notified that any dissemination, distribution or copying of this e-mail message, and any attachments thereto, is strictly prohibited. If you have received this e-mail message in error, please immediately notify the sender and permanently delete the original and any copies of this email and any prints thereof.
ABSENT AN EXPRESS STATEMENT TO THE CONTRARY HEREINABOVE, THIS E-MAIL IS NOT INTENDED AS A SUBSTITUTE FOR A WRITING. Notwithstanding the Uniform Electronic Transactions Act or the applicability of any other law of similar substance and effect, absent an express statement to the contrary hereinabove, this e-mail message its contents, and any attachments hereto are not intended to represent an offer or acceptance to enter into a contract and are not otherwise intended to bind the sender, Sanmina-SCI Corporation (or any of its subsidiaries), or any other person or entity.
[-- Attachment #2: Type: text/html, Size: 4420 bytes --]
^ permalink raw reply
* Re: XSysAce driver cant mount DOS part
From: Jeff Angielski @ 2007-07-12 18:26 UTC (permalink / raw)
To: Robertson, Joseph M.; +Cc: linuxppc-embedded
In-Reply-To: <939D37AEB47F1F49B88FAB6599B6023501A17205@hsv1dafpew02.das.gov.sanm.corp>
On Thu, 2007-07-12 at 13:03 -0500, Robertson, Joseph M. wrote:
> Hi all,
>
> I've been workig with this for a while but have made no progress.
> Today I got the latest XSysAce patch for kernel 2.6.17.1 and applied
> it to get clean code.
> I inherited the previous code from another developer.
>
> My problem is that mounting the DOS partition always fails in a short
> time with a kernel oops.
Can you access that partition on your Linux host using a CF adapter?
Can you access that partition from the uboot prompt?
How did you format that partition? mkfs.msdos?
--
Jeff Angielski
The PTR Group
www.theptrgroup.com
^ permalink raw reply
* Re: XSysAce driver cant mount DOS part
From: Grant Likely @ 2007-07-12 18:16 UTC (permalink / raw)
To: Robertson, Joseph M.; +Cc: linuxppc-embedded
In-Reply-To: <939D37AEB47F1F49B88FAB6599B6023501A17205@hsv1dafpew02.das.gov.sanm.corp>
On 7/12/07, Robertson, Joseph M. <joseph.robertson@sanmina-sci.com> wrote:
>
> I've been workig with this for a while but have made no progress.
> Today I got the latest XSysAce patch for kernel 2.6.17.1 and applied it to
> get clean code.
> I inherited the previous code from another developer.
Who's tree are you using? Montavistas? Mainline?
Which sysace driver are you using? The old one from Xilinx or the new one?
>
> My problem is that mounting the DOS partition always fails in a short time
> with a kernel oops.
>
> ECAU-9999:# Oops: kernel access of bad area, sig: 11 [#1]
>
> PREEMPT
---8<---snip--->8---
> LR [C0070C18] drain_array+0xb8/0x124
>
> Call Trace:
Did you trim off the call trace? The call trace is pretty useful for
figuring out what happened.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* XSysAce driver cant mount DOS part
From: Robertson, Joseph M. @ 2007-07-12 18:03 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 3216 bytes --]
Hi all,
I've been workig with this for a while but have made no progress.
Today I got the latest XSysAce patch for kernel 2.6.17.1 and applied it to get clean code.
I inherited the previous code from another developer.
My problem is that mounting the DOS partition always fails in a short time with a kernel oops.
ECAU-9999:# Oops: kernel access of bad area, sig: 11 [#1]
PREEMPT
NIP: C00701C8 LR: C0070C18 CTR: 00000000
REGS: c0391dd0 TRAP: 0300 Not tainted (2.6.17.1)
MSR: 00021030 <ME,IR,DR> CR: 22028082 XER: 0000000B
DAR: 00000000, DSISR: 00800000
TASK = c0373030[4] 'events/0' THREAD: c0390000
GPR00: 00000080 C0391E80 C0373030 C02CAC00 C0E03000 C0E03154 00000000 C02CAC00
GPR08: 00200200 00000000 00100100 00000000 00051A4B FFFFDE60 03BD4900 007FFF3B
GPR16: 00400000 00000001 FFFFFFFF 03BCDC58 00000000 007FFF00 00000002 C0280000
GPR24: C0363A10 0000000B 00000000 00000000 00000000 C02CAC00 C035ED20 C0E03000
NIP [C00701C8] free_block+0x8c/0x138
LR [C0070C18] drain_array+0xb8/0x124
Call Trace:
The setup:
My own build system.
Kernel 2.6.17.1 with lots of xilinx stuff, eth, i2c, xsysace. Crosscompiled for PPC405.
Latest, clean XSysAce code. mods: major hardcoded to = 125. Polled mode.
CF: 3 partitions,
1: DOS FAT16
2: Ext2 main
3: Ext2 rescue
This build boots up fine, mounts a ext2 as root fine. I can also mount the rescue partition with no problems.
Does anyone have any pointers of where I should look for problems?
My next step is to go and set it up for interrupt service and see if that changes anything.
Thanks,
Joe Robertson
Joseph.Robertson@sanmina-sci.com
CONFIDENTIALITY
This e-mail message and any attachments thereto, is intended only for use by the addressee(s) named herein and may contain legally privileged and/or confidential information. If you are not the intended recipient of this e-mail message, you are hereby notified that any dissemination, distribution or copying of this e-mail message, and any attachments thereto, is strictly prohibited. If you have received this e-mail message in error, please immediately notify the sender and permanently delete the original and any copies of this email and any prints thereof.
ABSENT AN EXPRESS STATEMENT TO THE CONTRARY HEREINABOVE, THIS E-MAIL IS NOT INTENDED AS A SUBSTITUTE FOR A WRITING. Notwithstanding the Uniform Electronic Transactions Act or the applicability of any other law of similar substance and effect, absent an express statement to the contrary hereinabove, this e-mail message its contents, and any attachments hereto are not intended to represent an offer or acceptance to enter into a contract and are not otherwise intended to bind the sender, Sanmina-SCI Corporation (or any of its subsidiaries), or any other person or entity.
[-- Attachment #2: Type: text/html, Size: 5825 bytes --]
^ permalink raw reply
* Re: [PATCH 00/10] IB/ehca: Multiple Event Queues, MR/MW rework, large page MRs, fixes
From: Roland Dreier @ 2007-07-12 17:15 UTC (permalink / raw)
To: Joachim Fenkes
Cc: LKML, LinuxPPC-Dev, Christoph Raisch, OF-General, Stefan Roscher
In-Reply-To: <200707121745.27592.fenkes@de.ibm.com>
> Note that patch 7 will introduce a few lines over 80 chars that will be
> unindented in patch 8 - I hope that's okay with you.
That's fine -- the 80 column rule is one thing I don't worry about too
much; absurdly long lines are bad, but if a line is, say, 84 chars and
breaking it makes the code uglier, then I just leave the 84 char line.
> [09/10] fixes a lot of checkpatch.pl warnings
Are these warnings from earlier patches in the series, or problems
that already existed in the code? If they are coming from other
patches in the series, please just fix the earlier patches before I
merge them.
Thanks,
Roland
^ permalink raw reply
* RE: [PATCH 1/4] Add DMA sector to Documentation/powerpc/booting-without-of.txt file.
From: Phil Terry @ 2007-07-12 17:12 UTC (permalink / raw)
To: Wei.Zhang; +Cc: linuxppc-dev, paulus
In-Reply-To: <46B96294322F7D458F9648B60E15112C6F3E42@zch01exm26.fsl.freescale.net>
Excuse me butting in if I've got this whole dtc, of, device driver
model, etc., stuff wrong but I thought it was supposed to work like
this:
The DMA engine is a generic kernel service. Its a "device". You can
infer its presence without a dts/of by the fact that you have the fsl
soc but ok if you want to put it in dts/of that works too.
All its going to do is load a "driver" which makes available the
services of the "device" under a generic DMA internal api.
Say I'm writing a sound card, video card, widget card, etc., driver.
My driver gets loaded by virtue of detecting the card/device (via of,
pci, usb, platform, whatever bus mechanisms).
My driver would benefit from using a generic DMA device so it uses the
internal api to look for one and uses the API of that device to request
a channel for its use. I don't care what channel I get, I don't need a
fixed, reserved channel of the DMA device as specified in the dts I just
need an unused channel. If no channels are available or I'm in a system
with no generic DMA service available I can either fall back to
processor copying or refuse to load.
Given the device might be a hot-insert USB device etc, there's nothing a
dts can do to help me here in this scenario, right?
I thought the idea of the dts/of was for the hardware specific boot
loader to tell the kernel about hardware that the kernel couldn't
otherwise know about, because its not detectable by a bus probe method,
etc. Its not there to tell you how to use the device or arbitrate which
other devices get to use a device when there are resource conflicts,
etc.
If the dts/of/boot loader tells the kernel its a fsl soc then it knows
how to work out which one and what level, and therefore knows what
devices, such as the DMA device are present.
I'm truly interested in understanding the correct interpretation because
we are developing a DMA based, rapidio distributed system on fsl 8641
and from lurking on here and reading the archives etc, all I see is a
constant butting of heads on what the dts/of is and how its supposed to
work.
Quite why we are using a 20 year old spec, which was never finished, and
ceased to be a formal spec 10 years ago as the "new" way forward is a
puzzle to me as well. Not flame bait, but if someone could point me to
background material it would be helpful for my education in getting up
to speed (on the rationale for using it going forwards, not all the old
sites for the spec itself).
Cheers
Phil
On Thu, 2007-07-12 at 17:48 +0800, Zhang Wei-r63237 wrote:
>
> > -----Original Message-----
> > From: Segher Boessenkool [mailto:segher@kernel.crashing.org]
> > Sent: Thursday, July 12, 2007 1:54 AM
> > To: Wood Scott-B07421
> > Cc: Zhang Wei-r63237; linuxppc-dev@ozlabs.org; paulus@samba.org
> > Subject: Re: [PATCH 1/4] Add DMA sector to
> > Documentation/powerpc/booting-without-of.txt file.
> >
> > >>> I'd rather just treat the different DMA channels as independent
> > >>> devices,
> > >>> rather than children of a dma "bus", and change the compatible
> > >>> name if
> > >>> they're not general purpose. There's only one register that's
> > >>> shared
> > >>> among the channels, and it's a superfluous status summary
> > register.
> > >>>
> > >> Your and my ideas are both sides of a coin. :-)
> > >
> > > I think there's a substantive difference between them.
> > Making each
> > > channel an independent device makes it easier for other drivers to
> > > use them.
> >
> > True. If the DMA channels are independent enough, putting them
> > in nodes of their own isn't too cumbersome, either.
> >
> >
>
> If you want to use DMA engine driver for the reserved channel, you
> should add it to dma-controller node and assign 'reserved'.
> If you don't want to use DMA engine driver, just remove it from
> dma-controller node and put the channel to special device node.
>
> Thanks!
> Wei.
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
>
^ permalink raw reply
* Re: Fwd: [PATCH] 2.6.18-rt7: fix more issues with 32-bit cycles_t in latency_trace.c
From: Sergei Shtylyov @ 2007-07-12 17:06 UTC (permalink / raw)
To: mingo, Thomas Gleixner; +Cc: linuxppc-dev
In-Reply-To: <200611130026.17204.sshtylyov@ru.mvista.com>
Hello, I wrote:
> In addition to clock wrap check being falsely triggered with 32-bit cycles_t,
> as noticed to Kevin Hilman, there's another issue: using %Lx format to print
> 32-bit values warrants erroneous values on 32-bit machines like ARM and PPC32.
> Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
> ---
> PPC32 actually has 64-bit timebase counter, so could provide for 64-bit
> cycles_t -- maybe it's worth to rewrite get_cycles() to read both lower and
> upper registers?
This one (called latency-tracer-prink-fix.patch in the broken out
patchset) has been erroneously "restored" some months ago. Since
preempt_max_latency is of type 'unsigned long' now and all the other vars are
of type 'cycle_t' (which aliases 'u64'), only the first cast is actually
needed (or rather, the first format specifier needs to be changed to %08lx).
Erm, maybe I'll cook a patch...
> Index: linux-2.6/kernel/latency_trace.c
> ===================================================================
> --- linux-2.6.orig/kernel/latency_trace.c
> +++ linux-2.6/kernel/latency_trace.c
> @@ -1623,8 +1623,8 @@ check_critical_timing(int cpu, struct cp
> #ifndef CONFIG_CRITICAL_LATENCY_HIST
> if (!preempt_thresh && preempt_max_latency > delta) {
> printk("bug: updating %016Lx > %016Lx?\n",
> - preempt_max_latency, delta);
> - printk(" [%016Lx %016Lx %016Lx]\n", T0, T1, T2);
> + (u64)preempt_max_latency, (u64)delta);
> + printk(" [%016Lx %016Lx %016Lx]\n", (u64)T0, (u64)T1, (u64)T2);
> }
> #endif
WBR, Sergei
^ permalink raw reply
* Re: [PATCH 2.6.21-rt2] PowerPC: revert fix for threaded fasteoi IRQ handlers
From: Thomas Gleixner @ 2007-07-12 16:52 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: linuxppc-dev, mingo, linux-kernel, dwalker
In-Reply-To: <46965B28.7000703@ru.mvista.com>
On Thu, 2007-07-12 at 20:47 +0400, Sergei Shtylyov wrote:
> Now that the -rt patch has been first release in the broken-out version,
> let me tell you that the following 3 patches in the series can be just
> annihilated:
>
> preempt-irqs-ppc-ack-irq-fixups.patch
> preempt-irqs-ppc-fix-b5.patch
> preempt-irqs-ppc-fix-more-fasteoi.patch
>
> as all that the latter two are doing is undoing the former one.
Really ? I know for quite a while.
We kept some of those files to document contributions. Go read back on
the LKML archives, where we were accused more than once not to keep
track of these things.
They can be folded together and fixed up, one thing after the other
please.
tglx
^ permalink raw reply
* Re: [PATCH 2.6.21-rt2] PowerPC: revert fix for threaded fasteoi IRQ handlers
From: Sergei Shtylyov @ 2007-07-12 16:47 UTC (permalink / raw)
To: mingo, tglx; +Cc: linuxppc-dev, linux-kernel, dwalker
In-Reply-To: <200705171719.34968.sshtylyov@ru.mvista.com>
Hello, I wrote:
> Revert the change to the "fasteoi" type chips as after handle_fasteoi_irq() had
> been fixed, they've become meaningless (and even dangerous -- as was the case
> with Celleb that has been fixed earlier)...
> Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
> ---
> The patch in question wasn't even initially accepted but then was erroneously
> restored along with the TOD patch. I've asked to revert it but to no avail,
> so here's the formal patch to revert it at last...
Now that the -rt patch has been first release in the broken-out version,
let me tell you that the following 3 patches in the series can be just
annihilated:
preempt-irqs-ppc-ack-irq-fixups.patch
preempt-irqs-ppc-fix-b5.patch
preempt-irqs-ppc-fix-more-fasteoi.patch
as all that the latter two are doing is undoing the former one.
WBR, Sergei
^ permalink raw reply
* Re: Tickless Hz/hrtimers/etc. on PowerPC
From: Sergei Shtylyov @ 2007-07-12 16:41 UTC (permalink / raw)
To: Matt Sealey; +Cc: linuxppc-dev, Domen Puncer
In-Reply-To: <4696369A.2010200@ru.mvista.com>
[-- Attachment #1: Type: text/plain, Size: 691 bytes --]
Sergei Shtylyov wrote:
> Hello.
>
> Domen Puncer wrote:
>
>>> Does anyone have the definitive patchset to enable the tickless hz,
>>> some kind of hrtimer and the other related improvements in the
>>> PowerPC tree?
>
>
>> I use attached patches for tickless.
>> Order in which they're applied:
>> PowerPC_GENERIC_CLOCKEVENTS.patch
Argh! Finally had forgotten to attach a fixlet for this one, somewaht
adjusting the code for classic PPC decrementer.
[...]
WBR, Sergei
> PS: All attached patches are against 2.6.21-rt2 -- fitting them into the
> current (or whatever) version of the kernel is left as an excercise to
> the readers. ;-)
This one is for 2.6.21-rt2 as well.
[-- Attachment #2: PowerPC-fix-clockevents-for-classic-CPU.patch --]
[-- Type: text/x-patch, Size: 2054 bytes --]
Uncoditionally set a maximum positive value to the decrementer before calling
an event handler for all "classic" PPC CPUs (although this is only necessary
to clear interrupt on POWER4+, I've been asked to do it this way) -- otherwise
it wouldn't have been done for an offline CPU in periodic mode since the event
reprogramming has been delegated to the timer subsystem.
Also, as the classic decrementer doesn't have periodic mode, make set_mode()
method for this case completely empty.
While at it, add a switch case for CLOCK_EVT_MODE_RESUME to hush the warning.
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
arch/powerpc/kernel/time.c | 15 +++++++--------
1 files changed, 7 insertions(+), 8 deletions(-)
Index: linux-2.6/arch/powerpc/kernel/time.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/time.c
+++ linux-2.6/arch/powerpc/kernel/time.c
@@ -166,11 +166,14 @@ static void decrementer_set_mode(enum cl
case CLOCK_EVT_MODE_SHUTDOWN:
tcr &= ~TCR_DIE;
break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
}
mtspr(SPRN_TCR, tcr);
-#endif
+
if (mode == CLOCK_EVT_MODE_PERIODIC)
decrementer_set_next_event(tb_ticks_per_jiffy, dev);
+#endif
}
static struct clock_event_device decrementer_clockevent = {
@@ -549,16 +552,12 @@ void timer_interrupt(struct pt_regs * re
irq_enter();
#ifdef CONFIG_GENERIC_CLOCKEVENTS
-#ifdef CONFIG_PPC_MULTIPLATFORM
+#if !defined(CONFIG_40x) && !defined(CONFIG_BOOKE)
/*
* We must write a positive value to the decrementer to clear
- * the interrupt on the IBM 970 CPU series. In periodic mode,
- * this happens when the decrementer gets reloaded later, but
- * in one-shot mode, we have to do it here since an event handler
- * may skip loading the new value...
+ * the interrupt on POWER4+ compatible CPUs.
*/
- if (per_cpu(decrementers, cpu).mode != CLOCK_EVT_MODE_PERIODIC)
- set_dec(DECREMENTER_MAX);
+ set_dec(DECREMENTER_MAX);
#endif
/*
* We can't disable the decrementer, so in the period between
^ permalink raw reply
* Re: Tickless Hz/hrtimers/etc. on PowerPC
From: Sergei Shtylyov @ 2007-07-12 16:32 UTC (permalink / raw)
To: Matt Sealey; +Cc: ppc-dev, Michael Neuling
In-Reply-To: <46955674.9090304@genesi-usa.com>
Hello.
Matt Sealey wrote:
> And I don't want to run -rt or wireless-dev for the benefit of a single
BTW, the latest -rt has has been also released in the broken out form (at
last!) which has "PPC gtod and highres support" section in its series file.
> feature. What I am after is something like Ingo Molnar throws out..
One 1.5 Megabyte patch?! Bleh... thanks goodness he (or Thomas) has
finally changed his mind about this. :-)
> single patches done the old way, not git trees. It's so much easier to
> handle and integrate for example into a Gentoo ebuild or to make a
> tarball of accumulated patches from a certain release kernel.
This also can become a nightmare if you intend to pick up some later fixes
only.
WBR, Sergei
^ permalink raw reply
* Re: [RFC 0/3] lro: Generic Large Receive Offload for TCP traffic
From: Andrew Gallatin @ 2007-07-12 16:01 UTC (permalink / raw)
To: Jan-Bernd Themann
Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel, linux-ppc,
Christoph Raisch, loic, Marcus Eder, stefan.roscher, brice
In-Reply-To: <200707111621.24852.ossthema@de.ibm.com>
On 7/11/07, Jan-Bernd Themann <ossthema@de.ibm.com> wrote:
> Generic Large Receive Offload proposal
I'm very glad that somebody is stepping up to take responsibility
for this!
I'm the primary author of the Myricom Myri10GE driver, and its LRO mechanism
(which has been rejected several times when posted here). I don't subscribe
to the LKML or netdev lists (the b/w is way too much for me).
Thankfully, my colleague Brice (who maintains our driver in the kernel)
forwarded me this message.
I looked at your patch, and I believe that we can improve the
performance further by using a slightly different approach, or at
least making that approach optional.
When I first did our LRO implementation, it aggregated packets
essentially the same way you are doing it -- by appending packets to
the frag_list. I did quite extensive profiling, and the most expensive
operations seemed to be the allocation and freeing of memory. A
colleague of mine (Loic, CC'ed) came up with the brilliant idea of
receiving into pages. When I implemented his suggestion, it turned
out to be much, much more efficient to receive into pages, and to
accumulate the pages to the frags array.
The benchmarks I did on very low end machines in my lab (2GHz
amd64 x2 3800+) showed that the receiver was saturated at roughly
4.2Gb/s without LRO, 5.7Gb/s with frag_list based LRO, 8.6Gb/s with
frags array based LRO, and somewhat idle at line rate with frags array
based LRO and 32KB order=3 pages. (This is 1500b frames, BTW).
The savings comes from being able to do fewer allocations. For
example, 2 1500b packets fit in a single page. So, for a "full" frag
array, we have 16 1/2 4KB pages and a single skb holding them.
This works out to be 9 allocations for roughly 23KB of payload,
rather than 16. Using order 3 (32KB) pages, it gets even better,
and we have just 2 allocations per full skb frag list.
So... It would be wonderful if your patch could also deal with
data residing in pages, rather than in skbs. I can understand
how you might not want to modify your driver to do this, which
is why I'm asking about making it optional. However,
your driver would probably benefit from receiving into
pages, and I encourage you to investigate that.
I'm picturing an additional path into lro, such as:
int lro_maybe_receive_frags(struct net_lro_mgr *lro_mgr,
struct skb_frag_struct *frags,
int len, void *priv);
This would return 0 if the packet was "accepted", and an
error if it was not. It would then call a modified
__lro_proc_skb() (perhaps better named __lro_proc_segment())
which would have the length as an argument (so as to avoid
the need to pass the skb to lro_tcp_ip_check()) in addition
to the *frags.
The only real additional work would be in having an alternate path
inside lro_init_desc() which allocated an skb to hang the pages from
if the passed skb was null, and in having an alternate
lro_add_packet() path which added the frag(s), rather than chaining an
skb.
Also, your patch does not seem to maintain TCP checksums.
To be fair, we did not maintain checksums in our earlier LRO
work either, and it was much simpler that way! :) However,
not maintaining the TCP checksum can lead to user complaints
(invalid csum reported by traffic sniffers), as well as problems
when various filtering software is used which attempts to
re-write the TCP header.
I would very much appreciate it if you could look at my LRO
implementation in our Myri10GE driver which has been
posted (and rejected) several times in the past by Brice.
The source code is also available at:
http://www.myri.com/ftp/pub/Myri10GE/myri10ge-linux.1.3.0.tgz.
It uses a page based approach, and it maintains correct TCP
checksums.
This driver is Dual BSD/GPL licensed, and you are free to take
whatever you like.
Thank you again for stepping up with a generic implementation!
Drew
^ permalink raw reply
* [PATCH 10/10] IB/ehca: Support large page MRs
From: Joachim Fenkes @ 2007-07-12 15:54 UTC (permalink / raw)
To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier
Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200707121745.27592.fenkes@de.ibm.com>
From: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Add support for MR pages larger than 4K on eHCA2. This reduces firmware
memory consumption. If enabled via the mr_largepage module parameter, the MR
page size will be determined based on the MR length and the hardware
capabilities - if the MR is >= 16M, 16M pages are used, for example.
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_classes.h | 10 +
drivers/infiniband/hw/ehca/ehca_main.c | 17 ++-
drivers/infiniband/hw/ehca/ehca_mrmw.c | 371 ++++++++++++++++++++++++-----
drivers/infiniband/hw/ehca/ehca_mrmw.h | 2 +-
drivers/infiniband/hw/ehca/hcp_if.c | 20 ++-
5 files changed, 357 insertions(+), 63 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 1752821..2a39cfa 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -105,6 +105,12 @@ struct ehca_sport {
};
#define EHCA_MAX_NR_EQS 512
+
+#define HCA_CAP_MR_PGSIZE_4K 1
+#define HCA_CAP_MR_PGSIZE_64K 2
+#define HCA_CAP_MR_PGSIZE_1M 4
+#define HCA_CAP_MR_PGSIZE_16M 8
+
struct ehca_shca {
struct ib_device ib_device;
struct ibmebus_dev *ibmebus_dev;
@@ -121,6 +127,8 @@ struct ehca_shca {
struct h_galpas galpas;
struct mutex modify_mutex;
u64 hca_cap;
+ /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */
+ u32 hca_cap_mr_pgsize;
int max_mtu;
atomic_t cur_eq_idx;
};
@@ -213,6 +221,7 @@ struct ehca_mr {
enum ehca_mr_flag flags;
u32 num_kpages; /* number of kernel pages */
u32 num_hwpages; /* number of hw pages to form MR */
+ u64 hwpage_size; /* hw page size used for this MR */
int acl; /* ACL (stored here for usage in reregister) */
u64 *start; /* virtual start address (stored here for */
/* usage in reregister) */
@@ -247,6 +256,7 @@ struct ehca_mr_pginfo {
enum ehca_mr_pgi_type type;
u64 num_kpages;
u64 kpage_cnt;
+ u64 hwpage_size; /* hw page size used for this MR */
u64 num_hwpages; /* number of hw pages */
u64 hwpage_cnt; /* counter for hw pages */
u64 next_hwpage; /* next hw page in buffer/chunk/listelem */
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index ecf4ef4..5f207f2 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -65,6 +65,7 @@ int ehca_static_rate = -1;
int ehca_scaling_code = 0;
int ehca_nr_eqs = 2;
int ehca_dist_eqs = 0;
+int ehca_mr_largepage = 0;
module_param_named(open_aqp1, ehca_open_aqp1, int, 0);
module_param_named(debug_level, ehca_debug_level, int, 0);
@@ -77,6 +78,7 @@ module_param_named(static_rate, ehca_static_rate, int, 0);
module_param_named(scaling_code, ehca_scaling_code, int, 0);
module_param_named(nr_eqs, ehca_nr_eqs, int, 0);
module_param_named(dist_eqs, ehca_dist_eqs, int, 0);
+module_param_named(mr_largepage, ehca_mr_largepage, int, 0);
MODULE_PARM_DESC(open_aqp1,
"AQP1 on startup (0: no (default), 1: yes)");
@@ -104,6 +106,9 @@ MODULE_PARM_DESC(nr_eqs,
MODULE_PARM_DESC(dist_eqs,
"enable distributing EQs across CQs "
"(0: disabled/default, 1: enabled)");
+MODULE_PARM_DESC(mr_largepage,
+ "use large page for MR (0: use PAGE_SIZE (default), "
+ "1: use large page depending on MR size");
DEFINE_RWLOCK(ehca_qp_idr_lock);
DEFINE_RWLOCK(ehca_cq_idr_lock);
@@ -314,6 +319,8 @@ int ehca_sense_attributes(struct ehca_shca *shca)
if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
ehca_gen_dbg(" %s", hca_cap_descr[i].descr);
+ shca->hca_cap_mr_pgsize = rblock->memory_page_size_supported;
+
port = (struct hipz_query_port *)rblock;
h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
if (h_ret != H_SUCCESS) {
@@ -609,13 +616,20 @@ static ssize_t ehca_show_adapter_handle(struct device *dev,
}
static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL);
+static ssize_t ehca_show_mr_largepage(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", ehca_mr_largepage);
+}
+static DEVICE_ATTR(mr_largepage, S_IRUGO, ehca_show_mr_largepage, NULL);
+
static ssize_t ehca_show_nr_eqs(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%d\n", ehca_nr_eqs);
}
-
static DEVICE_ATTR(nr_eqs, S_IRUGO, ehca_show_nr_eqs, NULL);
static struct attribute *ehca_dev_attrs[] = {
@@ -635,6 +649,7 @@ static struct attribute *ehca_dev_attrs[] = {
&dev_attr_max_pd.attr,
&dev_attr_max_ah.attr,
&dev_attr_nr_eqs.attr,
+ &dev_attr_mr_largepage.attr,
NULL
};
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index 6262c54..ba28783 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -5,6 +5,7 @@
*
* Authors: Dietmar Decker <ddecker@de.ibm.com>
* Christoph Raisch <raisch@de.ibm.com>
+ * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
*
* Copyright (c) 2005 IBM Corporation
*
@@ -56,6 +57,37 @@
static struct kmem_cache *mr_cache;
static struct kmem_cache *mw_cache;
+enum ehca_mr_pgsize {
+ EHCA_MR_PGSIZE4K = 0x1000L,
+ EHCA_MR_PGSIZE64K = 0x10000L,
+ EHCA_MR_PGSIZE1M = 0x100000L,
+ EHCA_MR_PGSIZE16M = 0x1000000L
+};
+
+extern int ehca_mr_largepage;
+
+static u32 ehca_encode_hwpage_size(u32 pgsize)
+{
+ u32 idx = 0;
+ pgsize >>= 12;
+ /*
+ * map mr page size into hw code:
+ * 0, 1, 2, 3 for 4K, 64K, 1M, 64M
+ */
+ while (!(pgsize & 1)) {
+ idx++;
+ pgsize >>= 4;
+ }
+ return idx;
+}
+
+static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca)
+{
+ if (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)
+ return EHCA_MR_PGSIZE16M;
+ return EHCA_MR_PGSIZE4K;
+}
+
static struct ehca_mr *ehca_mr_new(void)
{
struct ehca_mr *me;
@@ -207,19 +239,23 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
struct ehca_mr_pginfo pginfo;
u32 num_kpages;
u32 num_hwpages;
+ u64 hw_pgsize;
num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size,
PAGE_SIZE);
- num_hwpages = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE) +
- size, EHCA_PAGESIZE);
+ /* for kernel space we try most possible pgsize */
+ hw_pgsize = ehca_get_max_hwpage_size(shca);
+ num_hwpages = NUM_CHUNKS(((u64)iova_start % hw_pgsize) + size,
+ hw_pgsize);
memset(&pginfo, 0, sizeof(pginfo));
pginfo.type = EHCA_MR_PGI_PHYS;
pginfo.num_kpages = num_kpages;
+ pginfo.hwpage_size = hw_pgsize;
pginfo.num_hwpages = num_hwpages;
pginfo.u.phy.num_phys_buf = num_phys_buf;
pginfo.u.phy.phys_buf_array = phys_buf_array;
- pginfo.next_hwpage = (((u64)iova_start & ~PAGE_MASK) /
- EHCA_PAGESIZE);
+ pginfo.next_hwpage =
+ ((u64)iova_start & ~(hw_pgsize - 1)) / hw_pgsize;
ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags,
e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
@@ -259,6 +295,7 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
int ret;
u32 num_kpages;
u32 num_hwpages;
+ u64 hwpage_size;
if (!pd) {
ehca_gen_err("bad pd=%p", pd);
@@ -309,16 +346,32 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
/* determine number of MR pages */
num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE);
- num_hwpages = NUM_CHUNKS((virt % EHCA_PAGESIZE) + length,
- EHCA_PAGESIZE);
+ /* select proper hw_pgsize */
+ if (ehca_mr_largepage &&
+ (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)) {
+ if (length <= EHCA_MR_PGSIZE4K
+ && PAGE_SIZE == EHCA_MR_PGSIZE4K)
+ hwpage_size = EHCA_MR_PGSIZE4K;
+ else if (length <= EHCA_MR_PGSIZE64K)
+ hwpage_size = EHCA_MR_PGSIZE64K;
+ else if (length <= EHCA_MR_PGSIZE1M)
+ hwpage_size = EHCA_MR_PGSIZE1M;
+ else
+ hwpage_size = EHCA_MR_PGSIZE16M;
+ } else
+ hwpage_size = EHCA_MR_PGSIZE4K;
+ ehca_dbg(pd->device, "hwpage_size=%lx", hwpage_size);
+reg_user_mr_fallback:
+ num_hwpages = NUM_CHUNKS((virt % hwpage_size) + length, hwpage_size);
/* register MR on HCA */
memset(&pginfo, 0, sizeof(pginfo));
pginfo.type = EHCA_MR_PGI_USER;
+ pginfo.hwpage_size = hwpage_size;
pginfo.num_kpages = num_kpages;
pginfo.num_hwpages = num_hwpages;
pginfo.u.usr.region = e_mr->umem;
- pginfo.next_hwpage = e_mr->umem->offset / EHCA_PAGESIZE;
+ pginfo.next_hwpage = e_mr->umem->offset / hwpage_size;
pginfo.u.usr.next_chunk = list_prepare_entry(pginfo.u.usr.next_chunk,
(&e_mr->umem->chunk_list),
list);
@@ -326,6 +379,18 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags,
e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
&e_mr->ib.ib_mr.rkey);
+ if (ret == -EINVAL && pginfo.hwpage_size > PAGE_SIZE) {
+ ehca_warn(pd->device, "failed to register mr "
+ "with hwpage_size=%lx", hwpage_size);
+ ehca_info(pd->device, "try to register mr with "
+ "kpage_size=%lx", PAGE_SIZE);
+ /*
+ * this means kpages are not contiguous for a hw page
+ * try kernel page size as fallback solution
+ */
+ hwpage_size = PAGE_SIZE;
+ goto reg_user_mr_fallback;
+ }
if (ret) {
ib_mr = ERR_PTR(ret);
goto reg_user_mr_exit2;
@@ -452,6 +517,8 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
new_pd = container_of(mr->pd, struct ehca_pd, ib_pd);
if (mr_rereg_mask & IB_MR_REREG_TRANS) {
+ u64 hw_pgsize = ehca_get_max_hwpage_size(shca);
+
new_start = iova_start; /* change address */
/* check physical buffer list and calculate size */
ret = ehca_mr_chk_buf_and_calc_size(phys_buf_array,
@@ -468,16 +535,17 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
}
num_kpages = NUM_CHUNKS(((u64)new_start % PAGE_SIZE) +
new_size, PAGE_SIZE);
- num_hwpages = NUM_CHUNKS(((u64)new_start % EHCA_PAGESIZE) +
- new_size, EHCA_PAGESIZE);
+ num_hwpages = NUM_CHUNKS(((u64)new_start % hw_pgsize) +
+ new_size, hw_pgsize);
memset(&pginfo, 0, sizeof(pginfo));
pginfo.type = EHCA_MR_PGI_PHYS;
pginfo.num_kpages = num_kpages;
+ pginfo.hwpage_size = hw_pgsize;
pginfo.num_hwpages = num_hwpages;
pginfo.u.phy.num_phys_buf = num_phys_buf;
pginfo.u.phy.phys_buf_array = phys_buf_array;
- pginfo.next_hwpage = (((u64)iova_start & ~PAGE_MASK) /
- EHCA_PAGESIZE);
+ pginfo.next_hwpage =
+ ((u64)iova_start & ~(hw_pgsize - 1)) / hw_pgsize;
}
if (mr_rereg_mask & IB_MR_REREG_ACCESS)
new_acl = mr_access_flags;
@@ -709,6 +777,7 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
int ret;
u32 tmp_lkey, tmp_rkey;
struct ehca_mr_pginfo pginfo;
+ u64 hw_pgsize;
/* check other parameters */
if (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) &&
@@ -738,8 +807,8 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
ib_fmr = ERR_PTR(-EINVAL);
goto alloc_fmr_exit0;
}
- if (((1 << fmr_attr->page_shift) != EHCA_PAGESIZE) &&
- ((1 << fmr_attr->page_shift) != PAGE_SIZE)) {
+ hw_pgsize = ehca_get_max_hwpage_size(shca);
+ if ((1 << fmr_attr->page_shift) != hw_pgsize) {
ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x",
fmr_attr->page_shift);
ib_fmr = ERR_PTR(-EINVAL);
@@ -755,6 +824,10 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
/* register MR on HCA */
memset(&pginfo, 0, sizeof(pginfo));
+ /*
+ * pginfo.num_hwpages==0, ie register_rpages() will not be called
+ * but deferred to map_phys_fmr()
+ */
ret = ehca_reg_mr(shca, e_fmr, NULL,
fmr_attr->max_pages * (1 << fmr_attr->page_shift),
mr_access_flags, e_pd, &pginfo,
@@ -765,6 +838,7 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
}
/* successful */
+ e_fmr->hwpage_size = hw_pgsize;
e_fmr->fmr_page_size = 1 << fmr_attr->page_shift;
e_fmr->fmr_max_pages = fmr_attr->max_pages;
e_fmr->fmr_max_maps = fmr_attr->max_maps;
@@ -822,10 +896,12 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr,
memset(&pginfo, 0, sizeof(pginfo));
pginfo.type = EHCA_MR_PGI_FMR;
pginfo.num_kpages = list_len;
- pginfo.num_hwpages = list_len * (e_fmr->fmr_page_size / EHCA_PAGESIZE);
+ pginfo.hwpage_size = e_fmr->hwpage_size;
+ pginfo.num_hwpages =
+ list_len * e_fmr->fmr_page_size / pginfo.hwpage_size;
pginfo.u.fmr.page_list = page_list;
- pginfo.next_hwpage = ((iova & (e_fmr->fmr_page_size-1)) /
- EHCA_PAGESIZE);
+ pginfo.next_hwpage =
+ (iova & (e_fmr->fmr_page_size-1)) / pginfo.hwpage_size;
pginfo.u.fmr.fmr_pgsize = e_fmr->fmr_page_size;
ret = ehca_rereg_mr(shca, e_fmr, (u64 *)iova,
@@ -964,7 +1040,7 @@ int ehca_reg_mr(struct ehca_shca *shca,
struct ehca_mr_hipzout_parms hipzout;
ehca_mrmw_map_acl(acl, &hipz_acl);
- ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
+ ehca_mrmw_set_pgsize_hipz_acl(pginfo->hwpage_size, &hipz_acl);
if (ehca_use_hp_mr == 1)
hipz_acl |= 0x00000001;
@@ -987,6 +1063,7 @@ int ehca_reg_mr(struct ehca_shca *shca,
/* successful registration */
e_mr->num_kpages = pginfo->num_kpages;
e_mr->num_hwpages = pginfo->num_hwpages;
+ e_mr->hwpage_size = pginfo->hwpage_size;
e_mr->start = iova_start;
e_mr->size = size;
e_mr->acl = acl;
@@ -1029,6 +1106,9 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
u32 i;
u64 *kpage;
+ if (!pginfo->num_hwpages) /* in case of fmr */
+ return 0;
+
kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
if (!kpage) {
ehca_err(&shca->ib_device, "kpage alloc failed");
@@ -1036,7 +1116,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
goto ehca_reg_mr_rpages_exit0;
}
- /* max 512 pages per shot */
+ /* max MAX_RPAGES ehca mr pages per register call */
for (i = 0; i < NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES); i++) {
if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) {
@@ -1049,8 +1129,8 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
ret = ehca_set_pagebuf(pginfo, rnum, kpage);
if (ret) {
ehca_err(&shca->ib_device, "ehca_set_pagebuf "
- "bad rc, ret=%x rnum=%x kpage=%p",
- ret, rnum, kpage);
+ "bad rc, ret=%x rnum=%x kpage=%p",
+ ret, rnum, kpage);
goto ehca_reg_mr_rpages_exit1;
}
@@ -1065,9 +1145,10 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
} else
rpage = *kpage;
- h_ret = hipz_h_register_rpage_mr(shca->ipz_hca_handle, e_mr,
- 0, /* pagesize 4k */
- 0, rpage, rnum);
+ h_ret = hipz_h_register_rpage_mr(
+ shca->ipz_hca_handle, e_mr,
+ ehca_encode_hwpage_size(pginfo->hwpage_size),
+ 0, rpage, rnum);
if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) {
/*
@@ -1131,7 +1212,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
struct ehca_mr_hipzout_parms hipzout;
ehca_mrmw_map_acl(acl, &hipz_acl);
- ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
+ ehca_mrmw_set_pgsize_hipz_acl(pginfo->hwpage_size, &hipz_acl);
kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
if (!kpage) {
@@ -1182,6 +1263,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
*/
e_mr->num_kpages = pginfo->num_kpages;
e_mr->num_hwpages = pginfo->num_hwpages;
+ e_mr->hwpage_size = pginfo->hwpage_size;
e_mr->start = iova_start;
e_mr->size = size;
e_mr->acl = acl;
@@ -1268,13 +1350,14 @@ int ehca_rereg_mr(struct ehca_shca *shca,
/* set some MR values */
e_mr->flags = save_mr.flags;
+ e_mr->hwpage_size = save_mr.hwpage_size;
e_mr->fmr_page_size = save_mr.fmr_page_size;
e_mr->fmr_max_pages = save_mr.fmr_max_pages;
e_mr->fmr_max_maps = save_mr.fmr_max_maps;
e_mr->fmr_map_cnt = save_mr.fmr_map_cnt;
ret = ehca_reg_mr(shca, e_mr, iova_start, size, acl,
- e_pd, pginfo, lkey, rkey);
+ e_pd, pginfo, lkey, rkey);
if (ret) {
u32 offset = (u64)(&e_mr->flags) - (u64)e_mr;
memcpy(&e_mr->flags, &(save_mr.flags),
@@ -1355,6 +1438,7 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca,
/* set some MR values */
e_fmr->flags = save_fmr.flags;
+ e_fmr->hwpage_size = save_fmr.hwpage_size;
e_fmr->fmr_page_size = save_fmr.fmr_page_size;
e_fmr->fmr_max_pages = save_fmr.fmr_max_pages;
e_fmr->fmr_max_maps = save_fmr.fmr_max_maps;
@@ -1363,8 +1447,6 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca,
memset(&pginfo, 0, sizeof(pginfo));
pginfo.type = EHCA_MR_PGI_FMR;
- pginfo.num_kpages = 0;
- pginfo.num_hwpages = 0;
ret = ehca_reg_mr(shca, e_fmr, NULL,
(e_fmr->fmr_max_pages * e_fmr->fmr_page_size),
e_fmr->acl, e_pd, &pginfo, &tmp_lkey,
@@ -1373,7 +1455,6 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca,
u32 offset = (u64)(&e_fmr->flags) - (u64)e_fmr;
memcpy(&e_fmr->flags, &(save_mr.flags),
sizeof(struct ehca_mr) - offset);
- goto ehca_unmap_one_fmr_exit0;
}
ehca_unmap_one_fmr_exit0:
@@ -1401,7 +1482,7 @@ int ehca_reg_smr(struct ehca_shca *shca,
struct ehca_mr_hipzout_parms hipzout;
ehca_mrmw_map_acl(acl, &hipz_acl);
- ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
+ ehca_mrmw_set_pgsize_hipz_acl(e_origmr->hwpage_size, &hipz_acl);
h_ret = hipz_h_register_smr(shca->ipz_hca_handle, e_newmr, e_origmr,
(u64)iova_start, hipz_acl, e_pd->fw_pd,
@@ -1420,6 +1501,7 @@ int ehca_reg_smr(struct ehca_shca *shca,
/* successful registration */
e_newmr->num_kpages = e_origmr->num_kpages;
e_newmr->num_hwpages = e_origmr->num_hwpages;
+ e_newmr->hwpage_size = e_origmr->hwpage_size;
e_newmr->start = iova_start;
e_newmr->size = e_origmr->size;
e_newmr->acl = acl;
@@ -1452,6 +1534,7 @@ int ehca_reg_internal_maxmr(
struct ib_phys_buf ib_pbuf;
u32 num_kpages;
u32 num_hwpages;
+ u64 hw_pgsize;
e_mr = ehca_mr_new();
if (!e_mr) {
@@ -1468,13 +1551,15 @@ int ehca_reg_internal_maxmr(
ib_pbuf.size = size_maxmr;
num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr,
PAGE_SIZE);
- num_hwpages = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE) + size_maxmr,
- EHCA_PAGESIZE);
+ hw_pgsize = ehca_get_max_hwpage_size(shca);
+ num_hwpages = NUM_CHUNKS(((u64)iova_start % hw_pgsize) + size_maxmr,
+ hw_pgsize);
memset(&pginfo, 0, sizeof(pginfo));
pginfo.type = EHCA_MR_PGI_PHYS;
pginfo.num_kpages = num_kpages;
pginfo.num_hwpages = num_hwpages;
+ pginfo.hwpage_size = hw_pgsize;
pginfo.u.phy.num_phys_buf = 1;
pginfo.u.phy.phys_buf_array = &ib_pbuf;
@@ -1523,7 +1608,7 @@ int ehca_reg_maxmr(struct ehca_shca *shca,
struct ehca_mr_hipzout_parms hipzout;
ehca_mrmw_map_acl(acl, &hipz_acl);
- ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
+ ehca_mrmw_set_pgsize_hipz_acl(e_origmr->hwpage_size, &hipz_acl);
h_ret = hipz_h_register_smr(shca->ipz_hca_handle, e_newmr, e_origmr,
(u64)iova_start, hipz_acl, e_pd->fw_pd,
@@ -1539,6 +1624,7 @@ int ehca_reg_maxmr(struct ehca_shca *shca,
/* successful registration */
e_newmr->num_kpages = e_origmr->num_kpages;
e_newmr->num_hwpages = e_origmr->num_hwpages;
+ e_newmr->hwpage_size = e_origmr->hwpage_size;
e_newmr->start = iova_start;
e_newmr->size = e_origmr->size;
e_newmr->acl = acl;
@@ -1684,6 +1770,7 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo,
u64 pgaddr;
u32 i = 0;
u32 j = 0;
+ int hwpages_per_kpage = PAGE_SIZE / pginfo->hwpage_size;
/* loop over desired chunk entries */
chunk = pginfo->u.usr.next_chunk;
@@ -1695,7 +1782,7 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo,
<< PAGE_SHIFT ;
*kpage = phys_to_abs(pgaddr +
(pginfo->next_hwpage *
- EHCA_PAGESIZE));
+ pginfo->hwpage_size));
if ( !(*kpage) ) {
ehca_gen_err("pgaddr=%lx "
"chunk->page_list[i]=%lx "
@@ -1708,8 +1795,7 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo,
(pginfo->hwpage_cnt)++;
(pginfo->next_hwpage)++;
kpage++;
- if (pginfo->next_hwpage %
- (PAGE_SIZE / EHCA_PAGESIZE) == 0) {
+ if (pginfo->next_hwpage % hwpages_per_kpage == 0) {
(pginfo->kpage_cnt)++;
(pginfo->u.usr.next_nmap)++;
pginfo->next_hwpage = 0;
@@ -1738,6 +1824,143 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo,
return ret;
}
+/*
+ * check given pages for contiguous layout
+ * last page addr is returned in prev_pgaddr for further check
+ */
+static int ehca_check_kpages_per_ate(struct scatterlist *page_list,
+ int start_idx, int end_idx,
+ u64 *prev_pgaddr)
+{
+ int t;
+ for (t = start_idx; t <= end_idx; t++) {
+ u64 pgaddr = page_to_pfn(page_list[t].page) << PAGE_SHIFT;
+ ehca_gen_dbg("chunk_page=%lx value=%016lx", pgaddr,
+ *(u64 *)abs_to_virt(phys_to_abs(pgaddr)));
+ if (pgaddr - PAGE_SIZE != *prev_pgaddr) {
+ ehca_gen_err("uncontiguous page found pgaddr=%lx "
+ "prev_pgaddr=%lx page_list_i=%x",
+ pgaddr, *prev_pgaddr, t);
+ return -EINVAL;
+ }
+ *prev_pgaddr = pgaddr;
+ }
+ return 0;
+}
+
+/* PAGE_SIZE < pginfo->hwpage_size */
+static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo,
+ u32 number,
+ u64 *kpage)
+{
+ int ret = 0;
+ struct ib_umem_chunk *prev_chunk;
+ struct ib_umem_chunk *chunk;
+ u64 pgaddr, prev_pgaddr;
+ u32 i = 0;
+ u32 j = 0;
+ int kpages_per_hwpage = pginfo->hwpage_size / PAGE_SIZE;
+ int nr_kpages = kpages_per_hwpage;
+
+ /* loop over desired chunk entries */
+ chunk = pginfo->u.usr.next_chunk;
+ prev_chunk = pginfo->u.usr.next_chunk;
+ list_for_each_entry_continue(
+ chunk, (&(pginfo->u.usr.region->chunk_list)), list) {
+ for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) {
+ if (nr_kpages == kpages_per_hwpage) {
+ pgaddr = ( page_to_pfn(chunk->page_list[i].page)
+ << PAGE_SHIFT );
+ *kpage = phys_to_abs(pgaddr);
+ if ( !(*kpage) ) {
+ ehca_gen_err("pgaddr=%lx i=%x",
+ pgaddr, i);
+ ret = -EFAULT;
+ return ret;
+ }
+ /*
+ * The first page in a hwpage must be aligned;
+ * the first MR page is exempt from this rule.
+ */
+ if (pgaddr & (pginfo->hwpage_size - 1)) {
+ if (pginfo->hwpage_cnt) {
+ ehca_gen_err(
+ "invalid alignment "
+ "pgaddr=%lx i=%x "
+ "mr_pgsize=%lx",
+ pgaddr, i,
+ pginfo->hwpage_size);
+ ret = -EFAULT;
+ return ret;
+ }
+ /* first MR page */
+ pginfo->kpage_cnt =
+ (pgaddr &
+ (pginfo->hwpage_size - 1)) >>
+ PAGE_SHIFT;
+ nr_kpages -= pginfo->kpage_cnt;
+ *kpage = phys_to_abs(
+ pgaddr &
+ ~(pginfo->hwpage_size - 1));
+ }
+ ehca_gen_dbg("kpage=%lx chunk_page=%lx "
+ "value=%016lx", *kpage, pgaddr,
+ *(u64 *)abs_to_virt(
+ phys_to_abs(pgaddr)));
+ prev_pgaddr = pgaddr;
+ i++;
+ pginfo->kpage_cnt++;
+ pginfo->u.usr.next_nmap++;
+ nr_kpages--;
+ if (!nr_kpages)
+ goto next_kpage;
+ continue;
+ }
+ if (i + nr_kpages > chunk->nmap) {
+ ret = ehca_check_kpages_per_ate(
+ chunk->page_list, i,
+ chunk->nmap - 1, &prev_pgaddr);
+ if (ret) return ret;
+ pginfo->kpage_cnt += chunk->nmap - i;
+ pginfo->u.usr.next_nmap += chunk->nmap - i;
+ nr_kpages -= chunk->nmap - i;
+ break;
+ }
+
+ ret = ehca_check_kpages_per_ate(chunk->page_list, i,
+ i + nr_kpages - 1,
+ &prev_pgaddr);
+ if (ret) return ret;
+ i += nr_kpages;
+ pginfo->kpage_cnt += nr_kpages;
+ pginfo->u.usr.next_nmap += nr_kpages;
+next_kpage:
+ nr_kpages = kpages_per_hwpage;
+ (pginfo->hwpage_cnt)++;
+ kpage++;
+ j++;
+ if (j >= number) break;
+ }
+ if ((pginfo->u.usr.next_nmap >= chunk->nmap) &&
+ (j >= number)) {
+ pginfo->u.usr.next_nmap = 0;
+ prev_chunk = chunk;
+ break;
+ } else if (pginfo->u.usr.next_nmap >= chunk->nmap) {
+ pginfo->u.usr.next_nmap = 0;
+ prev_chunk = chunk;
+ } else if (j >= number)
+ break;
+ else
+ prev_chunk = chunk;
+ }
+ pginfo->u.usr.next_chunk =
+ list_prepare_entry(prev_chunk,
+ (&(pginfo->u.usr.region->chunk_list)),
+ list);
+ return ret;
+}
+
int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo,
u32 number,
u64 *kpage)
@@ -1750,9 +1973,10 @@ int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo,
/* loop over desired phys_buf_array entries */
while (i < number) {
pbuf = pginfo->u.phy.phys_buf_array + pginfo->u.phy.next_buf;
- num_hw = NUM_CHUNKS((pbuf->addr % EHCA_PAGESIZE) +
- pbuf->size, EHCA_PAGESIZE);
- offs_hw = (pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
+ num_hw = NUM_CHUNKS((pbuf->addr % pginfo->hwpage_size) +
+ pbuf->size, pginfo->hwpage_size);
+ offs_hw = (pbuf->addr & ~(pginfo->hwpage_size - 1)) /
+ pginfo->hwpage_size;
while (pginfo->next_hwpage < offs_hw + num_hw) {
/* sanity check */
if ((pginfo->kpage_cnt >= pginfo->num_kpages) ||
@@ -1768,21 +1992,23 @@ int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo,
return -EFAULT;
}
*kpage = phys_to_abs(
- (pbuf->addr & EHCA_PAGEMASK)
- + (pginfo->next_hwpage * EHCA_PAGESIZE));
+ (pbuf->addr & ~(pginfo->hwpage_size - 1)) +
+ (pginfo->next_hwpage * pginfo->hwpage_size));
if ( !(*kpage) && pbuf->addr ) {
- ehca_gen_err("pbuf->addr=%lx "
- "pbuf->size=%lx "
+ ehca_gen_err("pbuf->addr=%lx pbuf->size=%lx "
"next_hwpage=%lx", pbuf->addr,
- pbuf->size,
- pginfo->next_hwpage);
+ pbuf->size, pginfo->next_hwpage);
return -EFAULT;
}
(pginfo->hwpage_cnt)++;
(pginfo->next_hwpage)++;
- if (pginfo->next_hwpage %
- (PAGE_SIZE / EHCA_PAGESIZE) == 0)
- (pginfo->kpage_cnt)++;
+ if (PAGE_SIZE >= pginfo->hwpage_size) {
+ if (pginfo->next_hwpage %
+ (PAGE_SIZE / pginfo->hwpage_size) == 0)
+ (pginfo->kpage_cnt)++;
+ } else
+ pginfo->kpage_cnt += pginfo->hwpage_size /
+ PAGE_SIZE;
kpage++;
i++;
if (i >= number) break;
@@ -1806,8 +2032,8 @@ int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo,
/* loop over desired page_list entries */
fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem;
for (i = 0; i < number; i++) {
- *kpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) +
- pginfo->next_hwpage * EHCA_PAGESIZE);
+ *kpage = phys_to_abs((*fmrlist & ~(pginfo->hwpage_size - 1)) +
+ pginfo->next_hwpage * pginfo->hwpage_size);
if ( !(*kpage) ) {
ehca_gen_err("*fmrlist=%lx fmrlist=%p "
"next_listelem=%lx next_hwpage=%lx",
@@ -1817,15 +2043,38 @@ int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo,
return -EFAULT;
}
(pginfo->hwpage_cnt)++;
- (pginfo->next_hwpage)++;
- kpage++;
- if (pginfo->next_hwpage %
- (pginfo->u.fmr.fmr_pgsize / EHCA_PAGESIZE) == 0) {
- (pginfo->kpage_cnt)++;
- (pginfo->u.fmr.next_listelem)++;
- fmrlist++;
- pginfo->next_hwpage = 0;
+ if (pginfo->u.fmr.fmr_pgsize >= pginfo->hwpage_size) {
+ if (pginfo->next_hwpage %
+ (pginfo->u.fmr.fmr_pgsize /
+ pginfo->hwpage_size) == 0) {
+ (pginfo->kpage_cnt)++;
+ (pginfo->u.fmr.next_listelem)++;
+ fmrlist++;
+ pginfo->next_hwpage = 0;
+ } else
+ (pginfo->next_hwpage)++;
+ } else {
+ unsigned int cnt_per_hwpage = pginfo->hwpage_size /
+ pginfo->u.fmr.fmr_pgsize;
+ unsigned int j;
+ u64 prev = *kpage;
+ /* check if adrs are contiguous */
+ for (j = 1; j < cnt_per_hwpage; j++) {
+ u64 p = phys_to_abs(fmrlist[j] &
+ ~(pginfo->hwpage_size - 1));
+ if (prev + pginfo->u.fmr.fmr_pgsize != p) {
+ ehca_gen_err("uncontiguous fmr pages "
+ "found prev=%lx p=%lx "
+ "idx=%x", prev, p, i + j);
+ return -EINVAL;
+ }
+ prev = p;
+ }
+ pginfo->kpage_cnt += cnt_per_hwpage;
+ pginfo->u.fmr.next_listelem += cnt_per_hwpage;
+ fmrlist += cnt_per_hwpage;
}
+ kpage++;
}
return ret;
}
@@ -1842,7 +2091,9 @@ int ehca_set_pagebuf(struct ehca_mr_pginfo *pginfo,
ret = ehca_set_pagebuf_phys(pginfo, number, kpage);
break;
case EHCA_MR_PGI_USER:
- ret = ehca_set_pagebuf_user1(pginfo, number, kpage);
+ ret = PAGE_SIZE >= pginfo->hwpage_size ?
+ ehca_set_pagebuf_user1(pginfo, number, kpage) :
+ ehca_set_pagebuf_user2(pginfo, number, kpage);
break;
case EHCA_MR_PGI_FMR:
ret = ehca_set_pagebuf_fmr(pginfo, number, kpage);
@@ -1895,9 +2146,9 @@ void ehca_mrmw_map_acl(int ib_acl,
/*----------------------------------------------------------------------*/
/* sets page size in hipz access control for MR/MW. */
-void ehca_mrmw_set_pgsize_hipz_acl(u32 *hipz_acl) /*INOUT*/
+void ehca_mrmw_set_pgsize_hipz_acl(u32 pgsize, u32 *hipz_acl) /*INOUT*/
{
- return; /* HCA supports only 4k */
+ *hipz_acl |= (ehca_encode_hwpage_size(pgsize) << 24);
} /* end ehca_mrmw_set_pgsize_hipz_acl() */
/*----------------------------------------------------------------------*/
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.h b/drivers/infiniband/hw/ehca/ehca_mrmw.h
index 24f13fe..bc8f4e3 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.h
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.h
@@ -111,7 +111,7 @@ int ehca_mr_is_maxmr(u64 size,
void ehca_mrmw_map_acl(int ib_acl,
u32 *hipz_acl);
-void ehca_mrmw_set_pgsize_hipz_acl(u32 *hipz_acl);
+void ehca_mrmw_set_pgsize_hipz_acl(u32 pgsize, u32 *hipz_acl);
void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl,
int *ib_acl);
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
index 3394e05..358796c 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -427,7 +427,8 @@ u64 hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle,
{
return ehca_plpar_hcall_norets(H_REGISTER_RPAGES,
adapter_handle.handle, /* r4 */
- queue_type | pagesize << 8, /* r5 */
+ (u64)queue_type | ((u64)pagesize) << 8,
+ /* r5 */
resource_handle, /* r6 */
logical_address_of_page, /* r7 */
count, /* r8 */
@@ -724,6 +725,9 @@ u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle,
u64 ret;
u64 outs[PLPAR_HCALL9_BUFSIZE];
+ ehca_gen_dbg("kernel PAGE_SIZE=%x access_ctrl=%016x "
+ "vaddr=%lx length=%lx",
+ (u32)PAGE_SIZE, access_ctrl, vaddr, length);
ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
adapter_handle.handle, /* r4 */
5, /* r5 */
@@ -746,8 +750,22 @@ u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle,
const u64 logical_address_of_page,
const u64 count)
{
+ extern int ehca_debug_level;
u64 ret;
+ if (unlikely(ehca_debug_level >= 2)) {
+ if (count > 1) {
+ u64 *kpage;
+ int i;
+ kpage = (u64 *)abs_to_virt(logical_address_of_page);
+ for (i = 0; i < count; i++)
+ ehca_gen_dbg("kpage[%d]=%p",
+ i, (void *)kpage[i]);
+ } else
+ ehca_gen_dbg("kpage=%p",
+ (void *)logical_address_of_page);
+ }
+
if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) {
ehca_gen_err("logical_address_of_page not on a 4k boundary "
"adapter_handle=%lx mr=%p mr_handle=%lx "
--
1.5.2
^ permalink raw reply related
* [PATCH 09/10] IB/ehca: Fix warnings issued by checkpatch.pl
From: Joachim Fenkes @ 2007-07-12 15:53 UTC (permalink / raw)
To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier
Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200707121745.27592.fenkes@de.ibm.com>
From: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_av.c | 2 +-
drivers/infiniband/hw/ehca/ehca_classes.h | 4 +-
drivers/infiniband/hw/ehca/ehca_classes_pSeries.h | 156 ++++++++++----------
drivers/infiniband/hw/ehca/ehca_cq.c | 2 +-
drivers/infiniband/hw/ehca/ehca_eq.c | 3 +-
drivers/infiniband/hw/ehca/ehca_hca.c | 28 +++-
drivers/infiniband/hw/ehca/ehca_irq.c | 56 ++++----
drivers/infiniband/hw/ehca/ehca_iverbs.h | 7 +-
drivers/infiniband/hw/ehca/ehca_main.c | 21 ++--
drivers/infiniband/hw/ehca/ehca_mrmw.c | 59 ++++----
drivers/infiniband/hw/ehca/ehca_mrmw.h | 7 +-
drivers/infiniband/hw/ehca/ehca_qes.h | 22 ++--
drivers/infiniband/hw/ehca/ehca_qp.c | 39 +++---
drivers/infiniband/hw/ehca/ehca_reqs.c | 15 ++-
drivers/infiniband/hw/ehca/ehca_tools.h | 28 ++--
drivers/infiniband/hw/ehca/ehca_uverbs.c | 10 +-
drivers/infiniband/hw/ehca/hcp_if.c | 8 +-
drivers/infiniband/hw/ehca/hcp_phyp.c | 2 +-
drivers/infiniband/hw/ehca/hipz_fns_core.h | 4 +-
drivers/infiniband/hw/ehca/hipz_hw.h | 24 ++--
drivers/infiniband/hw/ehca/ipz_pt_fn.c | 2 +-
drivers/infiniband/hw/ehca/ipz_pt_fn.h | 4 +-
22 files changed, 261 insertions(+), 242 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c
index 3cd6bf3..e53a97a 100644
--- a/drivers/infiniband/hw/ehca/ehca_av.c
+++ b/drivers/infiniband/hw/ehca/ehca_av.c
@@ -79,7 +79,7 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
av->av.ipd = (ah_mult > 0) ?
((ehca_mult - 1) / ah_mult) : 0;
} else
- av->av.ipd = ehca_static_rate;
+ av->av.ipd = ehca_static_rate;
av->av.lnh = ah_attr->ah_flags;
av->av.grh.word_0 = EHCA_BMASK_SET(GRH_IPVERSION_MASK, 6);
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 92103df..1752821 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -215,7 +215,7 @@ struct ehca_mr {
u32 num_hwpages; /* number of hw pages to form MR */
int acl; /* ACL (stored here for usage in reregister) */
u64 *start; /* virtual start address (stored here for */
- /* usage in reregister) */
+ /* usage in reregister) */
u64 size; /* size (stored here for usage in reregister) */
u32 fmr_page_size; /* page size for FMR */
u32 fmr_max_pages; /* max pages for FMR */
@@ -400,6 +400,6 @@ struct ehca_alloc_qp_parms {
int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp);
int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int qp_num);
-struct ehca_qp* ehca_cq_get_qp(struct ehca_cq *cq, int qp_num);
+struct ehca_qp *ehca_cq_get_qp(struct ehca_cq *cq, int qp_num);
#endif
diff --git a/drivers/infiniband/hw/ehca/ehca_classes_pSeries.h b/drivers/infiniband/hw/ehca/ehca_classes_pSeries.h
index fb3df5c..1798e64 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes_pSeries.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes_pSeries.h
@@ -154,83 +154,83 @@ struct hcp_modify_qp_control_block {
u32 reserved_70_127[58]; /* 70 */
};
-#define MQPCB_MASK_QKEY EHCA_BMASK_IBM(0,0)
-#define MQPCB_MASK_SEND_PSN EHCA_BMASK_IBM(2,2)
-#define MQPCB_MASK_RECEIVE_PSN EHCA_BMASK_IBM(3,3)
-#define MQPCB_MASK_PRIM_PHYS_PORT EHCA_BMASK_IBM(4,4)
-#define MQPCB_PRIM_PHYS_PORT EHCA_BMASK_IBM(24,31)
-#define MQPCB_MASK_ALT_PHYS_PORT EHCA_BMASK_IBM(5,5)
-#define MQPCB_MASK_PRIM_P_KEY_IDX EHCA_BMASK_IBM(6,6)
-#define MQPCB_PRIM_P_KEY_IDX EHCA_BMASK_IBM(24,31)
-#define MQPCB_MASK_ALT_P_KEY_IDX EHCA_BMASK_IBM(7,7)
-#define MQPCB_MASK_RDMA_ATOMIC_CTRL EHCA_BMASK_IBM(8,8)
-#define MQPCB_MASK_QP_STATE EHCA_BMASK_IBM(9,9)
-#define MQPCB_QP_STATE EHCA_BMASK_IBM(24,31)
-#define MQPCB_MASK_RDMA_NR_ATOMIC_RESP_RES EHCA_BMASK_IBM(11,11)
-#define MQPCB_MASK_PATH_MIGRATION_STATE EHCA_BMASK_IBM(12,12)
-#define MQPCB_MASK_RDMA_ATOMIC_OUTST_DEST_QP EHCA_BMASK_IBM(13,13)
-#define MQPCB_MASK_DEST_QP_NR EHCA_BMASK_IBM(14,14)
-#define MQPCB_MASK_MIN_RNR_NAK_TIMER_FIELD EHCA_BMASK_IBM(15,15)
-#define MQPCB_MASK_SERVICE_LEVEL EHCA_BMASK_IBM(16,16)
-#define MQPCB_MASK_SEND_GRH_FLAG EHCA_BMASK_IBM(17,17)
-#define MQPCB_MASK_RETRY_COUNT EHCA_BMASK_IBM(18,18)
-#define MQPCB_MASK_TIMEOUT EHCA_BMASK_IBM(19,19)
-#define MQPCB_MASK_PATH_MTU EHCA_BMASK_IBM(20,20)
-#define MQPCB_PATH_MTU EHCA_BMASK_IBM(24,31)
-#define MQPCB_MASK_MAX_STATIC_RATE EHCA_BMASK_IBM(21,21)
-#define MQPCB_MAX_STATIC_RATE EHCA_BMASK_IBM(24,31)
-#define MQPCB_MASK_DLID EHCA_BMASK_IBM(22,22)
-#define MQPCB_DLID EHCA_BMASK_IBM(16,31)
-#define MQPCB_MASK_RNR_RETRY_COUNT EHCA_BMASK_IBM(23,23)
-#define MQPCB_RNR_RETRY_COUNT EHCA_BMASK_IBM(29,31)
-#define MQPCB_MASK_SOURCE_PATH_BITS EHCA_BMASK_IBM(24,24)
-#define MQPCB_SOURCE_PATH_BITS EHCA_BMASK_IBM(25,31)
-#define MQPCB_MASK_TRAFFIC_CLASS EHCA_BMASK_IBM(25,25)
-#define MQPCB_TRAFFIC_CLASS EHCA_BMASK_IBM(24,31)
-#define MQPCB_MASK_HOP_LIMIT EHCA_BMASK_IBM(26,26)
-#define MQPCB_HOP_LIMIT EHCA_BMASK_IBM(24,31)
-#define MQPCB_MASK_SOURCE_GID_IDX EHCA_BMASK_IBM(27,27)
-#define MQPCB_SOURCE_GID_IDX EHCA_BMASK_IBM(24,31)
-#define MQPCB_MASK_FLOW_LABEL EHCA_BMASK_IBM(28,28)
-#define MQPCB_FLOW_LABEL EHCA_BMASK_IBM(12,31)
-#define MQPCB_MASK_DEST_GID EHCA_BMASK_IBM(30,30)
-#define MQPCB_MASK_SERVICE_LEVEL_AL EHCA_BMASK_IBM(31,31)
-#define MQPCB_SERVICE_LEVEL_AL EHCA_BMASK_IBM(28,31)
-#define MQPCB_MASK_SEND_GRH_FLAG_AL EHCA_BMASK_IBM(32,32)
-#define MQPCB_SEND_GRH_FLAG_AL EHCA_BMASK_IBM(31,31)
-#define MQPCB_MASK_RETRY_COUNT_AL EHCA_BMASK_IBM(33,33)
-#define MQPCB_RETRY_COUNT_AL EHCA_BMASK_IBM(29,31)
-#define MQPCB_MASK_TIMEOUT_AL EHCA_BMASK_IBM(34,34)
-#define MQPCB_TIMEOUT_AL EHCA_BMASK_IBM(27,31)
-#define MQPCB_MASK_MAX_STATIC_RATE_AL EHCA_BMASK_IBM(35,35)
-#define MQPCB_MAX_STATIC_RATE_AL EHCA_BMASK_IBM(24,31)
-#define MQPCB_MASK_DLID_AL EHCA_BMASK_IBM(36,36)
-#define MQPCB_DLID_AL EHCA_BMASK_IBM(16,31)
-#define MQPCB_MASK_RNR_RETRY_COUNT_AL EHCA_BMASK_IBM(37,37)
-#define MQPCB_RNR_RETRY_COUNT_AL EHCA_BMASK_IBM(29,31)
-#define MQPCB_MASK_SOURCE_PATH_BITS_AL EHCA_BMASK_IBM(38,38)
-#define MQPCB_SOURCE_PATH_BITS_AL EHCA_BMASK_IBM(25,31)
-#define MQPCB_MASK_TRAFFIC_CLASS_AL EHCA_BMASK_IBM(39,39)
-#define MQPCB_TRAFFIC_CLASS_AL EHCA_BMASK_IBM(24,31)
-#define MQPCB_MASK_HOP_LIMIT_AL EHCA_BMASK_IBM(40,40)
-#define MQPCB_HOP_LIMIT_AL EHCA_BMASK_IBM(24,31)
-#define MQPCB_MASK_SOURCE_GID_IDX_AL EHCA_BMASK_IBM(41,41)
-#define MQPCB_SOURCE_GID_IDX_AL EHCA_BMASK_IBM(24,31)
-#define MQPCB_MASK_FLOW_LABEL_AL EHCA_BMASK_IBM(42,42)
-#define MQPCB_FLOW_LABEL_AL EHCA_BMASK_IBM(12,31)
-#define MQPCB_MASK_DEST_GID_AL EHCA_BMASK_IBM(44,44)
-#define MQPCB_MASK_MAX_NR_OUTST_SEND_WR EHCA_BMASK_IBM(45,45)
-#define MQPCB_MAX_NR_OUTST_SEND_WR EHCA_BMASK_IBM(16,31)
-#define MQPCB_MASK_MAX_NR_OUTST_RECV_WR EHCA_BMASK_IBM(46,46)
-#define MQPCB_MAX_NR_OUTST_RECV_WR EHCA_BMASK_IBM(16,31)
-#define MQPCB_MASK_DISABLE_ETE_CREDIT_CHECK EHCA_BMASK_IBM(47,47)
-#define MQPCB_DISABLE_ETE_CREDIT_CHECK EHCA_BMASK_IBM(31,31)
-#define MQPCB_QP_NUMBER EHCA_BMASK_IBM(8,31)
-#define MQPCB_MASK_QP_ENABLE EHCA_BMASK_IBM(48,48)
-#define MQPCB_QP_ENABLE EHCA_BMASK_IBM(31,31)
-#define MQPCB_MASK_CURR_SRQ_LIMIT EHCA_BMASK_IBM(49,49)
-#define MQPCB_CURR_SRQ_LIMIT EHCA_BMASK_IBM(16,31)
-#define MQPCB_MASK_QP_AFF_ASYN_EV_LOG_REG EHCA_BMASK_IBM(50,50)
-#define MQPCB_MASK_SHARED_RQ_HNDL EHCA_BMASK_IBM(51,51)
+#define MQPCB_MASK_QKEY EHCA_BMASK_IBM( 0, 0)
+#define MQPCB_MASK_SEND_PSN EHCA_BMASK_IBM( 2, 2)
+#define MQPCB_MASK_RECEIVE_PSN EHCA_BMASK_IBM( 3, 3)
+#define MQPCB_MASK_PRIM_PHYS_PORT EHCA_BMASK_IBM( 4, 4)
+#define MQPCB_PRIM_PHYS_PORT EHCA_BMASK_IBM(24, 31)
+#define MQPCB_MASK_ALT_PHYS_PORT EHCA_BMASK_IBM( 5, 5)
+#define MQPCB_MASK_PRIM_P_KEY_IDX EHCA_BMASK_IBM( 6, 6)
+#define MQPCB_PRIM_P_KEY_IDX EHCA_BMASK_IBM(24, 31)
+#define MQPCB_MASK_ALT_P_KEY_IDX EHCA_BMASK_IBM( 7, 7)
+#define MQPCB_MASK_RDMA_ATOMIC_CTRL EHCA_BMASK_IBM( 8, 8)
+#define MQPCB_MASK_QP_STATE EHCA_BMASK_IBM( 9, 9)
+#define MQPCB_QP_STATE EHCA_BMASK_IBM(24, 31)
+#define MQPCB_MASK_RDMA_NR_ATOMIC_RESP_RES EHCA_BMASK_IBM(11, 11)
+#define MQPCB_MASK_PATH_MIGRATION_STATE EHCA_BMASK_IBM(12, 12)
+#define MQPCB_MASK_RDMA_ATOMIC_OUTST_DEST_QP EHCA_BMASK_IBM(13, 13)
+#define MQPCB_MASK_DEST_QP_NR EHCA_BMASK_IBM(14, 14)
+#define MQPCB_MASK_MIN_RNR_NAK_TIMER_FIELD EHCA_BMASK_IBM(15, 15)
+#define MQPCB_MASK_SERVICE_LEVEL EHCA_BMASK_IBM(16, 16)
+#define MQPCB_MASK_SEND_GRH_FLAG EHCA_BMASK_IBM(17, 17)
+#define MQPCB_MASK_RETRY_COUNT EHCA_BMASK_IBM(18, 18)
+#define MQPCB_MASK_TIMEOUT EHCA_BMASK_IBM(19, 19)
+#define MQPCB_MASK_PATH_MTU EHCA_BMASK_IBM(20, 20)
+#define MQPCB_PATH_MTU EHCA_BMASK_IBM(24, 31)
+#define MQPCB_MASK_MAX_STATIC_RATE EHCA_BMASK_IBM(21, 21)
+#define MQPCB_MAX_STATIC_RATE EHCA_BMASK_IBM(24, 31)
+#define MQPCB_MASK_DLID EHCA_BMASK_IBM(22, 22)
+#define MQPCB_DLID EHCA_BMASK_IBM(16, 31)
+#define MQPCB_MASK_RNR_RETRY_COUNT EHCA_BMASK_IBM(23, 23)
+#define MQPCB_RNR_RETRY_COUNT EHCA_BMASK_IBM(29, 31)
+#define MQPCB_MASK_SOURCE_PATH_BITS EHCA_BMASK_IBM(24, 24)
+#define MQPCB_SOURCE_PATH_BITS EHCA_BMASK_IBM(25, 31)
+#define MQPCB_MASK_TRAFFIC_CLASS EHCA_BMASK_IBM(25, 25)
+#define MQPCB_TRAFFIC_CLASS EHCA_BMASK_IBM(24, 31)
+#define MQPCB_MASK_HOP_LIMIT EHCA_BMASK_IBM(26, 26)
+#define MQPCB_HOP_LIMIT EHCA_BMASK_IBM(24, 31)
+#define MQPCB_MASK_SOURCE_GID_IDX EHCA_BMASK_IBM(27, 27)
+#define MQPCB_SOURCE_GID_IDX EHCA_BMASK_IBM(24, 31)
+#define MQPCB_MASK_FLOW_LABEL EHCA_BMASK_IBM(28, 28)
+#define MQPCB_FLOW_LABEL EHCA_BMASK_IBM(12, 31)
+#define MQPCB_MASK_DEST_GID EHCA_BMASK_IBM(30, 30)
+#define MQPCB_MASK_SERVICE_LEVEL_AL EHCA_BMASK_IBM(31, 31)
+#define MQPCB_SERVICE_LEVEL_AL EHCA_BMASK_IBM(28, 31)
+#define MQPCB_MASK_SEND_GRH_FLAG_AL EHCA_BMASK_IBM(32, 32)
+#define MQPCB_SEND_GRH_FLAG_AL EHCA_BMASK_IBM(31, 31)
+#define MQPCB_MASK_RETRY_COUNT_AL EHCA_BMASK_IBM(33, 33)
+#define MQPCB_RETRY_COUNT_AL EHCA_BMASK_IBM(29, 31)
+#define MQPCB_MASK_TIMEOUT_AL EHCA_BMASK_IBM(34, 34)
+#define MQPCB_TIMEOUT_AL EHCA_BMASK_IBM(27, 31)
+#define MQPCB_MASK_MAX_STATIC_RATE_AL EHCA_BMASK_IBM(35, 35)
+#define MQPCB_MAX_STATIC_RATE_AL EHCA_BMASK_IBM(24, 31)
+#define MQPCB_MASK_DLID_AL EHCA_BMASK_IBM(36, 36)
+#define MQPCB_DLID_AL EHCA_BMASK_IBM(16, 31)
+#define MQPCB_MASK_RNR_RETRY_COUNT_AL EHCA_BMASK_IBM(37, 37)
+#define MQPCB_RNR_RETRY_COUNT_AL EHCA_BMASK_IBM(29, 31)
+#define MQPCB_MASK_SOURCE_PATH_BITS_AL EHCA_BMASK_IBM(38, 38)
+#define MQPCB_SOURCE_PATH_BITS_AL EHCA_BMASK_IBM(25, 31)
+#define MQPCB_MASK_TRAFFIC_CLASS_AL EHCA_BMASK_IBM(39, 39)
+#define MQPCB_TRAFFIC_CLASS_AL EHCA_BMASK_IBM(24, 31)
+#define MQPCB_MASK_HOP_LIMIT_AL EHCA_BMASK_IBM(40, 40)
+#define MQPCB_HOP_LIMIT_AL EHCA_BMASK_IBM(24, 31)
+#define MQPCB_MASK_SOURCE_GID_IDX_AL EHCA_BMASK_IBM(41, 41)
+#define MQPCB_SOURCE_GID_IDX_AL EHCA_BMASK_IBM(24, 31)
+#define MQPCB_MASK_FLOW_LABEL_AL EHCA_BMASK_IBM(42, 42)
+#define MQPCB_FLOW_LABEL_AL EHCA_BMASK_IBM(12, 31)
+#define MQPCB_MASK_DEST_GID_AL EHCA_BMASK_IBM(44, 44)
+#define MQPCB_MASK_MAX_NR_OUTST_SEND_WR EHCA_BMASK_IBM(45, 45)
+#define MQPCB_MAX_NR_OUTST_SEND_WR EHCA_BMASK_IBM(16, 31)
+#define MQPCB_MASK_MAX_NR_OUTST_RECV_WR EHCA_BMASK_IBM(46, 46)
+#define MQPCB_MAX_NR_OUTST_RECV_WR EHCA_BMASK_IBM(16, 31)
+#define MQPCB_MASK_DISABLE_ETE_CREDIT_CHECK EHCA_BMASK_IBM(47, 47)
+#define MQPCB_DISABLE_ETE_CREDIT_CHECK EHCA_BMASK_IBM(31, 31)
+#define MQPCB_QP_NUMBER EHCA_BMASK_IBM( 8, 31)
+#define MQPCB_MASK_QP_ENABLE EHCA_BMASK_IBM(48, 48)
+#define MQPCB_QP_ENABLE EHCA_BMASK_IBM(31, 31)
+#define MQPCB_MASK_CURR_SRQ_LIMIT EHCA_BMASK_IBM(49, 49)
+#define MQPCB_CURR_SRQ_LIMIT EHCA_BMASK_IBM(16, 31)
+#define MQPCB_MASK_QP_AFF_ASYN_EV_LOG_REG EHCA_BMASK_IBM(50, 50)
+#define MQPCB_MASK_SHARED_RQ_HNDL EHCA_BMASK_IBM(51, 51)
#endif /* __EHCA_CLASSES_PSERIES_H__ */
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 97da51e..ba1bcb9 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -97,7 +97,7 @@ int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int real_qp_num)
return ret;
}
-struct ehca_qp* ehca_cq_get_qp(struct ehca_cq *cq, int real_qp_num)
+struct ehca_qp *ehca_cq_get_qp(struct ehca_cq *cq, int real_qp_num)
{
struct ehca_qp *ret = NULL;
unsigned int key = real_qp_num & (QP_HASHTAB_LEN-1);
diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c
index d443bcb..78a2e5a 100644
--- a/drivers/infiniband/hw/ehca/ehca_eq.c
+++ b/drivers/infiniband/hw/ehca/ehca_eq.c
@@ -111,7 +111,8 @@ struct ehca_eq *ehca_create_eq(struct ehca_shca *shca,
for (i = 0; i < nr_pages; i++) {
u64 rpage;
- if (!(vpage = ipz_qpageit_get_inc(&eq->ipz_queue))) {
+ vpage = ipz_qpageit_get_inc(&eq->ipz_queue);
+ if (!vpage) {
ret = -ENOMEM;
goto create_eq_exit2;
}
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index bbd3c6a..fc19ef9 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -127,6 +127,7 @@ int ehca_query_port(struct ib_device *ibdev,
u8 port, struct ib_port_attr *props)
{
int ret = 0;
+ u64 h_ret;
struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
ib_device);
struct hipz_query_port *rblock;
@@ -137,7 +138,8 @@ int ehca_query_port(struct ib_device *ibdev,
return -ENOMEM;
}
- if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
+ h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
+ if (h_ret != H_SUCCESS) {
ehca_err(&shca->ib_device, "Can't query port properties");
ret = -EINVAL;
goto query_port1;
@@ -197,6 +199,7 @@ int ehca_query_sma_attr(struct ehca_shca *shca,
u8 port, struct ehca_sma_attr *attr)
{
int ret = 0;
+ u64 h_ret;
struct hipz_query_port *rblock;
rblock = ehca_alloc_fw_ctrlblock(GFP_ATOMIC);
@@ -205,7 +208,8 @@ int ehca_query_sma_attr(struct ehca_shca *shca,
return -ENOMEM;
}
- if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
+ h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
+ if (h_ret != H_SUCCESS) {
ehca_err(&shca->ib_device, "Can't query port properties");
ret = -EINVAL;
goto query_sma_attr1;
@@ -230,9 +234,11 @@ query_sma_attr1:
int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
{
int ret = 0;
- struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device);
+ u64 h_ret;
+ struct ehca_shca *shca;
struct hipz_query_port *rblock;
+ shca = container_of(ibdev, struct ehca_shca, ib_device);
if (index > 16) {
ehca_err(&shca->ib_device, "Invalid index: %x.", index);
return -EINVAL;
@@ -244,7 +250,8 @@ int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
return -ENOMEM;
}
- if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
+ h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
+ if (h_ret != H_SUCCESS) {
ehca_err(&shca->ib_device, "Can't query port properties");
ret = -EINVAL;
goto query_pkey1;
@@ -262,6 +269,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port,
int index, union ib_gid *gid)
{
int ret = 0;
+ u64 h_ret;
struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
ib_device);
struct hipz_query_port *rblock;
@@ -277,7 +285,8 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port,
return -ENOMEM;
}
- if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
+ h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
+ if (h_ret != H_SUCCESS) {
ehca_err(&shca->ib_device, "Can't query port properties");
ret = -EINVAL;
goto query_gid1;
@@ -302,11 +311,12 @@ int ehca_modify_port(struct ib_device *ibdev,
struct ib_port_modify *props)
{
int ret = 0;
- struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device);
+ struct ehca_shca *shca;
struct hipz_query_port *rblock;
u32 cap;
u64 hret;
+ shca = container_of(ibdev, struct ehca_shca, ib_device);
if ((props->set_port_cap_mask | props->clr_port_cap_mask)
& ~allowed_port_caps) {
ehca_err(&shca->ib_device, "Non-changeable bits set in masks "
@@ -325,7 +335,8 @@ int ehca_modify_port(struct ib_device *ibdev,
goto modify_port1;
}
- if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
+ hret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
+ if (hret != H_SUCCESS) {
ehca_err(&shca->ib_device, "Can't query port properties");
ret = -EINVAL;
goto modify_port2;
@@ -337,7 +348,8 @@ int ehca_modify_port(struct ib_device *ibdev,
hret = hipz_h_modify_port(shca->ipz_hca_handle, port,
cap, props->init_type, port_modify_mask);
if (hret != H_SUCCESS) {
- ehca_err(&shca->ib_device, "Modify port failed hret=%lx", hret);
+ ehca_err(&shca->ib_device, "Modify port failed hret=%lx",
+ hret);
ret = -EINVAL;
}
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index 7a4071a..1f043d0 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -49,26 +49,26 @@
#include "hipz_fns.h"
#include "ipz_pt_fn.h"
-#define EQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1)
-#define EQE_CQ_QP_NUMBER EHCA_BMASK_IBM(8,31)
-#define EQE_EE_IDENTIFIER EHCA_BMASK_IBM(2,7)
-#define EQE_CQ_NUMBER EHCA_BMASK_IBM(8,31)
-#define EQE_QP_NUMBER EHCA_BMASK_IBM(8,31)
-#define EQE_QP_TOKEN EHCA_BMASK_IBM(32,63)
-#define EQE_CQ_TOKEN EHCA_BMASK_IBM(32,63)
-
-#define NEQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1)
-#define NEQE_EVENT_CODE EHCA_BMASK_IBM(2,7)
-#define NEQE_PORT_NUMBER EHCA_BMASK_IBM(8,15)
-#define NEQE_PORT_AVAILABILITY EHCA_BMASK_IBM(16,16)
-#define NEQE_DISRUPTIVE EHCA_BMASK_IBM(16,16)
-
-#define ERROR_DATA_LENGTH EHCA_BMASK_IBM(52,63)
-#define ERROR_DATA_TYPE EHCA_BMASK_IBM(0,7)
+#define EQE_COMPLETION_EVENT EHCA_BMASK_IBM( 1, 1)
+#define EQE_CQ_QP_NUMBER EHCA_BMASK_IBM( 8, 31)
+#define EQE_EE_IDENTIFIER EHCA_BMASK_IBM( 2, 7)
+#define EQE_CQ_NUMBER EHCA_BMASK_IBM( 8, 31)
+#define EQE_QP_NUMBER EHCA_BMASK_IBM( 8, 31)
+#define EQE_QP_TOKEN EHCA_BMASK_IBM(32, 63)
+#define EQE_CQ_TOKEN EHCA_BMASK_IBM(32, 63)
+
+#define NEQE_COMPLETION_EVENT EHCA_BMASK_IBM( 1, 1)
+#define NEQE_EVENT_CODE EHCA_BMASK_IBM( 2, 7)
+#define NEQE_PORT_NUMBER EHCA_BMASK_IBM( 8, 15)
+#define NEQE_PORT_AVAILABILITY EHCA_BMASK_IBM(16, 16)
+#define NEQE_DISRUPTIVE EHCA_BMASK_IBM(16, 16)
+
+#define ERROR_DATA_LENGTH EHCA_BMASK_IBM(52, 63)
+#define ERROR_DATA_TYPE EHCA_BMASK_IBM( 0, 7)
static void queue_comp_task(struct ehca_cq *__cq);
-static struct ehca_comp_pool* pool;
+static struct ehca_comp_pool *pool;
#ifdef CONFIG_HOTPLUG_CPU
static struct notifier_block comp_pool_callback_nb;
#endif
@@ -85,8 +85,8 @@ static inline void comp_event_callback(struct ehca_cq *cq)
return;
}
-static void print_error_data(struct ehca_shca * shca, void* data,
- u64* rblock, int length)
+static void print_error_data(struct ehca_shca *shca, void *data,
+ u64 *rblock, int length)
{
u64 type = EHCA_BMASK_GET(ERROR_DATA_TYPE, rblock[2]);
u64 resource = rblock[1];
@@ -94,7 +94,7 @@ static void print_error_data(struct ehca_shca * shca, void* data,
switch (type) {
case 0x1: /* Queue Pair */
{
- struct ehca_qp *qp = (struct ehca_qp*)data;
+ struct ehca_qp *qp = (struct ehca_qp *)data;
/* only print error data if AER is set */
if (rblock[6] == 0)
@@ -107,7 +107,7 @@ static void print_error_data(struct ehca_shca * shca, void* data,
}
case 0x4: /* Completion Queue */
{
- struct ehca_cq *cq = (struct ehca_cq*)data;
+ struct ehca_cq *cq = (struct ehca_cq *)data;
ehca_err(&shca->ib_device,
"CQ 0x%x (resource=%lx) has errors.",
@@ -564,7 +564,7 @@ void ehca_tasklet_eq(unsigned long data)
ehca_process_eq((struct ehca_eq *)data, 1);
}
-static inline int find_next_online_cpu(struct ehca_comp_pool* pool)
+static inline int find_next_online_cpu(struct ehca_comp_pool *pool)
{
int cpu;
unsigned long flags;
@@ -628,7 +628,7 @@ static void queue_comp_task(struct ehca_cq *__cq)
__queue_comp_task(__cq, cct);
}
-static void run_comp_task(struct ehca_cpu_comp_task* cct)
+static void run_comp_task(struct ehca_cpu_comp_task *cct)
{
struct ehca_cq *cq;
unsigned long flags;
@@ -658,12 +658,12 @@ static void run_comp_task(struct ehca_cpu_comp_task* cct)
static int comp_task(void *__cct)
{
- struct ehca_cpu_comp_task* cct = __cct;
+ struct ehca_cpu_comp_task *cct = __cct;
int cql_empty;
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_INTERRUPTIBLE);
- while(!kthread_should_stop()) {
+ while (!kthread_should_stop()) {
add_wait_queue(&cct->wait_queue, &wait);
spin_lock_irq(&cct->task_lock);
@@ -737,7 +737,7 @@ static void take_over_work(struct ehca_comp_pool *pool,
list_splice_init(&cct->cq_list, &list);
- while(!list_empty(&list)) {
+ while (!list_empty(&list)) {
cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
list_del(&cq->entry);
@@ -760,7 +760,7 @@ static int comp_pool_callback(struct notifier_block *nfb,
case CPU_UP_PREPARE:
case CPU_UP_PREPARE_FROZEN:
ehca_gen_dbg("CPU: %x (CPU_PREPARE)", cpu);
- if(!create_comp_task(pool, cpu)) {
+ if (!create_comp_task(pool, cpu)) {
ehca_gen_err("Can't create comp_task for cpu: %x", cpu);
return NOTIFY_BAD;
}
@@ -830,7 +830,7 @@ int ehca_create_comp_pool(void)
#ifdef CONFIG_HOTPLUG_CPU
comp_pool_callback_nb.notifier_call = comp_pool_callback;
- comp_pool_callback_nb.priority =0;
+ comp_pool_callback_nb.priority = 0;
register_cpu_notifier(&comp_pool_callback_nb);
#endif
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h
index bf8fbf7..99881e3 100644
--- a/drivers/infiniband/hw/ehca/ehca_iverbs.h
+++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h
@@ -81,8 +81,9 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
int num_phys_buf,
int mr_access_flags, u64 *iova_start);
-struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt,
- int mr_access_flags, struct ib_udata *udata);
+struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+ u64 virt, int mr_access_flags,
+ struct ib_udata *udata);
int ehca_rereg_phys_mr(struct ib_mr *mr,
int mr_rereg_mask,
@@ -191,7 +192,7 @@ void ehca_poll_eqs(unsigned long data);
void *ehca_alloc_fw_ctrlblock(gfp_t flags);
void ehca_free_fw_ctrlblock(void *ptr);
#else
-#define ehca_alloc_fw_ctrlblock(flags) ((void *) get_zeroed_page(flags))
+#define ehca_alloc_fw_ctrlblock(flags) ((void *)get_zeroed_page(flags))
#define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr))
#endif
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 57c551e..ecf4ef4 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -116,7 +116,7 @@ static DEFINE_SPINLOCK(shca_list_lock);
static struct timer_list poll_eqs_timer;
#ifdef CONFIG_PPC_64K_PAGES
-static struct kmem_cache *ctblk_cache = NULL;
+static struct kmem_cache *ctblk_cache;
void *ehca_alloc_fw_ctrlblock(gfp_t flags)
{
@@ -219,8 +219,8 @@ static void ehca_destroy_slab_caches(void)
#endif
}
-#define EHCA_HCAAVER EHCA_BMASK_IBM(32,39)
-#define EHCA_REVID EHCA_BMASK_IBM(40,63)
+#define EHCA_HCAAVER EHCA_BMASK_IBM(32, 39)
+#define EHCA_REVID EHCA_BMASK_IBM(40, 63)
static struct cap_descr {
u64 mask;
@@ -314,7 +314,7 @@ int ehca_sense_attributes(struct ehca_shca *shca)
if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
ehca_gen_dbg(" %s", hca_cap_descr[i].descr);
- port = (struct hipz_query_port *) rblock;
+ port = (struct hipz_query_port *)rblock;
h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
if (h_ret != H_SUCCESS) {
ehca_gen_err("Cannot query port properties. h_ret=%lx",
@@ -463,7 +463,7 @@ static int ehca_create_aqp1(struct ehca_shca *shca, u32 port)
return -EPERM;
}
- ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void*)(-1), 10, 0);
+ ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void *)(-1), 10, 0);
if (IS_ERR(ibcq)) {
ehca_err(&shca->ib_device, "Cannot create AQP1 CQ.");
return PTR_ERR(ibcq);
@@ -730,7 +730,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
}
/* create internal protection domain */
- ibpd = ehca_alloc_pd(&shca->ib_device, (void*)(-1), NULL);
+ ibpd = ehca_alloc_pd(&shca->ib_device, (void *)(-1), NULL);
if (IS_ERR(ibpd)) {
ehca_err(&shca->ib_device, "Cannot create internal PD.");
ret = PTR_ERR(ibpd);
@@ -944,18 +944,21 @@ int __init ehca_module_init(void)
return -EINVAL;
}
- if ((ret = ehca_create_comp_pool())) {
+ ret = ehca_create_comp_pool();
+ if (ret) {
ehca_gen_err("Cannot create comp pool.");
return ret;
}
- if ((ret = ehca_create_slab_caches())) {
+ ret = ehca_create_slab_caches();
+ if (ret) {
ehca_gen_err("Cannot create SLAB caches");
ret = -ENOMEM;
goto module_init1;
}
- if ((ret = ibmebus_register_driver(&ehca_driver))) {
+ ret = ibmebus_register_driver(&ehca_driver);
+ if (ret) {
ehca_gen_err("Cannot register eHCA device driver");
ret = -EINVAL;
goto module_init2;
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index 93c26cc..6262c54 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -61,9 +61,9 @@ static struct ehca_mr *ehca_mr_new(void)
struct ehca_mr *me;
me = kmem_cache_zalloc(mr_cache, GFP_KERNEL);
- if (me) {
+ if (me)
spin_lock_init(&me->mrlock);
- } else
+ else
ehca_gen_err("alloc failed");
return me;
@@ -79,9 +79,9 @@ static struct ehca_mw *ehca_mw_new(void)
struct ehca_mw *me;
me = kmem_cache_zalloc(mw_cache, GFP_KERNEL);
- if (me) {
+ if (me)
spin_lock_init(&me->mwlock);
- } else
+ else
ehca_gen_err("alloc failed");
return me;
@@ -111,7 +111,7 @@ struct ib_mr *ehca_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
goto get_dma_mr_exit0;
}
- ret = ehca_reg_maxmr(shca, e_maxmr, (u64*)KERNELBASE,
+ ret = ehca_reg_maxmr(shca, e_maxmr, (u64 *)KERNELBASE,
mr_access_flags, e_pd,
&e_maxmr->ib.ib_mr.lkey,
&e_maxmr->ib.ib_mr.rkey);
@@ -246,8 +246,9 @@ reg_phys_mr_exit0:
/*----------------------------------------------------------------------*/
-struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt,
- int mr_access_flags, struct ib_udata *udata)
+struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+ u64 virt, int mr_access_flags,
+ struct ib_udata *udata)
{
struct ib_mr *ib_mr;
struct ehca_mr *e_mr;
@@ -295,7 +296,7 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt
e_mr->umem = ib_umem_get(pd->uobject->context, start, length,
mr_access_flags);
if (IS_ERR(e_mr->umem)) {
- ib_mr = (void *) e_mr->umem;
+ ib_mr = (void *)e_mr->umem;
goto reg_user_mr_exit1;
}
@@ -322,8 +323,9 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt
(&e_mr->umem->chunk_list),
list);
- ret = ehca_reg_mr(shca, e_mr, (u64*) virt, length, mr_access_flags, e_pd,
- &pginfo, &e_mr->ib.ib_mr.lkey, &e_mr->ib.ib_mr.rkey);
+ ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags,
+ e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
+ &e_mr->ib.ib_mr.rkey);
if (ret) {
ib_mr = ERR_PTR(ret);
goto reg_user_mr_exit2;
@@ -420,7 +422,7 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
goto rereg_phys_mr_exit0;
}
if (!phys_buf_array || num_phys_buf <= 0) {
- ehca_err(mr->device, "bad input values: mr_rereg_mask=%x"
+ ehca_err(mr->device, "bad input values mr_rereg_mask=%x"
" phys_buf_array=%p num_phys_buf=%x",
mr_rereg_mask, phys_buf_array, num_phys_buf);
ret = -EINVAL;
@@ -444,10 +446,10 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
/* set requested values dependent on rereg request */
spin_lock_irqsave(&e_mr->mrlock, sl_flags);
- new_start = e_mr->start; /* new == old address */
- new_size = e_mr->size; /* new == old length */
- new_acl = e_mr->acl; /* new == old access control */
- new_pd = container_of(mr->pd,struct ehca_pd,ib_pd); /*new == old PD*/
+ new_start = e_mr->start;
+ new_size = e_mr->size;
+ new_acl = e_mr->acl;
+ new_pd = container_of(mr->pd, struct ehca_pd, ib_pd);
if (mr_rereg_mask & IB_MR_REREG_TRANS) {
new_start = iova_start; /* change address */
@@ -517,7 +519,7 @@ int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
struct ehca_pd *my_pd = container_of(mr->pd, struct ehca_pd, ib_pd);
u32 cur_pid = current->tgid;
unsigned long sl_flags;
- struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
+ struct ehca_mr_hipzout_parms hipzout;
if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
(my_pd->ownpid != cur_pid)) {
@@ -629,7 +631,7 @@ struct ib_mw *ehca_alloc_mw(struct ib_pd *pd)
struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
struct ehca_shca *shca =
container_of(pd->device, struct ehca_shca, ib_device);
- struct ehca_mw_hipzout_parms hipzout = {{0},0};
+ struct ehca_mw_hipzout_parms hipzout;
e_mw = ehca_mw_new();
if (!e_mw) {
@@ -826,7 +828,7 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr,
EHCA_PAGESIZE);
pginfo.u.fmr.fmr_pgsize = e_fmr->fmr_page_size;
- ret = ehca_rereg_mr(shca, e_fmr, (u64*)iova,
+ ret = ehca_rereg_mr(shca, e_fmr, (u64 *)iova,
list_len * e_fmr->fmr_page_size,
e_fmr->acl, e_pd, &pginfo, &tmp_lkey, &tmp_rkey);
if (ret)
@@ -841,8 +843,7 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr,
map_phys_fmr_exit0:
if (ret)
ehca_err(fmr->device, "ret=%x fmr=%p page_list=%p list_len=%x "
- "iova=%lx",
- ret, fmr, page_list, list_len, iova);
+ "iova=%lx", ret, fmr, page_list, list_len, iova);
return ret;
} /* end ehca_map_phys_fmr() */
@@ -960,12 +961,12 @@ int ehca_reg_mr(struct ehca_shca *shca,
int ret;
u64 h_ret;
u32 hipz_acl;
- struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
+ struct ehca_mr_hipzout_parms hipzout;
ehca_mrmw_map_acl(acl, &hipz_acl);
ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
if (ehca_use_hp_mr == 1)
- hipz_acl |= 0x00000001;
+ hipz_acl |= 0x00000001;
h_ret = hipz_h_alloc_resource_mr(shca->ipz_hca_handle, e_mr,
(u64)iova_start, size, hipz_acl,
@@ -1127,7 +1128,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
u64 *kpage;
u64 rpage;
struct ehca_mr_pginfo pginfo_save;
- struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
+ struct ehca_mr_hipzout_parms hipzout;
ehca_mrmw_map_acl(acl, &hipz_acl);
ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
@@ -1167,7 +1168,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
"(Rereg1), h_ret=%lx e_mr=%p", h_ret, e_mr);
*pginfo = pginfo_save;
ret = -EAGAIN;
- } else if ((u64*)hipzout.vaddr != iova_start) {
+ } else if ((u64 *)hipzout.vaddr != iova_start) {
ehca_err(&shca->ib_device, "PHYP changed iova_start in "
"rereg_pmr, iova_start=%p iova_start_out=%lx e_mr=%p "
"mr_handle=%lx lkey=%x lkey_out=%x", iova_start,
@@ -1305,7 +1306,7 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca,
struct ehca_mr save_fmr;
u32 tmp_lkey, tmp_rkey;
struct ehca_mr_pginfo pginfo;
- struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
+ struct ehca_mr_hipzout_parms hipzout;
struct ehca_mr save_mr;
if (e_fmr->fmr_max_pages <= MAX_RPAGES) {
@@ -1397,7 +1398,7 @@ int ehca_reg_smr(struct ehca_shca *shca,
int ret = 0;
u64 h_ret;
u32 hipz_acl;
- struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
+ struct ehca_mr_hipzout_parms hipzout;
ehca_mrmw_map_acl(acl, &hipz_acl);
ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
@@ -1462,7 +1463,7 @@ int ehca_reg_internal_maxmr(
/* register internal max-MR on HCA */
size_maxmr = (u64)high_memory - PAGE_OFFSET;
- iova_start = (u64*)KERNELBASE;
+ iova_start = (u64 *)KERNELBASE;
ib_pbuf.addr = 0;
ib_pbuf.size = size_maxmr;
num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr,
@@ -1519,7 +1520,7 @@ int ehca_reg_maxmr(struct ehca_shca *shca,
u64 h_ret;
struct ehca_mr *e_origmr = shca->maxmr;
u32 hipz_acl;
- struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
+ struct ehca_mr_hipzout_parms hipzout;
ehca_mrmw_map_acl(acl, &hipz_acl);
ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
@@ -1865,7 +1866,7 @@ int ehca_mr_is_maxmr(u64 size,
{
/* a MR is treated as max-MR only if it fits following: */
if ((size == ((u64)high_memory - PAGE_OFFSET)) &&
- (iova_start == (void*)KERNELBASE)) {
+ (iova_start == (void *)KERNELBASE)) {
ehca_gen_dbg("this is a max-MR");
return 1;
} else
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.h b/drivers/infiniband/hw/ehca/ehca_mrmw.h
index fb69ede..24f13fe 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.h
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.h
@@ -101,15 +101,10 @@ int ehca_fmr_check_page_list(struct ehca_mr *e_fmr,
u64 *page_list,
int list_len);
-int ehca_set_pagebuf(struct ehca_mr *e_mr,
- struct ehca_mr_pginfo *pginfo,
+int ehca_set_pagebuf(struct ehca_mr_pginfo *pginfo,
u32 number,
u64 *kpage);
-int ehca_set_pagebuf_1(struct ehca_mr *e_mr,
- struct ehca_mr_pginfo *pginfo,
- u64 *rpage);
-
int ehca_mr_is_maxmr(u64 size,
u64 *iova_start);
diff --git a/drivers/infiniband/hw/ehca/ehca_qes.h b/drivers/infiniband/hw/ehca/ehca_qes.h
index 8707d29..8188030 100644
--- a/drivers/infiniband/hw/ehca/ehca_qes.h
+++ b/drivers/infiniband/hw/ehca/ehca_qes.h
@@ -53,13 +53,13 @@ struct ehca_vsgentry {
u32 length;
};
-#define GRH_FLAG_MASK EHCA_BMASK_IBM(7,7)
-#define GRH_IPVERSION_MASK EHCA_BMASK_IBM(0,3)
-#define GRH_TCLASS_MASK EHCA_BMASK_IBM(4,12)
-#define GRH_FLOWLABEL_MASK EHCA_BMASK_IBM(13,31)
-#define GRH_PAYLEN_MASK EHCA_BMASK_IBM(32,47)
-#define GRH_NEXTHEADER_MASK EHCA_BMASK_IBM(48,55)
-#define GRH_HOPLIMIT_MASK EHCA_BMASK_IBM(56,63)
+#define GRH_FLAG_MASK EHCA_BMASK_IBM( 7, 7)
+#define GRH_IPVERSION_MASK EHCA_BMASK_IBM( 0, 3)
+#define GRH_TCLASS_MASK EHCA_BMASK_IBM( 4, 12)
+#define GRH_FLOWLABEL_MASK EHCA_BMASK_IBM(13, 31)
+#define GRH_PAYLEN_MASK EHCA_BMASK_IBM(32, 47)
+#define GRH_NEXTHEADER_MASK EHCA_BMASK_IBM(48, 55)
+#define GRH_HOPLIMIT_MASK EHCA_BMASK_IBM(56, 63)
/*
* Unreliable Datagram Address Vector Format
@@ -206,10 +206,10 @@ struct ehca_wqe {
};
-#define WC_SEND_RECEIVE EHCA_BMASK_IBM(0,0)
-#define WC_IMM_DATA EHCA_BMASK_IBM(1,1)
-#define WC_GRH_PRESENT EHCA_BMASK_IBM(2,2)
-#define WC_SE_BIT EHCA_BMASK_IBM(3,3)
+#define WC_SEND_RECEIVE EHCA_BMASK_IBM(0, 0)
+#define WC_IMM_DATA EHCA_BMASK_IBM(1, 1)
+#define WC_GRH_PRESENT EHCA_BMASK_IBM(2, 2)
+#define WC_SE_BIT EHCA_BMASK_IBM(3, 3)
#define WC_STATUS_ERROR_BIT 0x80000000
#define WC_STATUS_REMOTE_ERROR_FLAGS 0x0000F800
#define WC_STATUS_PURGE_BIT 0x10
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index f6f4ef6..3bd13e1 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -602,10 +602,10 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd,
/* UD circumvention */
parms.act_nr_send_sges -= 2;
parms.act_nr_recv_sges -= 2;
- swqe_size = offsetof(struct ehca_wqe,
- u.ud_av.sg_list[parms.act_nr_send_sges]);
- rwqe_size = offsetof(struct ehca_wqe,
- u.ud_av.sg_list[parms.act_nr_recv_sges]);
+ swqe_size = offsetof(struct ehca_wqe, u.ud_av.sg_list[
+ parms.act_nr_send_sges]);
+ rwqe_size = offsetof(struct ehca_wqe, u.ud_av.sg_list[
+ parms.act_nr_recv_sges]);
}
if (IB_QPT_GSI == qp_type || IB_QPT_SMI == qp_type) {
@@ -690,8 +690,8 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd,
if (my_qp->send_cq) {
ret = ehca_cq_assign_qp(my_qp->send_cq, my_qp);
if (ret) {
- ehca_err(pd->device, "Couldn't assign qp to send_cq ret=%x",
- ret);
+ ehca_err(pd->device,
+ "Couldn't assign qp to send_cq ret=%x", ret);
goto create_qp_exit4;
}
}
@@ -749,7 +749,7 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
struct ehca_qp *ret;
ret = internal_create_qp(pd, qp_init_attr, NULL, udata, 0);
- return IS_ERR(ret) ? (struct ib_qp *) ret : &ret->ib_qp;
+ return IS_ERR(ret) ? (struct ib_qp *)ret : &ret->ib_qp;
}
int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
@@ -780,7 +780,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd,
my_qp = internal_create_qp(pd, &qp_init_attr, srq_init_attr, udata, 1);
if (IS_ERR(my_qp))
- return (struct ib_srq *) my_qp;
+ return (struct ib_srq *)my_qp;
/* copy back return values */
srq_init_attr->attr.max_wr = qp_init_attr.cap.max_recv_wr;
@@ -875,7 +875,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca,
my_qp, qp_num, h_ret);
return ehca2ib_return_code(h_ret);
}
- bad_send_wqe_p = (void*)((u64)bad_send_wqe_p & (~(1L<<63)));
+ bad_send_wqe_p = (void *)((u64)bad_send_wqe_p & (~(1L << 63)));
ehca_dbg(&shca->ib_device, "qp_num=%x bad_send_wqe_p=%p",
qp_num, bad_send_wqe_p);
/* convert wqe pointer to vadr */
@@ -890,7 +890,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca,
}
/* loop sets wqe's purge bit */
- wqe = (struct ehca_wqe*)ipz_qeit_calc(squeue, q_ofs);
+ wqe = (struct ehca_wqe *)ipz_qeit_calc(squeue, q_ofs);
*bad_wqe_cnt = 0;
while (wqe->optype != 0xff && wqe->wqef != 0xff) {
if (ehca_debug_level)
@@ -898,7 +898,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca,
wqe->nr_of_data_seg = 0; /* suppress data access */
wqe->wqef = WQEF_PURGE; /* WQE to be purged */
q_ofs = ipz_queue_advance_offset(squeue, q_ofs);
- wqe = (struct ehca_wqe*)ipz_qeit_calc(squeue, q_ofs);
+ wqe = (struct ehca_wqe *)ipz_qeit_calc(squeue, q_ofs);
*bad_wqe_cnt = (*bad_wqe_cnt)+1;
}
/*
@@ -1003,7 +1003,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
goto modify_qp_exit1;
}
- ehca_dbg(ibqp->device,"ehca_qp=%p qp_num=%x current qp_state=%x "
+ ehca_dbg(ibqp->device, "ehca_qp=%p qp_num=%x current qp_state=%x "
"new qp_state=%x attribute_mask=%x",
my_qp, ibqp->qp_num, qp_cur_state, attr->qp_state, attr_mask);
@@ -1019,7 +1019,8 @@ static int internal_modify_qp(struct ib_qp *ibqp,
goto modify_qp_exit1;
}
- if ((mqpcb->qp_state = ib2ehca_qp_state(qp_new_state)))
+ mqpcb->qp_state = ib2ehca_qp_state(qp_new_state);
+ if (mqpcb->qp_state)
update_mask = EHCA_BMASK_SET(MQPCB_MASK_QP_STATE, 1);
else {
ret = -EINVAL;
@@ -1077,7 +1078,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
spin_lock_irqsave(&my_qp->spinlock_s, flags);
squeue_locked = 1;
/* mark next free wqe */
- wqe = (struct ehca_wqe*)
+ wqe = (struct ehca_wqe *)
ipz_qeit_get(&my_qp->ipz_squeue);
wqe->optype = wqe->wqef = 0xff;
ehca_dbg(ibqp->device, "qp_num=%x next_free_wqe=%p",
@@ -1312,7 +1313,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
if (h_ret != H_SUCCESS) {
ret = ehca2ib_return_code(h_ret);
ehca_err(ibqp->device, "hipz_h_modify_qp() failed rc=%lx "
- "ehca_qp=%p qp_num=%x",h_ret, my_qp, ibqp->qp_num);
+ "ehca_qp=%p qp_num=%x", h_ret, my_qp, ibqp->qp_num);
goto modify_qp_exit2;
}
@@ -1411,7 +1412,7 @@ int ehca_query_qp(struct ib_qp *qp,
}
if (qp_attr_mask & QP_ATTR_QUERY_NOT_SUPPORTED) {
- ehca_err(qp->device,"Invalid attribute mask "
+ ehca_err(qp->device, "Invalid attribute mask "
"ehca_qp=%p qp_num=%x qp_attr_mask=%x ",
my_qp, qp->qp_num, qp_attr_mask);
return -EINVAL;
@@ -1419,7 +1420,7 @@ int ehca_query_qp(struct ib_qp *qp,
qpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
if (!qpcb) {
- ehca_err(qp->device,"Out of memory for qpcb "
+ ehca_err(qp->device, "Out of memory for qpcb "
"ehca_qp=%p qp_num=%x", my_qp, qp->qp_num);
return -ENOMEM;
}
@@ -1431,7 +1432,7 @@ int ehca_query_qp(struct ib_qp *qp,
if (h_ret != H_SUCCESS) {
ret = ehca2ib_return_code(h_ret);
- ehca_err(qp->device,"hipz_h_query_qp() failed "
+ ehca_err(qp->device, "hipz_h_query_qp() failed "
"ehca_qp=%p qp_num=%x h_ret=%lx",
my_qp, qp->qp_num, h_ret);
goto query_qp_exit1;
@@ -1442,7 +1443,7 @@ int ehca_query_qp(struct ib_qp *qp,
if (qp_attr->cur_qp_state == -EINVAL) {
ret = -EINVAL;
- ehca_err(qp->device,"Got invalid ehca_qp_state=%x "
+ ehca_err(qp->device, "Got invalid ehca_qp_state=%x "
"ehca_qp=%p qp_num=%x",
qpcb->qp_state, my_qp, qp->qp_num);
goto query_qp_exit1;
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index 61da65e..94eed70 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -79,7 +79,8 @@ static inline int ehca_write_rwqe(struct ipz_queue *ipz_rqueue,
}
if (ehca_debug_level) {
- ehca_gen_dbg("RECEIVE WQE written into ipz_rqueue=%p", ipz_rqueue);
+ ehca_gen_dbg("RECEIVE WQE written into ipz_rqueue=%p",
+ ipz_rqueue);
ehca_dmp( wqe_p, 16*(6 + wqe_p->nr_of_data_seg), "recv wqe");
}
@@ -99,7 +100,7 @@ static void trace_send_wr_ud(const struct ib_send_wr *send_wr)
struct ib_mad_hdr *mad_hdr = send_wr->wr.ud.mad_hdr;
struct ib_sge *sge = send_wr->sg_list;
ehca_gen_dbg("send_wr#%x wr_id=%lx num_sge=%x "
- "send_flags=%x opcode=%x",idx, send_wr->wr_id,
+ "send_flags=%x opcode=%x", idx, send_wr->wr_id,
send_wr->num_sge, send_wr->send_flags,
send_wr->opcode);
if (mad_hdr) {
@@ -116,7 +117,7 @@ static void trace_send_wr_ud(const struct ib_send_wr *send_wr)
mad_hdr->attr_mod);
}
for (j = 0; j < send_wr->num_sge; j++) {
- u8 *data = (u8 *) abs_to_virt(sge->addr);
+ u8 *data = (u8 *)abs_to_virt(sge->addr);
ehca_gen_dbg("send_wr#%x sge#%x addr=%p length=%x "
"lkey=%x",
idx, j, data, sge->length, sge->lkey);
@@ -534,9 +535,11 @@ poll_cq_one_read_cqe:
cqe_count++;
if (unlikely(cqe->status & WC_STATUS_PURGE_BIT)) {
- struct ehca_qp *qp=ehca_cq_get_qp(my_cq, cqe->local_qp_number);
+ struct ehca_qp *qp;
int purgeflag;
unsigned long flags;
+
+ qp = ehca_cq_get_qp(my_cq, cqe->local_qp_number);
if (!qp) {
ehca_err(cq->device, "cq_num=%x qp_num=%x "
"could not find qp -> ignore cqe",
@@ -551,8 +554,8 @@ poll_cq_one_read_cqe:
spin_unlock_irqrestore(&qp->spinlock_s, flags);
if (purgeflag) {
- ehca_dbg(cq->device, "Got CQE with purged bit qp_num=%x "
- "src_qp=%x",
+ ehca_dbg(cq->device,
+ "Got CQE with purged bit qp_num=%x src_qp=%x",
cqe->local_qp_number, cqe->remote_qp_number);
if (ehca_debug_level)
ehca_dmp(cqe, 64, "qp_num=%x src_qp=%x",
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h
index fd8238b..678b813 100644
--- a/drivers/infiniband/hw/ehca/ehca_tools.h
+++ b/drivers/infiniband/hw/ehca/ehca_tools.h
@@ -93,14 +93,14 @@ extern int ehca_debug_level;
#define ehca_gen_dbg(format, arg...) \
do { \
if (unlikely(ehca_debug_level)) \
- printk(KERN_DEBUG "PU%04x EHCA_DBG:%s " format "\n",\
+ printk(KERN_DEBUG "PU%04x EHCA_DBG:%s " format "\n", \
get_paca()->paca_index, __FUNCTION__, ## arg); \
} while (0)
#define ehca_gen_warn(format, arg...) \
do { \
if (unlikely(ehca_debug_level)) \
- printk(KERN_INFO "PU%04x EHCA_WARN:%s " format "\n",\
+ printk(KERN_INFO "PU%04x EHCA_WARN:%s " format "\n", \
get_paca()->paca_index, __FUNCTION__, ## arg); \
} while (0)
@@ -114,12 +114,12 @@ extern int ehca_debug_level;
* <format string> adr=X ofs=Y <8 bytes hex> <8 bytes hex>
*/
#define ehca_dmp(adr, len, format, args...) \
- do { \
- unsigned int x; \
+ do { \
+ unsigned int x; \
unsigned int l = (unsigned int)(len); \
- unsigned char *deb = (unsigned char*)(adr); \
+ unsigned char *deb = (unsigned char *)(adr); \
for (x = 0; x < l; x += 16) { \
- printk("EHCA_DMP:%s " format \
+ printk(KERN_INFO "EHCA_DMP:%s " format \
" adr=%p ofs=%04x %016lx %016lx\n", \
__FUNCTION__, ##args, deb, x, \
*((u64 *)&deb[0]), *((u64 *)&deb[8])); \
@@ -128,16 +128,16 @@ extern int ehca_debug_level;
} while (0)
/* define a bitmask, little endian version */
-#define EHCA_BMASK(pos,length) (((pos)<<16)+(length))
+#define EHCA_BMASK(pos, length) (((pos) << 16) + (length))
/* define a bitmask, the ibm way... */
-#define EHCA_BMASK_IBM(from,to) (((63-to)<<16)+((to)-(from)+1))
+#define EHCA_BMASK_IBM(from, to) (((63 - to) << 16) + ((to) - (from) + 1))
/* internal function, don't use */
-#define EHCA_BMASK_SHIFTPOS(mask) (((mask)>>16)&0xffff)
+#define EHCA_BMASK_SHIFTPOS(mask) (((mask) >> 16) & 0xffff)
/* internal function, don't use */
-#define EHCA_BMASK_MASK(mask) (0xffffffffffffffffULL >> ((64-(mask))&0xffff))
+#define EHCA_BMASK_MASK(mask) (~0ULL >> ((64 - (mask)) & 0xffff))
/**
* EHCA_BMASK_SET - return value shifted and masked by mask
@@ -145,14 +145,14 @@ extern int ehca_debug_level;
* variable&=~EHCA_BMASK_SET(MY_MASK,-1) clears the bits from the mask
* in variable
*/
-#define EHCA_BMASK_SET(mask,value) \
- ((EHCA_BMASK_MASK(mask) & ((u64)(value)))<<EHCA_BMASK_SHIFTPOS(mask))
+#define EHCA_BMASK_SET(mask, value) \
+ ((EHCA_BMASK_MASK(mask) & ((u64)(value))) << EHCA_BMASK_SHIFTPOS(mask))
/**
* EHCA_BMASK_GET - extract a parameter from value by mask
*/
-#define EHCA_BMASK_GET(mask,value) \
- (EHCA_BMASK_MASK(mask)& (((u64)(value))>>EHCA_BMASK_SHIFTPOS(mask)))
+#define EHCA_BMASK_GET(mask, value) \
+ (EHCA_BMASK_MASK(mask) & (((u64)(value)) >> EHCA_BMASK_SHIFTPOS(mask)))
/* Converts ehca to ib return code */
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c
index 3031b3b..05c4157 100644
--- a/drivers/infiniband/hw/ehca/ehca_uverbs.c
+++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c
@@ -70,7 +70,7 @@ int ehca_dealloc_ucontext(struct ib_ucontext *context)
static void ehca_mm_open(struct vm_area_struct *vma)
{
- u32 *count = (u32*)vma->vm_private_data;
+ u32 *count = (u32 *)vma->vm_private_data;
if (!count) {
ehca_gen_err("Invalid vma struct vm_start=%lx vm_end=%lx",
vma->vm_start, vma->vm_end);
@@ -86,7 +86,7 @@ static void ehca_mm_open(struct vm_area_struct *vma)
static void ehca_mm_close(struct vm_area_struct *vma)
{
- u32 *count = (u32*)vma->vm_private_data;
+ u32 *count = (u32 *)vma->vm_private_data;
if (!count) {
ehca_gen_err("Invalid vma struct vm_start=%lx vm_end=%lx",
vma->vm_start, vma->vm_end);
@@ -215,7 +215,8 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
case 2: /* qp rqueue_addr */
ehca_dbg(qp->ib_qp.device, "qp_num=%x rqueue",
qp->ib_qp.qp_num);
- ret = ehca_mmap_queue(vma, &qp->ipz_rqueue, &qp->mm_count_rqueue);
+ ret = ehca_mmap_queue(vma, &qp->ipz_rqueue,
+ &qp->mm_count_rqueue);
if (unlikely(ret)) {
ehca_err(qp->ib_qp.device,
"ehca_mmap_queue(rq) failed rc=%x qp_num=%x",
@@ -227,7 +228,8 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
case 3: /* qp squeue_addr */
ehca_dbg(qp->ib_qp.device, "qp_num=%x squeue",
qp->ib_qp.qp_num);
- ret = ehca_mmap_queue(vma, &qp->ipz_squeue, &qp->mm_count_squeue);
+ ret = ehca_mmap_queue(vma, &qp->ipz_squeue,
+ &qp->mm_count_squeue);
if (unlikely(ret)) {
ehca_err(qp->ib_qp.device,
"ehca_mmap_queue(sq) failed rc=%x qp_num=%x",
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
index 4776a8b..3394e05 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -501,8 +501,8 @@ u64 hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle,
return H_PARAMETER;
}
- return hipz_h_register_rpage(adapter_handle,pagesize,queue_type,
- qp_handle.handle,logical_address_of_page,
+ return hipz_h_register_rpage(adapter_handle, pagesize, queue_type,
+ qp_handle.handle, logical_address_of_page,
count);
}
@@ -522,9 +522,9 @@ u64 hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle,
qp_handle.handle, /* r6 */
0, 0, 0, 0, 0, 0);
if (log_addr_next_sq_wqe2processed)
- *log_addr_next_sq_wqe2processed = (void*)outs[0];
+ *log_addr_next_sq_wqe2processed = (void *)outs[0];
if (log_addr_next_rq_wqe2processed)
- *log_addr_next_rq_wqe2processed = (void*)outs[1];
+ *log_addr_next_rq_wqe2processed = (void *)outs[1];
return ret;
}
diff --git a/drivers/infiniband/hw/ehca/hcp_phyp.c b/drivers/infiniband/hw/ehca/hcp_phyp.c
index 0b1a477..069c69e 100644
--- a/drivers/infiniband/hw/ehca/hcp_phyp.c
+++ b/drivers/infiniband/hw/ehca/hcp_phyp.c
@@ -50,7 +50,7 @@ int hcall_map_page(u64 physaddr, u64 *mapaddr)
int hcall_unmap_page(u64 mapaddr)
{
- iounmap((volatile void __iomem*)mapaddr);
+ iounmap((volatile void __iomem *)mapaddr);
return 0;
}
diff --git a/drivers/infiniband/hw/ehca/hipz_fns_core.h b/drivers/infiniband/hw/ehca/hipz_fns_core.h
index 20898a1..868735f 100644
--- a/drivers/infiniband/hw/ehca/hipz_fns_core.h
+++ b/drivers/infiniband/hw/ehca/hipz_fns_core.h
@@ -53,10 +53,10 @@
#define hipz_galpa_load_cq(gal, offset) \
hipz_galpa_load(gal, CQTEMM_OFFSET(offset))
-#define hipz_galpa_store_qp(gal,offset, value) \
+#define hipz_galpa_store_qp(gal, offset, value) \
hipz_galpa_store(gal, QPTEMM_OFFSET(offset), value)
#define hipz_galpa_load_qp(gal, offset) \
- hipz_galpa_load(gal,QPTEMM_OFFSET(offset))
+ hipz_galpa_load(gal, QPTEMM_OFFSET(offset))
static inline void hipz_update_sqa(struct ehca_qp *qp, u16 nr_wqes)
{
diff --git a/drivers/infiniband/hw/ehca/hipz_hw.h b/drivers/infiniband/hw/ehca/hipz_hw.h
index dad6dea..d9739e5 100644
--- a/drivers/infiniband/hw/ehca/hipz_hw.h
+++ b/drivers/infiniband/hw/ehca/hipz_hw.h
@@ -161,11 +161,11 @@ struct hipz_qptemm {
/* 0x1000 */
};
-#define QPX_SQADDER EHCA_BMASK_IBM(48,63)
-#define QPX_RQADDER EHCA_BMASK_IBM(48,63)
-#define QPX_AAELOG_RESET_SRQ_LIMIT EHCA_BMASK_IBM(3,3)
+#define QPX_SQADDER EHCA_BMASK_IBM(48, 63)
+#define QPX_RQADDER EHCA_BMASK_IBM(48, 63)
+#define QPX_AAELOG_RESET_SRQ_LIMIT EHCA_BMASK_IBM(3, 3)
-#define QPTEMM_OFFSET(x) offsetof(struct hipz_qptemm,x)
+#define QPTEMM_OFFSET(x) offsetof(struct hipz_qptemm, x)
/* MRMWPT Entry Memory Map */
struct hipz_mrmwmm {
@@ -187,7 +187,7 @@ struct hipz_mrmwmm {
};
-#define MRMWMM_OFFSET(x) offsetof(struct hipz_mrmwmm,x)
+#define MRMWMM_OFFSET(x) offsetof(struct hipz_mrmwmm, x)
struct hipz_qpedmm {
/* 0x00 */
@@ -238,7 +238,7 @@ struct hipz_qpedmm {
u64 qpedx_rrva3;
};
-#define QPEDMM_OFFSET(x) offsetof(struct hipz_qpedmm,x)
+#define QPEDMM_OFFSET(x) offsetof(struct hipz_qpedmm, x)
/* CQ Table Entry Memory Map */
struct hipz_cqtemm {
@@ -263,12 +263,12 @@ struct hipz_cqtemm {
/* 0x1000 */
};
-#define CQX_FEC_CQE_CNT EHCA_BMASK_IBM(32,63)
-#define CQX_FECADDER EHCA_BMASK_IBM(32,63)
-#define CQX_N0_GENERATE_SOLICITED_COMP_EVENT EHCA_BMASK_IBM(0,0)
-#define CQX_N1_GENERATE_COMP_EVENT EHCA_BMASK_IBM(0,0)
+#define CQX_FEC_CQE_CNT EHCA_BMASK_IBM(32, 63)
+#define CQX_FECADDER EHCA_BMASK_IBM(32, 63)
+#define CQX_N0_GENERATE_SOLICITED_COMP_EVENT EHCA_BMASK_IBM(0, 0)
+#define CQX_N1_GENERATE_COMP_EVENT EHCA_BMASK_IBM(0, 0)
-#define CQTEMM_OFFSET(x) offsetof(struct hipz_cqtemm,x)
+#define CQTEMM_OFFSET(x) offsetof(struct hipz_cqtemm, x)
/* EQ Table Entry Memory Map */
struct hipz_eqtemm {
@@ -293,7 +293,7 @@ struct hipz_eqtemm {
};
-#define EQTEMM_OFFSET(x) offsetof(struct hipz_eqtemm,x)
+#define EQTEMM_OFFSET(x) offsetof(struct hipz_eqtemm, x)
/* access control defines for MR/MW */
#define HIPZ_ACCESSCTRL_L_WRITE 0x00800000
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
index bf7a400..9606f13 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.c
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
@@ -114,7 +114,7 @@ int ipz_queue_ctor(struct ipz_queue *queue,
*/
f = 0;
while (f < nr_of_pages) {
- u8 *kpage = (u8*)get_zeroed_page(GFP_KERNEL);
+ u8 *kpage = (u8 *)get_zeroed_page(GFP_KERNEL);
int k;
if (!kpage)
goto ipz_queue_ctor_exit0; /*NOMEM*/
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.h b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
index 007f088..39a4f64 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.h
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
@@ -240,7 +240,7 @@ void *ipz_qeit_eq_get_inc(struct ipz_queue *queue);
static inline void *ipz_eqit_eq_get_inc_valid(struct ipz_queue *queue)
{
void *ret = ipz_qeit_get(queue);
- u32 qe = *(u8 *) ret;
+ u32 qe = *(u8 *)ret;
if ((qe >> 7) != (queue->toggle_state & 1))
return NULL;
ipz_qeit_eq_get_inc(queue); /* this is a good one */
@@ -250,7 +250,7 @@ static inline void *ipz_eqit_eq_get_inc_valid(struct ipz_queue *queue)
static inline void *ipz_eqit_eq_peek_valid(struct ipz_queue *queue)
{
void *ret = ipz_qeit_get(queue);
- u32 qe = *(u8 *) ret;
+ u32 qe = *(u8 *)ret;
if ((qe >> 7) != (queue->toggle_state & 1))
return NULL;
return ret;
--
1.5.2
^ permalink raw reply related
* [PATCH 08/10] IB/ehca: Restructure ehca_set_pagebuf()
From: Joachim Fenkes @ 2007-07-12 15:53 UTC (permalink / raw)
To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier
Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200707121745.27592.fenkes@de.ibm.com>
From: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Split ehca_set_pagebuf() into three functions depending on MR type
(phys/user/fast) and remove superfluous ehca_set_pagebuf_1().
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_mrmw.c | 531 ++++++++++++--------------------
1 files changed, 200 insertions(+), 331 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index 53b334b..93c26cc 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -824,6 +824,7 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr,
pginfo.u.fmr.page_list = page_list;
pginfo.next_hwpage = ((iova & (e_fmr->fmr_page_size-1)) /
EHCA_PAGESIZE);
+ pginfo.u.fmr.fmr_pgsize = e_fmr->fmr_page_size;
ret = ehca_rereg_mr(shca, e_fmr, (u64*)iova,
list_len * e_fmr->fmr_page_size,
@@ -1044,15 +1045,15 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
} else
rnum = MAX_RPAGES;
- if (rnum > 1) {
- ret = ehca_set_pagebuf(e_mr, pginfo, rnum, kpage);
- if (ret) {
- ehca_err(&shca->ib_device, "ehca_set_pagebuf "
+ ret = ehca_set_pagebuf(pginfo, rnum, kpage);
+ if (ret) {
+ ehca_err(&shca->ib_device, "ehca_set_pagebuf "
"bad rc, ret=%x rnum=%x kpage=%p",
ret, rnum, kpage);
- ret = -EFAULT;
- goto ehca_reg_mr_rpages_exit1;
- }
+ goto ehca_reg_mr_rpages_exit1;
+ }
+
+ if (rnum > 1) {
rpage = virt_to_abs(kpage);
if (!rpage) {
ehca_err(&shca->ib_device, "kpage=%p i=%x",
@@ -1060,15 +1061,8 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
ret = -EFAULT;
goto ehca_reg_mr_rpages_exit1;
}
- } else { /* rnum==1 */
- ret = ehca_set_pagebuf_1(e_mr, pginfo, &rpage);
- if (ret) {
- ehca_err(&shca->ib_device, "ehca_set_pagebuf_1 "
- "bad rc, ret=%x i=%x", ret, i);
- ret = -EFAULT;
- goto ehca_reg_mr_rpages_exit1;
- }
- }
+ } else
+ rpage = *kpage;
h_ret = hipz_h_register_rpage_mr(shca->ipz_hca_handle, e_mr,
0, /* pagesize 4k */
@@ -1146,7 +1140,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
}
pginfo_save = *pginfo;
- ret = ehca_set_pagebuf(e_mr, pginfo, pginfo->num_hwpages, kpage);
+ ret = ehca_set_pagebuf(pginfo, pginfo->num_hwpages, kpage);
if (ret) {
ehca_err(&shca->ib_device, "set pagebuf failed, e_mr=%p "
"pginfo=%p type=%x num_kpages=%lx num_hwpages=%lx "
@@ -1306,98 +1300,86 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca,
{
int ret = 0;
u64 h_ret;
- int rereg_1_hcall = 1; /* 1: use hipz_mr_reregister directly */
- int rereg_3_hcall = 0; /* 1: use 3 hipz calls for unmapping */
struct ehca_pd *e_pd =
container_of(e_fmr->ib.ib_fmr.pd, struct ehca_pd, ib_pd);
struct ehca_mr save_fmr;
u32 tmp_lkey, tmp_rkey;
struct ehca_mr_pginfo pginfo;
struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
+ struct ehca_mr save_mr;
- /* first check if reregistration hCall can be used for unmap */
- if (e_fmr->fmr_max_pages > MAX_RPAGES) {
- rereg_1_hcall = 0;
- rereg_3_hcall = 1;
- }
-
- if (rereg_1_hcall) {
+ if (e_fmr->fmr_max_pages <= MAX_RPAGES) {
/*
* note: after using rereg hcall with len=0,
* rereg hcall must be used again for registering pages
*/
h_ret = hipz_h_reregister_pmr(shca->ipz_hca_handle, e_fmr, 0,
0, 0, e_pd->fw_pd, 0, &hipzout);
- if (h_ret != H_SUCCESS) {
- /*
- * should not happen, because length checked above,
- * FMRs are not shared and no MW bound to FMRs
- */
- ehca_err(&shca->ib_device, "hipz_reregister_pmr failed "
- "(Rereg1), h_ret=%lx e_fmr=%p hca_hndl=%lx "
- "mr_hndl=%lx lkey=%x lkey_out=%x",
- h_ret, e_fmr, shca->ipz_hca_handle.handle,
- e_fmr->ipz_mr_handle.handle,
- e_fmr->ib.ib_fmr.lkey, hipzout.lkey);
- rereg_3_hcall = 1;
- } else {
+ if (h_ret == H_SUCCESS) {
/* successful reregistration */
e_fmr->start = NULL;
e_fmr->size = 0;
tmp_lkey = hipzout.lkey;
tmp_rkey = hipzout.rkey;
+ return 0;
}
+ /*
+ * should not happen, because length checked above,
+ * FMRs are not shared and no MW bound to FMRs
+ */
+ ehca_err(&shca->ib_device, "hipz_reregister_pmr failed "
+ "(Rereg1), h_ret=%lx e_fmr=%p hca_hndl=%lx "
+ "mr_hndl=%lx lkey=%x lkey_out=%x",
+ h_ret, e_fmr, shca->ipz_hca_handle.handle,
+ e_fmr->ipz_mr_handle.handle,
+ e_fmr->ib.ib_fmr.lkey, hipzout.lkey);
+ /* try free and rereg */
}
- if (rereg_3_hcall) {
- struct ehca_mr save_mr;
-
- /* first free old FMR */
- h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr);
- if (h_ret != H_SUCCESS) {
- ehca_err(&shca->ib_device, "hipz_free_mr failed, "
- "h_ret=%lx e_fmr=%p hca_hndl=%lx mr_hndl=%lx "
- "lkey=%x",
- h_ret, e_fmr, shca->ipz_hca_handle.handle,
- e_fmr->ipz_mr_handle.handle,
- e_fmr->ib.ib_fmr.lkey);
- ret = ehca2ib_return_code(h_ret);
- goto ehca_unmap_one_fmr_exit0;
- }
- /* clean ehca_mr_t, without changing lock */
- save_fmr = *e_fmr;
- ehca_mr_deletenew(e_fmr);
+ /* first free old FMR */
+ h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr);
+ if (h_ret != H_SUCCESS) {
+ ehca_err(&shca->ib_device, "hipz_free_mr failed, "
+ "h_ret=%lx e_fmr=%p hca_hndl=%lx mr_hndl=%lx "
+ "lkey=%x",
+ h_ret, e_fmr, shca->ipz_hca_handle.handle,
+ e_fmr->ipz_mr_handle.handle,
+ e_fmr->ib.ib_fmr.lkey);
+ ret = ehca2ib_return_code(h_ret);
+ goto ehca_unmap_one_fmr_exit0;
+ }
+ /* clean ehca_mr_t, without changing lock */
+ save_fmr = *e_fmr;
+ ehca_mr_deletenew(e_fmr);
- /* set some MR values */
- e_fmr->flags = save_fmr.flags;
- e_fmr->fmr_page_size = save_fmr.fmr_page_size;
- e_fmr->fmr_max_pages = save_fmr.fmr_max_pages;
- e_fmr->fmr_max_maps = save_fmr.fmr_max_maps;
- e_fmr->fmr_map_cnt = save_fmr.fmr_map_cnt;
- e_fmr->acl = save_fmr.acl;
+ /* set some MR values */
+ e_fmr->flags = save_fmr.flags;
+ e_fmr->fmr_page_size = save_fmr.fmr_page_size;
+ e_fmr->fmr_max_pages = save_fmr.fmr_max_pages;
+ e_fmr->fmr_max_maps = save_fmr.fmr_max_maps;
+ e_fmr->fmr_map_cnt = save_fmr.fmr_map_cnt;
+ e_fmr->acl = save_fmr.acl;
- memset(&pginfo, 0, sizeof(pginfo));
- pginfo.type = EHCA_MR_PGI_FMR;
- pginfo.num_kpages = 0;
- pginfo.num_hwpages = 0;
- ret = ehca_reg_mr(shca, e_fmr, NULL,
- (e_fmr->fmr_max_pages * e_fmr->fmr_page_size),
- e_fmr->acl, e_pd, &pginfo, &tmp_lkey,
- &tmp_rkey);
- if (ret) {
- u32 offset = (u64)(&e_fmr->flags) - (u64)e_fmr;
- memcpy(&e_fmr->flags, &(save_mr.flags),
- sizeof(struct ehca_mr) - offset);
- goto ehca_unmap_one_fmr_exit0;
- }
+ memset(&pginfo, 0, sizeof(pginfo));
+ pginfo.type = EHCA_MR_PGI_FMR;
+ pginfo.num_kpages = 0;
+ pginfo.num_hwpages = 0;
+ ret = ehca_reg_mr(shca, e_fmr, NULL,
+ (e_fmr->fmr_max_pages * e_fmr->fmr_page_size),
+ e_fmr->acl, e_pd, &pginfo, &tmp_lkey,
+ &tmp_rkey);
+ if (ret) {
+ u32 offset = (u64)(&e_fmr->flags) - (u64)e_fmr;
+ memcpy(&e_fmr->flags, &(save_mr.flags),
+ sizeof(struct ehca_mr) - offset);
+ goto ehca_unmap_one_fmr_exit0;
}
ehca_unmap_one_fmr_exit0:
if (ret)
ehca_err(&shca->ib_device, "ret=%x tmp_lkey=%x tmp_rkey=%x "
- "fmr_max_pages=%x rereg_1_hcall=%x rereg_3_hcall=%x",
- ret, tmp_lkey, tmp_rkey, e_fmr->fmr_max_pages,
- rereg_1_hcall, rereg_3_hcall);
+ "fmr_max_pages=%x",
+ ret, tmp_lkey, tmp_rkey, e_fmr->fmr_max_pages);
return ret;
} /* end ehca_unmap_one_fmr() */
@@ -1690,300 +1672,187 @@ int ehca_fmr_check_page_list(struct ehca_mr *e_fmr,
/*----------------------------------------------------------------------*/
-/* setup page buffer from page info */
-int ehca_set_pagebuf(struct ehca_mr *e_mr,
- struct ehca_mr_pginfo *pginfo,
- u32 number,
- u64 *kpage)
+/* PAGE_SIZE >= pginfo->hwpage_size */
+static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo,
+ u32 number,
+ u64 *kpage)
{
int ret = 0;
struct ib_umem_chunk *prev_chunk;
struct ib_umem_chunk *chunk;
- struct ib_phys_buf *pbuf;
- u64 *fmrlist;
- u64 num_hw, pgaddr, offs_hw;
+ u64 pgaddr;
u32 i = 0;
u32 j = 0;
- if (pginfo->type == EHCA_MR_PGI_PHYS) {
- /* loop over desired phys_buf_array entries */
- while (i < number) {
- pbuf = pginfo->u.phy.phys_buf_array
- + pginfo->u.phy.next_buf;
- num_hw = NUM_CHUNKS((pbuf->addr % EHCA_PAGESIZE) +
- pbuf->size, EHCA_PAGESIZE);
- offs_hw = (pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
- while (pginfo->next_hwpage < offs_hw + num_hw) {
- /* sanity check */
- if ((pginfo->kpage_cnt >= pginfo->num_kpages) ||
- (pginfo->hwpage_cnt >= pginfo->num_hwpages)) {
- ehca_gen_err("kpage_cnt >= num_kpages, "
- "kpage_cnt=%lx "
- "num_kpages=%lx "
- "hwpage_cnt=%lx "
- "num_hwpages=%lx i=%x",
- pginfo->kpage_cnt,
- pginfo->num_kpages,
- pginfo->hwpage_cnt,
- pginfo->num_hwpages, i);
- ret = -EFAULT;
- goto ehca_set_pagebuf_exit0;
- }
- *kpage = phys_to_abs(
- (pbuf->addr & EHCA_PAGEMASK)
- + (pginfo->next_hwpage * EHCA_PAGESIZE));
- if ( !(*kpage) && pbuf->addr ) {
- ehca_gen_err("pbuf->addr=%lx "
- "pbuf->size=%lx "
- "next_hwpage=%lx", pbuf->addr,
- pbuf->size,
- pginfo->next_hwpage);
- ret = -EFAULT;
- goto ehca_set_pagebuf_exit0;
- }
- (pginfo->hwpage_cnt)++;
- (pginfo->next_hwpage)++;
- if (pginfo->next_hwpage %
- (PAGE_SIZE / EHCA_PAGESIZE) == 0)
- (pginfo->kpage_cnt)++;
- kpage++;
- i++;
- if (i >= number) break;
- }
- if (pginfo->next_hwpage >= offs_hw + num_hw) {
- (pginfo->u.phy.next_buf)++;
- pginfo->next_hwpage = 0;
- }
- }
- } else if (pginfo->type == EHCA_MR_PGI_USER) {
- /* loop over desired chunk entries */
- chunk = pginfo->u.usr.next_chunk;
- prev_chunk = pginfo->u.usr.next_chunk;
- list_for_each_entry_continue(chunk,
- (&(pginfo->u.usr.region->chunk_list)),
- list) {
- for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) {
- pgaddr = ( page_to_pfn(chunk->page_list[i].page)
- << PAGE_SHIFT );
- *kpage = phys_to_abs(pgaddr +
- (pginfo->next_hwpage *
- EHCA_PAGESIZE));
- if ( !(*kpage) ) {
- ehca_gen_err("pgaddr=%lx "
- "chunk->page_list[i]=%lx "
- "i=%x next_hwpage=%lx mr=%p",
- pgaddr,
- (u64)sg_dma_address(
- &chunk->
- page_list[i]),
- i, pginfo->next_hwpage, e_mr);
- ret = -EFAULT;
- goto ehca_set_pagebuf_exit0;
- }
- (pginfo->hwpage_cnt)++;
- (pginfo->next_hwpage)++;
- kpage++;
- if (pginfo->next_hwpage %
- (PAGE_SIZE / EHCA_PAGESIZE) == 0) {
- (pginfo->kpage_cnt)++;
- (pginfo->u.usr.next_nmap)++;
- pginfo->next_hwpage = 0;
- i++;
- }
- j++;
- if (j >= number) break;
- }
- if ((pginfo->u.usr.next_nmap >= chunk->nmap) &&
- (j >= number)) {
- pginfo->u.usr.next_nmap = 0;
- prev_chunk = chunk;
- break;
- } else if (pginfo->u.usr.next_nmap >= chunk->nmap) {
- pginfo->u.usr.next_nmap = 0;
- prev_chunk = chunk;
- } else if (j >= number)
- break;
- else
- prev_chunk = chunk;
- }
- pginfo->u.usr.next_chunk =
- list_prepare_entry(prev_chunk,
- (&(pginfo->u.usr.region->chunk_list)),
- list);
- } else if (pginfo->type == EHCA_MR_PGI_FMR) {
- /* loop over desired page_list entries */
- fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem;
- for (i = 0; i < number; i++) {
- *kpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) +
- pginfo->next_hwpage * EHCA_PAGESIZE);
+ /* loop over desired chunk entries */
+ chunk = pginfo->u.usr.next_chunk;
+ prev_chunk = pginfo->u.usr.next_chunk;
+ list_for_each_entry_continue(
+ chunk, (&(pginfo->u.usr.region->chunk_list)), list) {
+ for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) {
+ pgaddr = page_to_pfn(chunk->page_list[i].page)
+ << PAGE_SHIFT ;
+ *kpage = phys_to_abs(pgaddr +
+ (pginfo->next_hwpage *
+ EHCA_PAGESIZE));
if ( !(*kpage) ) {
- ehca_gen_err("*fmrlist=%lx fmrlist=%p "
- "next_listelem=%lx next_hwpage=%lx",
- *fmrlist, fmrlist,
- pginfo->u.fmr.next_listelem,
- pginfo->next_hwpage);
- ret = -EFAULT;
- goto ehca_set_pagebuf_exit0;
+ ehca_gen_err("pgaddr=%lx "
+ "chunk->page_list[i]=%lx "
+ "i=%x next_hwpage=%lx",
+ pgaddr, (u64)sg_dma_address(
+ &chunk->page_list[i]),
+ i, pginfo->next_hwpage);
+ return -EFAULT;
}
(pginfo->hwpage_cnt)++;
(pginfo->next_hwpage)++;
kpage++;
if (pginfo->next_hwpage %
- (e_mr->fmr_page_size / EHCA_PAGESIZE) == 0) {
+ (PAGE_SIZE / EHCA_PAGESIZE) == 0) {
(pginfo->kpage_cnt)++;
- (pginfo->u.fmr.next_listelem)++;
- fmrlist++;
+ (pginfo->u.usr.next_nmap)++;
pginfo->next_hwpage = 0;
+ i++;
}
+ j++;
+ if (j >= number) break;
}
- } else {
- ehca_gen_err("bad pginfo->type=%x", pginfo->type);
- ret = -EFAULT;
- goto ehca_set_pagebuf_exit0;
+ if ((pginfo->u.usr.next_nmap >= chunk->nmap) &&
+ (j >= number)) {
+ pginfo->u.usr.next_nmap = 0;
+ prev_chunk = chunk;
+ break;
+ } else if (pginfo->u.usr.next_nmap >= chunk->nmap) {
+ pginfo->u.usr.next_nmap = 0;
+ prev_chunk = chunk;
+ } else if (j >= number)
+ break;
+ else
+ prev_chunk = chunk;
}
-
-ehca_set_pagebuf_exit0:
- if (ret)
- ehca_gen_err("ret=%x e_mr=%p pginfo=%p type=%x num_kpages=%lx "
- "num_hwpages=%lx next_buf=%lx next_hwpage=%lx number=%x "
- "kpage=%p kpage_cnt=%lx hwpage_cnt=%lx i=%x "
- "next_listelem=%lx region=%p next_chunk=%p "
- "next_nmap=%lx", ret, e_mr, pginfo, pginfo->type,
- pginfo->num_kpages, pginfo->num_hwpages,
- pginfo->u.phy.next_buf, pginfo->next_hwpage, number, kpage,
- pginfo->kpage_cnt, pginfo->hwpage_cnt, i,
- pginfo->u.fmr.next_listelem, pginfo->u.usr.region,
- pginfo->u.usr.next_chunk, pginfo->u.usr.next_nmap);
+ pginfo->u.usr.next_chunk =
+ list_prepare_entry(prev_chunk,
+ (&(pginfo->u.usr.region->chunk_list)),
+ list);
return ret;
-} /* end ehca_set_pagebuf() */
-
-/*----------------------------------------------------------------------*/
+}
-/* setup 1 page from page info page buffer */
-int ehca_set_pagebuf_1(struct ehca_mr *e_mr,
- struct ehca_mr_pginfo *pginfo,
- u64 *rpage)
+int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo,
+ u32 number,
+ u64 *kpage)
{
int ret = 0;
- struct ib_phys_buf *tmp_pbuf;
- u64 *fmrlist;
- struct ib_umem_chunk *chunk;
- struct ib_umem_chunk *prev_chunk;
- u64 pgaddr, num_hw, offs_hw;
-
- if (pginfo->type == EHCA_MR_PGI_PHYS) {
- /* sanity check */
- if ((pginfo->kpage_cnt >= pginfo->num_kpages) ||
- (pginfo->hwpage_cnt >= pginfo->num_hwpages)) {
- ehca_gen_err("kpage_cnt >= num_hwpages, kpage_cnt=%lx "
- "num_hwpages=%lx hwpage_cnt=%lx num_hwpages=%lx",
- pginfo->kpage_cnt, pginfo->num_kpages,
- pginfo->hwpage_cnt, pginfo->num_hwpages);
- ret = -EFAULT;
- goto ehca_set_pagebuf_1_exit0;
- }
- tmp_pbuf = pginfo->u.phy.phys_buf_array + pginfo->u.phy.next_buf;
- num_hw = NUM_CHUNKS((tmp_pbuf->addr % EHCA_PAGESIZE) +
- tmp_pbuf->size, EHCA_PAGESIZE);
- offs_hw = (tmp_pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
- *rpage = phys_to_abs((tmp_pbuf->addr & EHCA_PAGEMASK) +
- (pginfo->next_hwpage * EHCA_PAGESIZE));
- if ( !(*rpage) && tmp_pbuf->addr ) {
- ehca_gen_err("tmp_pbuf->addr=%lx"
- " tmp_pbuf->size=%lx next_hwpage=%lx",
- tmp_pbuf->addr, tmp_pbuf->size,
- pginfo->next_hwpage);
- ret = -EFAULT;
- goto ehca_set_pagebuf_1_exit0;
- }
- (pginfo->hwpage_cnt)++;
- (pginfo->next_hwpage)++;
- if (pginfo->next_hwpage % (PAGE_SIZE / EHCA_PAGESIZE) == 0)
- (pginfo->kpage_cnt)++;
- if (pginfo->next_hwpage >= offs_hw + num_hw) {
- (pginfo->u.phy.next_buf)++;
- pginfo->next_hwpage = 0;
- }
- } else if (pginfo->type == EHCA_MR_PGI_USER) {
- chunk = pginfo->u.usr.next_chunk;
- prev_chunk = pginfo->u.usr.next_chunk;
- list_for_each_entry_continue(chunk,
- (&(pginfo->u.usr.region->chunk_list)),
- list) {
- pgaddr = ( page_to_pfn(chunk->page_list[
- pginfo->u.usr.next_nmap].page)
- << PAGE_SHIFT);
- *rpage = phys_to_abs(pgaddr +
- (pginfo->next_hwpage * EHCA_PAGESIZE));
- if ( !(*rpage) ) {
- ehca_gen_err("pgaddr=%lx chunk->page_list[]=%lx"
- " next_nmap=%lx next_hwpage=%lx mr=%p",
- pgaddr, (u64)sg_dma_address(
- &chunk->page_list[
- pginfo->u.usr.
- next_nmap]),
- pginfo->u.usr.next_nmap, pginfo->next_hwpage,
- e_mr);
- ret = -EFAULT;
- goto ehca_set_pagebuf_1_exit0;
+ struct ib_phys_buf *pbuf;
+ u64 num_hw, offs_hw;
+ u32 i = 0;
+
+ /* loop over desired phys_buf_array entries */
+ while (i < number) {
+ pbuf = pginfo->u.phy.phys_buf_array + pginfo->u.phy.next_buf;
+ num_hw = NUM_CHUNKS((pbuf->addr % EHCA_PAGESIZE) +
+ pbuf->size, EHCA_PAGESIZE);
+ offs_hw = (pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
+ while (pginfo->next_hwpage < offs_hw + num_hw) {
+ /* sanity check */
+ if ((pginfo->kpage_cnt >= pginfo->num_kpages) ||
+ (pginfo->hwpage_cnt >= pginfo->num_hwpages)) {
+ ehca_gen_err("kpage_cnt >= num_kpages, "
+ "kpage_cnt=%lx num_kpages=%lx "
+ "hwpage_cnt=%lx "
+ "num_hwpages=%lx i=%x",
+ pginfo->kpage_cnt,
+ pginfo->num_kpages,
+ pginfo->hwpage_cnt,
+ pginfo->num_hwpages, i);
+ return -EFAULT;
+ }
+ *kpage = phys_to_abs(
+ (pbuf->addr & EHCA_PAGEMASK)
+ + (pginfo->next_hwpage * EHCA_PAGESIZE));
+ if ( !(*kpage) && pbuf->addr ) {
+ ehca_gen_err("pbuf->addr=%lx "
+ "pbuf->size=%lx "
+ "next_hwpage=%lx", pbuf->addr,
+ pbuf->size,
+ pginfo->next_hwpage);
+ return -EFAULT;
}
(pginfo->hwpage_cnt)++;
(pginfo->next_hwpage)++;
if (pginfo->next_hwpage %
- (PAGE_SIZE / EHCA_PAGESIZE) == 0) {
+ (PAGE_SIZE / EHCA_PAGESIZE) == 0)
(pginfo->kpage_cnt)++;
- (pginfo->u.usr.next_nmap)++;
- pginfo->next_hwpage = 0;
- }
- if (pginfo->u.usr.next_nmap >= chunk->nmap) {
- pginfo->u.usr.next_nmap = 0;
- prev_chunk = chunk;
- }
- break;
+ kpage++;
+ i++;
+ if (i >= number) break;
}
- pginfo->u.usr.next_chunk =
- list_prepare_entry(prev_chunk,
- (&(pginfo->u.usr.region->chunk_list)),
- list);
- } else if (pginfo->type == EHCA_MR_PGI_FMR) {
- fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem;
- *rpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) +
+ if (pginfo->next_hwpage >= offs_hw + num_hw) {
+ (pginfo->u.phy.next_buf)++;
+ pginfo->next_hwpage = 0;
+ }
+ }
+ return ret;
+}
+
+int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo,
+ u32 number,
+ u64 *kpage)
+{
+ int ret = 0;
+ u64 *fmrlist;
+ u32 i;
+
+ /* loop over desired page_list entries */
+ fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem;
+ for (i = 0; i < number; i++) {
+ *kpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) +
pginfo->next_hwpage * EHCA_PAGESIZE);
- if ( !(*rpage) ) {
+ if ( !(*kpage) ) {
ehca_gen_err("*fmrlist=%lx fmrlist=%p "
"next_listelem=%lx next_hwpage=%lx",
- *fmrlist, fmrlist, pginfo->u.fmr.next_listelem,
+ *fmrlist, fmrlist,
+ pginfo->u.fmr.next_listelem,
pginfo->next_hwpage);
- ret = -EFAULT;
- goto ehca_set_pagebuf_1_exit0;
+ return -EFAULT;
}
(pginfo->hwpage_cnt)++;
(pginfo->next_hwpage)++;
+ kpage++;
if (pginfo->next_hwpage %
- (e_mr->fmr_page_size / EHCA_PAGESIZE) == 0) {
+ (pginfo->u.fmr.fmr_pgsize / EHCA_PAGESIZE) == 0) {
(pginfo->kpage_cnt)++;
(pginfo->u.fmr.next_listelem)++;
+ fmrlist++;
pginfo->next_hwpage = 0;
}
- } else {
+ }
+ return ret;
+}
+
+/* setup page buffer from page info */
+int ehca_set_pagebuf(struct ehca_mr_pginfo *pginfo,
+ u32 number,
+ u64 *kpage)
+{
+ int ret;
+
+ switch (pginfo->type) {
+ case EHCA_MR_PGI_PHYS:
+ ret = ehca_set_pagebuf_phys(pginfo, number, kpage);
+ break;
+ case EHCA_MR_PGI_USER:
+ ret = ehca_set_pagebuf_user1(pginfo, number, kpage);
+ break;
+ case EHCA_MR_PGI_FMR:
+ ret = ehca_set_pagebuf_fmr(pginfo, number, kpage);
+ break;
+ default:
ehca_gen_err("bad pginfo->type=%x", pginfo->type);
ret = -EFAULT;
- goto ehca_set_pagebuf_1_exit0;
+ break;
}
-
-ehca_set_pagebuf_1_exit0:
- if (ret)
- ehca_gen_err("ret=%x e_mr=%p pginfo=%p type=%x num_kpages=%lx "
- "num_hwpages=%lx next_buf=%lx next_hwpage=%lx rpage=%p "
- "kpage_cnt=%lx hwpage_cnt=%lx next_listelem=%lx "
- "region=%p next_chunk=%p next_nmap=%lx", ret, e_mr,
- pginfo, pginfo->type, pginfo->num_kpages,
- pginfo->num_hwpages, pginfo->u.phy.next_buf, pginfo->next_hwpage,
- rpage, pginfo->kpage_cnt, pginfo->hwpage_cnt,
- pginfo->u.fmr.next_listelem, pginfo->u.usr.region,
- pginfo->u.usr.next_chunk, pginfo->u.usr.next_nmap);
return ret;
-} /* end ehca_set_pagebuf_1() */
+} /* end ehca_set_pagebuf() */
/*----------------------------------------------------------------------*/
--
1.5.2
^ permalink raw reply related
* [PATCH 07/10] IB/ehca: MR/MW structure refactoring
From: Joachim Fenkes @ 2007-07-12 15:52 UTC (permalink / raw)
To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier
Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200707121745.27592.fenkes@de.ibm.com>
From: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
- Rename struct ehca_mr fields to clearly distinguish between kernel and HW
page size
- Sort struct ehca_mr_pginfo into a common part and a union containing
specific fields for physical, user and fast MR
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_classes.h | 50 ++--
drivers/infiniband/hw/ehca/ehca_mrmw.c | 511 +++++++++++++++--------------
2 files changed, 284 insertions(+), 277 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index b2d614a..92103df 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -211,8 +211,8 @@ struct ehca_mr {
spinlock_t mrlock;
enum ehca_mr_flag flags;
- u32 num_pages; /* number of MR pages */
- u32 num_4k; /* number of 4k "page" portions to form MR */
+ u32 num_kpages; /* number of kernel pages */
+ u32 num_hwpages; /* number of hw pages to form MR */
int acl; /* ACL (stored here for usage in reregister) */
u64 *start; /* virtual start address (stored here for */
/* usage in reregister) */
@@ -224,9 +224,6 @@ struct ehca_mr {
/* fw specific data */
struct ipz_mrmw_handle ipz_mr_handle; /* MR handle for h-calls */
struct h_galpas galpas;
- /* data for userspace bridge */
- u32 nr_of_pages;
- void *pagearray;
};
struct ehca_mw {
@@ -248,26 +245,29 @@ enum ehca_mr_pgi_type {
struct ehca_mr_pginfo {
enum ehca_mr_pgi_type type;
- u64 num_pages;
- u64 page_cnt;
- u64 num_4k; /* number of 4k "page" portions */
- u64 page_4k_cnt; /* counter for 4k "page" portions */
- u64 next_4k; /* next 4k "page" portion in buffer/chunk/listelem */
-
- /* type EHCA_MR_PGI_PHYS section */
- int num_phys_buf;
- struct ib_phys_buf *phys_buf_array;
- u64 next_buf;
-
- /* type EHCA_MR_PGI_USER section */
- struct ib_umem *region;
- struct ib_umem_chunk *next_chunk;
- u64 next_nmap;
-
- /* type EHCA_MR_PGI_FMR section */
- u64 *page_list;
- u64 next_listelem;
- /* next_4k also used within EHCA_MR_PGI_FMR */
+ u64 num_kpages;
+ u64 kpage_cnt;
+ u64 num_hwpages; /* number of hw pages */
+ u64 hwpage_cnt; /* counter for hw pages */
+ u64 next_hwpage; /* next hw page in buffer/chunk/listelem */
+
+ union {
+ struct { /* type EHCA_MR_PGI_PHYS section */
+ int num_phys_buf;
+ struct ib_phys_buf *phys_buf_array;
+ u64 next_buf;
+ } phy;
+ struct { /* type EHCA_MR_PGI_USER section */
+ struct ib_umem *region;
+ struct ib_umem_chunk *next_chunk;
+ u64 next_nmap;
+ } usr;
+ struct { /* type EHCA_MR_PGI_FMR section */
+ u64 fmr_pgsize;
+ u64 *page_list;
+ u64 next_listelem;
+ } fmr;
+ } u;
};
/* output parameters for MR/FMR hipz calls */
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index 58e8b33..53b334b 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -150,9 +150,6 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
u64 size;
- struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
- u32 num_pages_mr;
- u32 num_pages_4k; /* 4k portion "pages" */
if ((num_phys_buf <= 0) || !phys_buf_array) {
ehca_err(pd->device, "bad input values: num_phys_buf=%x "
@@ -196,12 +193,6 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
goto reg_phys_mr_exit0;
}
- /* determine number of MR pages */
- num_pages_mr = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size,
- PAGE_SIZE);
- num_pages_4k = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE) + size,
- EHCA_PAGESIZE);
-
/* register MR on HCA */
if (ehca_mr_is_maxmr(size, iova_start)) {
e_mr->flags |= EHCA_MR_FLAG_MAXMR;
@@ -213,13 +204,22 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
goto reg_phys_mr_exit1;
}
} else {
- pginfo.type = EHCA_MR_PGI_PHYS;
- pginfo.num_pages = num_pages_mr;
- pginfo.num_4k = num_pages_4k;
- pginfo.num_phys_buf = num_phys_buf;
- pginfo.phys_buf_array = phys_buf_array;
- pginfo.next_4k = (((u64)iova_start & ~PAGE_MASK) /
- EHCA_PAGESIZE);
+ struct ehca_mr_pginfo pginfo;
+ u32 num_kpages;
+ u32 num_hwpages;
+
+ num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size,
+ PAGE_SIZE);
+ num_hwpages = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE) +
+ size, EHCA_PAGESIZE);
+ memset(&pginfo, 0, sizeof(pginfo));
+ pginfo.type = EHCA_MR_PGI_PHYS;
+ pginfo.num_kpages = num_kpages;
+ pginfo.num_hwpages = num_hwpages;
+ pginfo.u.phy.num_phys_buf = num_phys_buf;
+ pginfo.u.phy.phys_buf_array = phys_buf_array;
+ pginfo.next_hwpage = (((u64)iova_start & ~PAGE_MASK) /
+ EHCA_PAGESIZE);
ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags,
e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
@@ -254,10 +254,10 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt
struct ehca_shca *shca =
container_of(pd->device, struct ehca_shca, ib_device);
struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
- struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
+ struct ehca_mr_pginfo pginfo;
int ret;
- u32 num_pages_mr;
- u32 num_pages_4k; /* 4k portion "pages" */
+ u32 num_kpages;
+ u32 num_hwpages;
if (!pd) {
ehca_gen_err("bad pd=%p", pd);
@@ -307,19 +307,20 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt
}
/* determine number of MR pages */
- num_pages_mr = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE);
- num_pages_4k = NUM_CHUNKS((virt % EHCA_PAGESIZE) + length,
- EHCA_PAGESIZE);
+ num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE);
+ num_hwpages = NUM_CHUNKS((virt % EHCA_PAGESIZE) + length,
+ EHCA_PAGESIZE);
/* register MR on HCA */
- pginfo.type = EHCA_MR_PGI_USER;
- pginfo.num_pages = num_pages_mr;
- pginfo.num_4k = num_pages_4k;
- pginfo.region = e_mr->umem;
- pginfo.next_4k = e_mr->umem->offset / EHCA_PAGESIZE;
- pginfo.next_chunk = list_prepare_entry(pginfo.next_chunk,
- (&e_mr->umem->chunk_list),
- list);
+ memset(&pginfo, 0, sizeof(pginfo));
+ pginfo.type = EHCA_MR_PGI_USER;
+ pginfo.num_kpages = num_kpages;
+ pginfo.num_hwpages = num_hwpages;
+ pginfo.u.usr.region = e_mr->umem;
+ pginfo.next_hwpage = e_mr->umem->offset / EHCA_PAGESIZE;
+ pginfo.u.usr.next_chunk = list_prepare_entry(pginfo.u.usr.next_chunk,
+ (&e_mr->umem->chunk_list),
+ list);
ret = ehca_reg_mr(shca, e_mr, (u64*) virt, length, mr_access_flags, e_pd,
&pginfo, &e_mr->ib.ib_mr.lkey, &e_mr->ib.ib_mr.rkey);
@@ -365,9 +366,9 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
struct ehca_pd *new_pd;
u32 tmp_lkey, tmp_rkey;
unsigned long sl_flags;
- u32 num_pages_mr = 0;
- u32 num_pages_4k = 0; /* 4k portion "pages" */
- struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
+ u32 num_kpages = 0;
+ u32 num_hwpages = 0;
+ struct ehca_mr_pginfo pginfo;
u32 cur_pid = current->tgid;
if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
@@ -463,17 +464,18 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
ret = -EINVAL;
goto rereg_phys_mr_exit1;
}
- num_pages_mr = NUM_CHUNKS(((u64)new_start % PAGE_SIZE) +
- new_size, PAGE_SIZE);
- num_pages_4k = NUM_CHUNKS(((u64)new_start % EHCA_PAGESIZE) +
- new_size, EHCA_PAGESIZE);
- pginfo.type = EHCA_MR_PGI_PHYS;
- pginfo.num_pages = num_pages_mr;
- pginfo.num_4k = num_pages_4k;
- pginfo.num_phys_buf = num_phys_buf;
- pginfo.phys_buf_array = phys_buf_array;
- pginfo.next_4k = (((u64)iova_start & ~PAGE_MASK) /
- EHCA_PAGESIZE);
+ num_kpages = NUM_CHUNKS(((u64)new_start % PAGE_SIZE) +
+ new_size, PAGE_SIZE);
+ num_hwpages = NUM_CHUNKS(((u64)new_start % EHCA_PAGESIZE) +
+ new_size, EHCA_PAGESIZE);
+ memset(&pginfo, 0, sizeof(pginfo));
+ pginfo.type = EHCA_MR_PGI_PHYS;
+ pginfo.num_kpages = num_kpages;
+ pginfo.num_hwpages = num_hwpages;
+ pginfo.u.phy.num_phys_buf = num_phys_buf;
+ pginfo.u.phy.phys_buf_array = phys_buf_array;
+ pginfo.next_hwpage = (((u64)iova_start & ~PAGE_MASK) /
+ EHCA_PAGESIZE);
}
if (mr_rereg_mask & IB_MR_REREG_ACCESS)
new_acl = mr_access_flags;
@@ -544,11 +546,11 @@ int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
ret = ehca2ib_return_code(h_ret);
goto query_mr_exit1;
}
- mr_attr->pd = mr->pd;
+ mr_attr->pd = mr->pd;
mr_attr->device_virt_addr = hipzout.vaddr;
- mr_attr->size = hipzout.len;
- mr_attr->lkey = hipzout.lkey;
- mr_attr->rkey = hipzout.rkey;
+ mr_attr->size = hipzout.len;
+ mr_attr->lkey = hipzout.lkey;
+ mr_attr->rkey = hipzout.rkey;
ehca_mrmw_reverse_map_acl(&hipzout.acl, &mr_attr->mr_access_flags);
query_mr_exit1:
@@ -704,7 +706,7 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
struct ehca_mr *e_fmr;
int ret;
u32 tmp_lkey, tmp_rkey;
- struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
+ struct ehca_mr_pginfo pginfo;
/* check other parameters */
if (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) &&
@@ -750,6 +752,7 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
e_fmr->flags |= EHCA_MR_FLAG_FMR;
/* register MR on HCA */
+ memset(&pginfo, 0, sizeof(pginfo));
ret = ehca_reg_mr(shca, e_fmr, NULL,
fmr_attr->max_pages * (1 << fmr_attr->page_shift),
mr_access_flags, e_pd, &pginfo,
@@ -788,7 +791,7 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr,
container_of(fmr->device, struct ehca_shca, ib_device);
struct ehca_mr *e_fmr = container_of(fmr, struct ehca_mr, ib.ib_fmr);
struct ehca_pd *e_pd = container_of(fmr->pd, struct ehca_pd, ib_pd);
- struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
+ struct ehca_mr_pginfo pginfo;
u32 tmp_lkey, tmp_rkey;
if (!(e_fmr->flags & EHCA_MR_FLAG_FMR)) {
@@ -814,12 +817,13 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr,
fmr, e_fmr->fmr_map_cnt, e_fmr->fmr_max_maps);
}
- pginfo.type = EHCA_MR_PGI_FMR;
- pginfo.num_pages = list_len;
- pginfo.num_4k = list_len * (e_fmr->fmr_page_size / EHCA_PAGESIZE);
- pginfo.page_list = page_list;
- pginfo.next_4k = ((iova & (e_fmr->fmr_page_size-1)) /
- EHCA_PAGESIZE);
+ memset(&pginfo, 0, sizeof(pginfo));
+ pginfo.type = EHCA_MR_PGI_FMR;
+ pginfo.num_kpages = list_len;
+ pginfo.num_hwpages = list_len * (e_fmr->fmr_page_size / EHCA_PAGESIZE);
+ pginfo.u.fmr.page_list = page_list;
+ pginfo.next_hwpage = ((iova & (e_fmr->fmr_page_size-1)) /
+ EHCA_PAGESIZE);
ret = ehca_rereg_mr(shca, e_fmr, (u64*)iova,
list_len * e_fmr->fmr_page_size,
@@ -979,11 +983,11 @@ int ehca_reg_mr(struct ehca_shca *shca,
goto ehca_reg_mr_exit1;
/* successful registration */
- e_mr->num_pages = pginfo->num_pages;
- e_mr->num_4k = pginfo->num_4k;
- e_mr->start = iova_start;
- e_mr->size = size;
- e_mr->acl = acl;
+ e_mr->num_kpages = pginfo->num_kpages;
+ e_mr->num_hwpages = pginfo->num_hwpages;
+ e_mr->start = iova_start;
+ e_mr->size = size;
+ e_mr->acl = acl;
*lkey = hipzout.lkey;
*rkey = hipzout.rkey;
return 0;
@@ -993,10 +997,10 @@ ehca_reg_mr_exit1:
if (h_ret != H_SUCCESS) {
ehca_err(&shca->ib_device, "h_ret=%lx shca=%p e_mr=%p "
"iova_start=%p size=%lx acl=%x e_pd=%p lkey=%x "
- "pginfo=%p num_pages=%lx num_4k=%lx ret=%x",
+ "pginfo=%p num_kpages=%lx num_hwpages=%lx ret=%x",
h_ret, shca, e_mr, iova_start, size, acl, e_pd,
- hipzout.lkey, pginfo, pginfo->num_pages,
- pginfo->num_4k, ret);
+ hipzout.lkey, pginfo, pginfo->num_kpages,
+ pginfo->num_hwpages, ret);
ehca_err(&shca->ib_device, "internal error in ehca_reg_mr, "
"not recoverable");
}
@@ -1004,9 +1008,9 @@ ehca_reg_mr_exit0:
if (ret)
ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p "
"iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p "
- "num_pages=%lx num_4k=%lx",
+ "num_kpages=%lx num_hwpages=%lx",
ret, shca, e_mr, iova_start, size, acl, e_pd, pginfo,
- pginfo->num_pages, pginfo->num_4k);
+ pginfo->num_kpages, pginfo->num_hwpages);
return ret;
} /* end ehca_reg_mr() */
@@ -1031,10 +1035,10 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
}
/* max 512 pages per shot */
- for (i = 0; i < NUM_CHUNKS(pginfo->num_4k, MAX_RPAGES); i++) {
+ for (i = 0; i < NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES); i++) {
- if (i == NUM_CHUNKS(pginfo->num_4k, MAX_RPAGES) - 1) {
- rnum = pginfo->num_4k % MAX_RPAGES; /* last shot */
+ if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) {
+ rnum = pginfo->num_hwpages % MAX_RPAGES; /* last shot */
if (rnum == 0)
rnum = MAX_RPAGES; /* last shot is full */
} else
@@ -1070,7 +1074,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
0, /* pagesize 4k */
0, rpage, rnum);
- if (i == NUM_CHUNKS(pginfo->num_4k, MAX_RPAGES) - 1) {
+ if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) {
/*
* check for 'registration complete'==H_SUCCESS
* and for 'page registered'==H_PAGE_REGISTERED
@@ -1106,8 +1110,8 @@ ehca_reg_mr_rpages_exit1:
ehca_reg_mr_rpages_exit0:
if (ret)
ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p "
- "num_pages=%lx num_4k=%lx", ret, shca, e_mr, pginfo,
- pginfo->num_pages, pginfo->num_4k);
+ "num_kpages=%lx num_hwpages=%lx", ret, shca, e_mr,
+ pginfo, pginfo->num_kpages, pginfo->num_hwpages);
return ret;
} /* end ehca_reg_mr_rpages() */
@@ -1142,12 +1146,12 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
}
pginfo_save = *pginfo;
- ret = ehca_set_pagebuf(e_mr, pginfo, pginfo->num_4k, kpage);
+ ret = ehca_set_pagebuf(e_mr, pginfo, pginfo->num_hwpages, kpage);
if (ret) {
ehca_err(&shca->ib_device, "set pagebuf failed, e_mr=%p "
- "pginfo=%p type=%x num_pages=%lx num_4k=%lx kpage=%p",
- e_mr, pginfo, pginfo->type, pginfo->num_pages,
- pginfo->num_4k,kpage);
+ "pginfo=%p type=%x num_kpages=%lx num_hwpages=%lx "
+ "kpage=%p", e_mr, pginfo, pginfo->type,
+ pginfo->num_kpages, pginfo->num_hwpages, kpage);
goto ehca_rereg_mr_rereg1_exit1;
}
rpage = virt_to_abs(kpage);
@@ -1181,11 +1185,11 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
* successful reregistration
* note: start and start_out are identical for eServer HCAs
*/
- e_mr->num_pages = pginfo->num_pages;
- e_mr->num_4k = pginfo->num_4k;
- e_mr->start = iova_start;
- e_mr->size = size;
- e_mr->acl = acl;
+ e_mr->num_kpages = pginfo->num_kpages;
+ e_mr->num_hwpages = pginfo->num_hwpages;
+ e_mr->start = iova_start;
+ e_mr->size = size;
+ e_mr->acl = acl;
*lkey = hipzout.lkey;
*rkey = hipzout.rkey;
}
@@ -1195,9 +1199,9 @@ ehca_rereg_mr_rereg1_exit1:
ehca_rereg_mr_rereg1_exit0:
if ( ret && (ret != -EAGAIN) )
ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x "
- "pginfo=%p num_pages=%lx num_4k=%lx",
- ret, *lkey, *rkey, pginfo, pginfo->num_pages,
- pginfo->num_4k);
+ "pginfo=%p num_kpages=%lx num_hwpages=%lx",
+ ret, *lkey, *rkey, pginfo, pginfo->num_kpages,
+ pginfo->num_hwpages);
return ret;
} /* end ehca_rereg_mr_rereg1() */
@@ -1219,10 +1223,12 @@ int ehca_rereg_mr(struct ehca_shca *shca,
int rereg_3_hcall = 0; /* 1: use 3 hipz calls for reregistration */
/* first determine reregistration hCall(s) */
- if ((pginfo->num_4k > MAX_RPAGES) || (e_mr->num_4k > MAX_RPAGES) ||
- (pginfo->num_4k > e_mr->num_4k)) {
- ehca_dbg(&shca->ib_device, "Rereg3 case, pginfo->num_4k=%lx "
- "e_mr->num_4k=%x", pginfo->num_4k, e_mr->num_4k);
+ if ((pginfo->num_hwpages > MAX_RPAGES) ||
+ (e_mr->num_hwpages > MAX_RPAGES) ||
+ (pginfo->num_hwpages > e_mr->num_hwpages)) {
+ ehca_dbg(&shca->ib_device, "Rereg3 case, "
+ "pginfo->num_hwpages=%lx e_mr->num_hwpages=%x",
+ pginfo->num_hwpages, e_mr->num_hwpages);
rereg_1_hcall = 0;
rereg_3_hcall = 1;
}
@@ -1286,9 +1292,9 @@ ehca_rereg_mr_exit0:
if (ret)
ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p "
"iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p "
- "num_pages=%lx lkey=%x rkey=%x rereg_1_hcall=%x "
+ "num_kpages=%lx lkey=%x rkey=%x rereg_1_hcall=%x "
"rereg_3_hcall=%x", ret, shca, e_mr, iova_start, size,
- acl, e_pd, pginfo, pginfo->num_pages, *lkey, *rkey,
+ acl, e_pd, pginfo, pginfo->num_kpages, *lkey, *rkey,
rereg_1_hcall, rereg_3_hcall);
return ret;
} /* end ehca_rereg_mr() */
@@ -1306,7 +1312,7 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca,
container_of(e_fmr->ib.ib_fmr.pd, struct ehca_pd, ib_pd);
struct ehca_mr save_fmr;
u32 tmp_lkey, tmp_rkey;
- struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
+ struct ehca_mr_pginfo pginfo;
struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
/* first check if reregistration hCall can be used for unmap */
@@ -1370,9 +1376,10 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca,
e_fmr->fmr_map_cnt = save_fmr.fmr_map_cnt;
e_fmr->acl = save_fmr.acl;
- pginfo.type = EHCA_MR_PGI_FMR;
- pginfo.num_pages = 0;
- pginfo.num_4k = 0;
+ memset(&pginfo, 0, sizeof(pginfo));
+ pginfo.type = EHCA_MR_PGI_FMR;
+ pginfo.num_kpages = 0;
+ pginfo.num_hwpages = 0;
ret = ehca_reg_mr(shca, e_fmr, NULL,
(e_fmr->fmr_max_pages * e_fmr->fmr_page_size),
e_fmr->acl, e_pd, &pginfo, &tmp_lkey,
@@ -1428,11 +1435,11 @@ int ehca_reg_smr(struct ehca_shca *shca,
goto ehca_reg_smr_exit0;
}
/* successful registration */
- e_newmr->num_pages = e_origmr->num_pages;
- e_newmr->num_4k = e_origmr->num_4k;
- e_newmr->start = iova_start;
- e_newmr->size = e_origmr->size;
- e_newmr->acl = acl;
+ e_newmr->num_kpages = e_origmr->num_kpages;
+ e_newmr->num_hwpages = e_origmr->num_hwpages;
+ e_newmr->start = iova_start;
+ e_newmr->size = e_origmr->size;
+ e_newmr->acl = acl;
e_newmr->ipz_mr_handle = hipzout.handle;
*lkey = hipzout.lkey;
*rkey = hipzout.rkey;
@@ -1458,10 +1465,10 @@ int ehca_reg_internal_maxmr(
struct ehca_mr *e_mr;
u64 *iova_start;
u64 size_maxmr;
- struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
+ struct ehca_mr_pginfo pginfo;
struct ib_phys_buf ib_pbuf;
- u32 num_pages_mr;
- u32 num_pages_4k; /* 4k portion "pages" */
+ u32 num_kpages;
+ u32 num_hwpages;
e_mr = ehca_mr_new();
if (!e_mr) {
@@ -1476,25 +1483,26 @@ int ehca_reg_internal_maxmr(
iova_start = (u64*)KERNELBASE;
ib_pbuf.addr = 0;
ib_pbuf.size = size_maxmr;
- num_pages_mr = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr,
- PAGE_SIZE);
- num_pages_4k = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE)
- + size_maxmr, EHCA_PAGESIZE);
-
- pginfo.type = EHCA_MR_PGI_PHYS;
- pginfo.num_pages = num_pages_mr;
- pginfo.num_4k = num_pages_4k;
- pginfo.num_phys_buf = 1;
- pginfo.phys_buf_array = &ib_pbuf;
+ num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr,
+ PAGE_SIZE);
+ num_hwpages = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE) + size_maxmr,
+ EHCA_PAGESIZE);
+
+ memset(&pginfo, 0, sizeof(pginfo));
+ pginfo.type = EHCA_MR_PGI_PHYS;
+ pginfo.num_kpages = num_kpages;
+ pginfo.num_hwpages = num_hwpages;
+ pginfo.u.phy.num_phys_buf = 1;
+ pginfo.u.phy.phys_buf_array = &ib_pbuf;
ret = ehca_reg_mr(shca, e_mr, iova_start, size_maxmr, 0, e_pd,
&pginfo, &e_mr->ib.ib_mr.lkey,
&e_mr->ib.ib_mr.rkey);
if (ret) {
ehca_err(&shca->ib_device, "reg of internal max MR failed, "
- "e_mr=%p iova_start=%p size_maxmr=%lx num_pages_mr=%x "
- "num_pages_4k=%x", e_mr, iova_start, size_maxmr,
- num_pages_mr, num_pages_4k);
+ "e_mr=%p iova_start=%p size_maxmr=%lx num_kpages=%x "
+ "num_hwpages=%x", e_mr, iova_start, size_maxmr,
+ num_kpages, num_hwpages);
goto ehca_reg_internal_maxmr_exit1;
}
@@ -1546,11 +1554,11 @@ int ehca_reg_maxmr(struct ehca_shca *shca,
return ehca2ib_return_code(h_ret);
}
/* successful registration */
- e_newmr->num_pages = e_origmr->num_pages;
- e_newmr->num_4k = e_origmr->num_4k;
- e_newmr->start = iova_start;
- e_newmr->size = e_origmr->size;
- e_newmr->acl = acl;
+ e_newmr->num_kpages = e_origmr->num_kpages;
+ e_newmr->num_hwpages = e_origmr->num_hwpages;
+ e_newmr->start = iova_start;
+ e_newmr->size = e_origmr->size;
+ e_newmr->acl = acl;
e_newmr->ipz_mr_handle = hipzout.handle;
*lkey = hipzout.lkey;
*rkey = hipzout.rkey;
@@ -1693,138 +1701,139 @@ int ehca_set_pagebuf(struct ehca_mr *e_mr,
struct ib_umem_chunk *chunk;
struct ib_phys_buf *pbuf;
u64 *fmrlist;
- u64 num4k, pgaddr, offs4k;
+ u64 num_hw, pgaddr, offs_hw;
u32 i = 0;
u32 j = 0;
if (pginfo->type == EHCA_MR_PGI_PHYS) {
/* loop over desired phys_buf_array entries */
while (i < number) {
- pbuf = pginfo->phys_buf_array + pginfo->next_buf;
- num4k = NUM_CHUNKS((pbuf->addr % EHCA_PAGESIZE)
- + pbuf->size, EHCA_PAGESIZE);
- offs4k = (pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
- while (pginfo->next_4k < offs4k + num4k) {
+ pbuf = pginfo->u.phy.phys_buf_array
+ + pginfo->u.phy.next_buf;
+ num_hw = NUM_CHUNKS((pbuf->addr % EHCA_PAGESIZE) +
+ pbuf->size, EHCA_PAGESIZE);
+ offs_hw = (pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
+ while (pginfo->next_hwpage < offs_hw + num_hw) {
/* sanity check */
- if ((pginfo->page_cnt >= pginfo->num_pages) ||
- (pginfo->page_4k_cnt >= pginfo->num_4k)) {
- ehca_gen_err("page_cnt >= num_pages, "
- "page_cnt=%lx "
- "num_pages=%lx "
- "page_4k_cnt=%lx "
- "num_4k=%lx i=%x",
- pginfo->page_cnt,
- pginfo->num_pages,
- pginfo->page_4k_cnt,
- pginfo->num_4k, i);
+ if ((pginfo->kpage_cnt >= pginfo->num_kpages) ||
+ (pginfo->hwpage_cnt >= pginfo->num_hwpages)) {
+ ehca_gen_err("kpage_cnt >= num_kpages, "
+ "kpage_cnt=%lx "
+ "num_kpages=%lx "
+ "hwpage_cnt=%lx "
+ "num_hwpages=%lx i=%x",
+ pginfo->kpage_cnt,
+ pginfo->num_kpages,
+ pginfo->hwpage_cnt,
+ pginfo->num_hwpages, i);
ret = -EFAULT;
goto ehca_set_pagebuf_exit0;
}
*kpage = phys_to_abs(
(pbuf->addr & EHCA_PAGEMASK)
- + (pginfo->next_4k * EHCA_PAGESIZE));
+ + (pginfo->next_hwpage * EHCA_PAGESIZE));
if ( !(*kpage) && pbuf->addr ) {
ehca_gen_err("pbuf->addr=%lx "
"pbuf->size=%lx "
- "next_4k=%lx", pbuf->addr,
+ "next_hwpage=%lx", pbuf->addr,
pbuf->size,
- pginfo->next_4k);
+ pginfo->next_hwpage);
ret = -EFAULT;
goto ehca_set_pagebuf_exit0;
}
- (pginfo->page_4k_cnt)++;
- (pginfo->next_4k)++;
- if (pginfo->next_4k %
+ (pginfo->hwpage_cnt)++;
+ (pginfo->next_hwpage)++;
+ if (pginfo->next_hwpage %
(PAGE_SIZE / EHCA_PAGESIZE) == 0)
- (pginfo->page_cnt)++;
+ (pginfo->kpage_cnt)++;
kpage++;
i++;
if (i >= number) break;
}
- if (pginfo->next_4k >= offs4k + num4k) {
- (pginfo->next_buf)++;
- pginfo->next_4k = 0;
+ if (pginfo->next_hwpage >= offs_hw + num_hw) {
+ (pginfo->u.phy.next_buf)++;
+ pginfo->next_hwpage = 0;
}
}
} else if (pginfo->type == EHCA_MR_PGI_USER) {
/* loop over desired chunk entries */
- chunk = pginfo->next_chunk;
- prev_chunk = pginfo->next_chunk;
+ chunk = pginfo->u.usr.next_chunk;
+ prev_chunk = pginfo->u.usr.next_chunk;
list_for_each_entry_continue(chunk,
- (&(pginfo->region->chunk_list)),
+ (&(pginfo->u.usr.region->chunk_list)),
list) {
- for (i = pginfo->next_nmap; i < chunk->nmap; ) {
+ for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) {
pgaddr = ( page_to_pfn(chunk->page_list[i].page)
<< PAGE_SHIFT );
*kpage = phys_to_abs(pgaddr +
- (pginfo->next_4k *
+ (pginfo->next_hwpage *
EHCA_PAGESIZE));
if ( !(*kpage) ) {
ehca_gen_err("pgaddr=%lx "
"chunk->page_list[i]=%lx "
- "i=%x next_4k=%lx mr=%p",
+ "i=%x next_hwpage=%lx mr=%p",
pgaddr,
(u64)sg_dma_address(
&chunk->
page_list[i]),
- i, pginfo->next_4k, e_mr);
+ i, pginfo->next_hwpage, e_mr);
ret = -EFAULT;
goto ehca_set_pagebuf_exit0;
}
- (pginfo->page_4k_cnt)++;
- (pginfo->next_4k)++;
+ (pginfo->hwpage_cnt)++;
+ (pginfo->next_hwpage)++;
kpage++;
- if (pginfo->next_4k %
+ if (pginfo->next_hwpage %
(PAGE_SIZE / EHCA_PAGESIZE) == 0) {
- (pginfo->page_cnt)++;
- (pginfo->next_nmap)++;
- pginfo->next_4k = 0;
+ (pginfo->kpage_cnt)++;
+ (pginfo->u.usr.next_nmap)++;
+ pginfo->next_hwpage = 0;
i++;
}
j++;
if (j >= number) break;
}
- if ((pginfo->next_nmap >= chunk->nmap) &&
+ if ((pginfo->u.usr.next_nmap >= chunk->nmap) &&
(j >= number)) {
- pginfo->next_nmap = 0;
+ pginfo->u.usr.next_nmap = 0;
prev_chunk = chunk;
break;
- } else if (pginfo->next_nmap >= chunk->nmap) {
- pginfo->next_nmap = 0;
+ } else if (pginfo->u.usr.next_nmap >= chunk->nmap) {
+ pginfo->u.usr.next_nmap = 0;
prev_chunk = chunk;
} else if (j >= number)
break;
else
prev_chunk = chunk;
}
- pginfo->next_chunk =
+ pginfo->u.usr.next_chunk =
list_prepare_entry(prev_chunk,
- (&(pginfo->region->chunk_list)),
+ (&(pginfo->u.usr.region->chunk_list)),
list);
} else if (pginfo->type == EHCA_MR_PGI_FMR) {
/* loop over desired page_list entries */
- fmrlist = pginfo->page_list + pginfo->next_listelem;
+ fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem;
for (i = 0; i < number; i++) {
*kpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) +
- pginfo->next_4k * EHCA_PAGESIZE);
+ pginfo->next_hwpage * EHCA_PAGESIZE);
if ( !(*kpage) ) {
ehca_gen_err("*fmrlist=%lx fmrlist=%p "
- "next_listelem=%lx next_4k=%lx",
+ "next_listelem=%lx next_hwpage=%lx",
*fmrlist, fmrlist,
- pginfo->next_listelem,
- pginfo->next_4k);
+ pginfo->u.fmr.next_listelem,
+ pginfo->next_hwpage);
ret = -EFAULT;
goto ehca_set_pagebuf_exit0;
}
- (pginfo->page_4k_cnt)++;
- (pginfo->next_4k)++;
+ (pginfo->hwpage_cnt)++;
+ (pginfo->next_hwpage)++;
kpage++;
- if (pginfo->next_4k %
+ if (pginfo->next_hwpage %
(e_mr->fmr_page_size / EHCA_PAGESIZE) == 0) {
- (pginfo->page_cnt)++;
- (pginfo->next_listelem)++;
+ (pginfo->kpage_cnt)++;
+ (pginfo->u.fmr.next_listelem)++;
fmrlist++;
- pginfo->next_4k = 0;
+ pginfo->next_hwpage = 0;
}
}
} else {
@@ -1835,16 +1844,16 @@ int ehca_set_pagebuf(struct ehca_mr *e_mr,
ehca_set_pagebuf_exit0:
if (ret)
- ehca_gen_err("ret=%x e_mr=%p pginfo=%p type=%x num_pages=%lx "
- "num_4k=%lx next_buf=%lx next_4k=%lx number=%x "
- "kpage=%p page_cnt=%lx page_4k_cnt=%lx i=%x "
+ ehca_gen_err("ret=%x e_mr=%p pginfo=%p type=%x num_kpages=%lx "
+ "num_hwpages=%lx next_buf=%lx next_hwpage=%lx number=%x "
+ "kpage=%p kpage_cnt=%lx hwpage_cnt=%lx i=%x "
"next_listelem=%lx region=%p next_chunk=%p "
"next_nmap=%lx", ret, e_mr, pginfo, pginfo->type,
- pginfo->num_pages, pginfo->num_4k,
- pginfo->next_buf, pginfo->next_4k, number, kpage,
- pginfo->page_cnt, pginfo->page_4k_cnt, i,
- pginfo->next_listelem, pginfo->region,
- pginfo->next_chunk, pginfo->next_nmap);
+ pginfo->num_kpages, pginfo->num_hwpages,
+ pginfo->u.phy.next_buf, pginfo->next_hwpage, number, kpage,
+ pginfo->kpage_cnt, pginfo->hwpage_cnt, i,
+ pginfo->u.fmr.next_listelem, pginfo->u.usr.region,
+ pginfo->u.usr.next_chunk, pginfo->u.usr.next_nmap);
return ret;
} /* end ehca_set_pagebuf() */
@@ -1860,101 +1869,101 @@ int ehca_set_pagebuf_1(struct ehca_mr *e_mr,
u64 *fmrlist;
struct ib_umem_chunk *chunk;
struct ib_umem_chunk *prev_chunk;
- u64 pgaddr, num4k, offs4k;
+ u64 pgaddr, num_hw, offs_hw;
if (pginfo->type == EHCA_MR_PGI_PHYS) {
/* sanity check */
- if ((pginfo->page_cnt >= pginfo->num_pages) ||
- (pginfo->page_4k_cnt >= pginfo->num_4k)) {
- ehca_gen_err("page_cnt >= num_pages, page_cnt=%lx "
- "num_pages=%lx page_4k_cnt=%lx num_4k=%lx",
- pginfo->page_cnt, pginfo->num_pages,
- pginfo->page_4k_cnt, pginfo->num_4k);
+ if ((pginfo->kpage_cnt >= pginfo->num_kpages) ||
+ (pginfo->hwpage_cnt >= pginfo->num_hwpages)) {
+ ehca_gen_err("kpage_cnt >= num_hwpages, kpage_cnt=%lx "
+ "num_hwpages=%lx hwpage_cnt=%lx num_hwpages=%lx",
+ pginfo->kpage_cnt, pginfo->num_kpages,
+ pginfo->hwpage_cnt, pginfo->num_hwpages);
ret = -EFAULT;
goto ehca_set_pagebuf_1_exit0;
}
- tmp_pbuf = pginfo->phys_buf_array + pginfo->next_buf;
- num4k = NUM_CHUNKS((tmp_pbuf->addr % EHCA_PAGESIZE) +
- tmp_pbuf->size, EHCA_PAGESIZE);
- offs4k = (tmp_pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
+ tmp_pbuf = pginfo->u.phy.phys_buf_array + pginfo->u.phy.next_buf;
+ num_hw = NUM_CHUNKS((tmp_pbuf->addr % EHCA_PAGESIZE) +
+ tmp_pbuf->size, EHCA_PAGESIZE);
+ offs_hw = (tmp_pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
*rpage = phys_to_abs((tmp_pbuf->addr & EHCA_PAGEMASK) +
- (pginfo->next_4k * EHCA_PAGESIZE));
+ (pginfo->next_hwpage * EHCA_PAGESIZE));
if ( !(*rpage) && tmp_pbuf->addr ) {
ehca_gen_err("tmp_pbuf->addr=%lx"
- " tmp_pbuf->size=%lx next_4k=%lx",
+ " tmp_pbuf->size=%lx next_hwpage=%lx",
tmp_pbuf->addr, tmp_pbuf->size,
- pginfo->next_4k);
+ pginfo->next_hwpage);
ret = -EFAULT;
goto ehca_set_pagebuf_1_exit0;
}
- (pginfo->page_4k_cnt)++;
- (pginfo->next_4k)++;
- if (pginfo->next_4k % (PAGE_SIZE / EHCA_PAGESIZE) == 0)
- (pginfo->page_cnt)++;
- if (pginfo->next_4k >= offs4k + num4k) {
- (pginfo->next_buf)++;
- pginfo->next_4k = 0;
+ (pginfo->hwpage_cnt)++;
+ (pginfo->next_hwpage)++;
+ if (pginfo->next_hwpage % (PAGE_SIZE / EHCA_PAGESIZE) == 0)
+ (pginfo->kpage_cnt)++;
+ if (pginfo->next_hwpage >= offs_hw + num_hw) {
+ (pginfo->u.phy.next_buf)++;
+ pginfo->next_hwpage = 0;
}
} else if (pginfo->type == EHCA_MR_PGI_USER) {
- chunk = pginfo->next_chunk;
- prev_chunk = pginfo->next_chunk;
+ chunk = pginfo->u.usr.next_chunk;
+ prev_chunk = pginfo->u.usr.next_chunk;
list_for_each_entry_continue(chunk,
- (&(pginfo->region->chunk_list)),
+ (&(pginfo->u.usr.region->chunk_list)),
list) {
pgaddr = ( page_to_pfn(chunk->page_list[
- pginfo->next_nmap].page)
+ pginfo->u.usr.next_nmap].page)
<< PAGE_SHIFT);
*rpage = phys_to_abs(pgaddr +
- (pginfo->next_4k * EHCA_PAGESIZE));
+ (pginfo->next_hwpage * EHCA_PAGESIZE));
if ( !(*rpage) ) {
ehca_gen_err("pgaddr=%lx chunk->page_list[]=%lx"
- " next_nmap=%lx next_4k=%lx mr=%p",
+ " next_nmap=%lx next_hwpage=%lx mr=%p",
pgaddr, (u64)sg_dma_address(
&chunk->page_list[
- pginfo->
+ pginfo->u.usr.
next_nmap]),
- pginfo->next_nmap, pginfo->next_4k,
+ pginfo->u.usr.next_nmap, pginfo->next_hwpage,
e_mr);
ret = -EFAULT;
goto ehca_set_pagebuf_1_exit0;
}
- (pginfo->page_4k_cnt)++;
- (pginfo->next_4k)++;
- if (pginfo->next_4k %
+ (pginfo->hwpage_cnt)++;
+ (pginfo->next_hwpage)++;
+ if (pginfo->next_hwpage %
(PAGE_SIZE / EHCA_PAGESIZE) == 0) {
- (pginfo->page_cnt)++;
- (pginfo->next_nmap)++;
- pginfo->next_4k = 0;
+ (pginfo->kpage_cnt)++;
+ (pginfo->u.usr.next_nmap)++;
+ pginfo->next_hwpage = 0;
}
- if (pginfo->next_nmap >= chunk->nmap) {
- pginfo->next_nmap = 0;
+ if (pginfo->u.usr.next_nmap >= chunk->nmap) {
+ pginfo->u.usr.next_nmap = 0;
prev_chunk = chunk;
}
break;
}
- pginfo->next_chunk =
+ pginfo->u.usr.next_chunk =
list_prepare_entry(prev_chunk,
- (&(pginfo->region->chunk_list)),
+ (&(pginfo->u.usr.region->chunk_list)),
list);
} else if (pginfo->type == EHCA_MR_PGI_FMR) {
- fmrlist = pginfo->page_list + pginfo->next_listelem;
+ fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem;
*rpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) +
- pginfo->next_4k * EHCA_PAGESIZE);
+ pginfo->next_hwpage * EHCA_PAGESIZE);
if ( !(*rpage) ) {
ehca_gen_err("*fmrlist=%lx fmrlist=%p "
- "next_listelem=%lx next_4k=%lx",
- *fmrlist, fmrlist, pginfo->next_listelem,
- pginfo->next_4k);
+ "next_listelem=%lx next_hwpage=%lx",
+ *fmrlist, fmrlist, pginfo->u.fmr.next_listelem,
+ pginfo->next_hwpage);
ret = -EFAULT;
goto ehca_set_pagebuf_1_exit0;
}
- (pginfo->page_4k_cnt)++;
- (pginfo->next_4k)++;
- if (pginfo->next_4k %
+ (pginfo->hwpage_cnt)++;
+ (pginfo->next_hwpage)++;
+ if (pginfo->next_hwpage %
(e_mr->fmr_page_size / EHCA_PAGESIZE) == 0) {
- (pginfo->page_cnt)++;
- (pginfo->next_listelem)++;
- pginfo->next_4k = 0;
+ (pginfo->kpage_cnt)++;
+ (pginfo->u.fmr.next_listelem)++;
+ pginfo->next_hwpage = 0;
}
} else {
ehca_gen_err("bad pginfo->type=%x", pginfo->type);
@@ -1964,15 +1973,15 @@ int ehca_set_pagebuf_1(struct ehca_mr *e_mr,
ehca_set_pagebuf_1_exit0:
if (ret)
- ehca_gen_err("ret=%x e_mr=%p pginfo=%p type=%x num_pages=%lx "
- "num_4k=%lx next_buf=%lx next_4k=%lx rpage=%p "
- "page_cnt=%lx page_4k_cnt=%lx next_listelem=%lx "
+ ehca_gen_err("ret=%x e_mr=%p pginfo=%p type=%x num_kpages=%lx "
+ "num_hwpages=%lx next_buf=%lx next_hwpage=%lx rpage=%p "
+ "kpage_cnt=%lx hwpage_cnt=%lx next_listelem=%lx "
"region=%p next_chunk=%p next_nmap=%lx", ret, e_mr,
- pginfo, pginfo->type, pginfo->num_pages,
- pginfo->num_4k, pginfo->next_buf, pginfo->next_4k,
- rpage, pginfo->page_cnt, pginfo->page_4k_cnt,
- pginfo->next_listelem, pginfo->region,
- pginfo->next_chunk, pginfo->next_nmap);
+ pginfo, pginfo->type, pginfo->num_kpages,
+ pginfo->num_hwpages, pginfo->u.phy.next_buf, pginfo->next_hwpage,
+ rpage, pginfo->kpage_cnt, pginfo->hwpage_cnt,
+ pginfo->u.fmr.next_listelem, pginfo->u.usr.region,
+ pginfo->u.usr.next_chunk, pginfo->u.usr.next_nmap);
return ret;
} /* end ehca_set_pagebuf_1() */
@@ -2053,19 +2062,17 @@ void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl,
*/
void ehca_mr_deletenew(struct ehca_mr *mr)
{
- mr->flags = 0;
- mr->num_pages = 0;
- mr->num_4k = 0;
- mr->acl = 0;
- mr->start = NULL;
+ mr->flags = 0;
+ mr->num_kpages = 0;
+ mr->num_hwpages = 0;
+ mr->acl = 0;
+ mr->start = NULL;
mr->fmr_page_size = 0;
mr->fmr_max_pages = 0;
- mr->fmr_max_maps = 0;
- mr->fmr_map_cnt = 0;
+ mr->fmr_max_maps = 0;
+ mr->fmr_map_cnt = 0;
memset(&mr->ipz_mr_handle, 0, sizeof(mr->ipz_mr_handle));
memset(&mr->galpas, 0, sizeof(mr->galpas));
- mr->nr_of_pages = 0;
- mr->pagearray = NULL;
} /* end ehca_mr_deletenew() */
int ehca_init_mrmw_cache(void)
--
1.5.2
^ permalink raw reply related
* [PATCH 06/10] IB/ehca: use macro to calculate number of chunks in a mem block
From: Joachim Fenkes @ 2007-07-12 15:51 UTC (permalink / raw)
To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier
Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200707121745.27592.fenkes@de.ibm.com>
From: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_mrmw.c | 47 ++++++++++++++++---------------
1 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index 1fe4f72..58e8b33 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -48,6 +48,8 @@
#include "hcp_if.h"
#include "hipz_hw.h"
+#define NUM_CHUNKS(length, chunk_size) \
+ (((length) + (chunk_size - 1)) / (chunk_size))
/* max number of rpages (per hcall register_rpages) */
#define MAX_RPAGES 512
@@ -195,10 +197,10 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
}
/* determine number of MR pages */
- num_pages_mr = ((((u64)iova_start % PAGE_SIZE) + size +
- PAGE_SIZE - 1) / PAGE_SIZE);
- num_pages_4k = ((((u64)iova_start % EHCA_PAGESIZE) + size +
- EHCA_PAGESIZE - 1) / EHCA_PAGESIZE);
+ num_pages_mr = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size,
+ PAGE_SIZE);
+ num_pages_4k = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE) + size,
+ EHCA_PAGESIZE);
/* register MR on HCA */
if (ehca_mr_is_maxmr(size, iova_start)) {
@@ -305,10 +307,9 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt
}
/* determine number of MR pages */
- num_pages_mr = (((virt % PAGE_SIZE) + length + PAGE_SIZE - 1) /
- PAGE_SIZE);
- num_pages_4k = (((virt % EHCA_PAGESIZE) + length + EHCA_PAGESIZE - 1) /
- EHCA_PAGESIZE);
+ num_pages_mr = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE);
+ num_pages_4k = NUM_CHUNKS((virt % EHCA_PAGESIZE) + length,
+ EHCA_PAGESIZE);
/* register MR on HCA */
pginfo.type = EHCA_MR_PGI_USER;
@@ -462,10 +463,10 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
ret = -EINVAL;
goto rereg_phys_mr_exit1;
}
- num_pages_mr = ((((u64)new_start % PAGE_SIZE) + new_size +
- PAGE_SIZE - 1) / PAGE_SIZE);
- num_pages_4k = ((((u64)new_start % EHCA_PAGESIZE) + new_size +
- EHCA_PAGESIZE - 1) / EHCA_PAGESIZE);
+ num_pages_mr = NUM_CHUNKS(((u64)new_start % PAGE_SIZE) +
+ new_size, PAGE_SIZE);
+ num_pages_4k = NUM_CHUNKS(((u64)new_start % EHCA_PAGESIZE) +
+ new_size, EHCA_PAGESIZE);
pginfo.type = EHCA_MR_PGI_PHYS;
pginfo.num_pages = num_pages_mr;
pginfo.num_4k = num_pages_4k;
@@ -1030,9 +1031,9 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
}
/* max 512 pages per shot */
- for (i = 0; i < ((pginfo->num_4k + MAX_RPAGES - 1) / MAX_RPAGES); i++) {
+ for (i = 0; i < NUM_CHUNKS(pginfo->num_4k, MAX_RPAGES); i++) {
- if (i == ((pginfo->num_4k + MAX_RPAGES - 1) / MAX_RPAGES) - 1) {
+ if (i == NUM_CHUNKS(pginfo->num_4k, MAX_RPAGES) - 1) {
rnum = pginfo->num_4k % MAX_RPAGES; /* last shot */
if (rnum == 0)
rnum = MAX_RPAGES; /* last shot is full */
@@ -1069,7 +1070,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
0, /* pagesize 4k */
0, rpage, rnum);
- if (i == ((pginfo->num_4k + MAX_RPAGES - 1) / MAX_RPAGES) - 1) {
+ if (i == NUM_CHUNKS(pginfo->num_4k, MAX_RPAGES) - 1) {
/*
* check for 'registration complete'==H_SUCCESS
* and for 'page registered'==H_PAGE_REGISTERED
@@ -1475,10 +1476,10 @@ int ehca_reg_internal_maxmr(
iova_start = (u64*)KERNELBASE;
ib_pbuf.addr = 0;
ib_pbuf.size = size_maxmr;
- num_pages_mr = ((((u64)iova_start % PAGE_SIZE) + size_maxmr +
- PAGE_SIZE - 1) / PAGE_SIZE);
- num_pages_4k = ((((u64)iova_start % EHCA_PAGESIZE) + size_maxmr +
- EHCA_PAGESIZE - 1) / EHCA_PAGESIZE);
+ num_pages_mr = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr,
+ PAGE_SIZE);
+ num_pages_4k = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE)
+ + size_maxmr, EHCA_PAGESIZE);
pginfo.type = EHCA_MR_PGI_PHYS;
pginfo.num_pages = num_pages_mr;
@@ -1700,8 +1701,8 @@ int ehca_set_pagebuf(struct ehca_mr *e_mr,
/* loop over desired phys_buf_array entries */
while (i < number) {
pbuf = pginfo->phys_buf_array + pginfo->next_buf;
- num4k = ((pbuf->addr % EHCA_PAGESIZE) + pbuf->size +
- EHCA_PAGESIZE - 1) / EHCA_PAGESIZE;
+ num4k = NUM_CHUNKS((pbuf->addr % EHCA_PAGESIZE)
+ + pbuf->size, EHCA_PAGESIZE);
offs4k = (pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
while (pginfo->next_4k < offs4k + num4k) {
/* sanity check */
@@ -1873,8 +1874,8 @@ int ehca_set_pagebuf_1(struct ehca_mr *e_mr,
goto ehca_set_pagebuf_1_exit0;
}
tmp_pbuf = pginfo->phys_buf_array + pginfo->next_buf;
- num4k = ((tmp_pbuf->addr % EHCA_PAGESIZE) + tmp_pbuf->size +
- EHCA_PAGESIZE - 1) / EHCA_PAGESIZE;
+ num4k = NUM_CHUNKS((tmp_pbuf->addr % EHCA_PAGESIZE) +
+ tmp_pbuf->size, EHCA_PAGESIZE);
offs4k = (tmp_pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
*rpage = phys_to_abs((tmp_pbuf->addr & EHCA_PAGEMASK) +
(pginfo->next_4k * EHCA_PAGESIZE));
--
1.5.2
^ permalink raw reply related
* [PATCH 05/10] IB/ehca: use #define for "pages per register_rpage" instead of hardcoded value
From: Joachim Fenkes @ 2007-07-12 15:51 UTC (permalink / raw)
To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier
Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200707121745.27592.fenkes@de.ibm.com>
From: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_mrmw.c | 19 +++++++++++--------
1 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index 7c1656a..1fe4f72 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -48,6 +48,9 @@
#include "hcp_if.h"
#include "hipz_hw.h"
+/* max number of rpages (per hcall register_rpages) */
+#define MAX_RPAGES 512
+
static struct kmem_cache *mr_cache;
static struct kmem_cache *mw_cache;
@@ -1027,14 +1030,14 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
}
/* max 512 pages per shot */
- for (i = 0; i < ((pginfo->num_4k + 512 - 1) / 512); i++) {
+ for (i = 0; i < ((pginfo->num_4k + MAX_RPAGES - 1) / MAX_RPAGES); i++) {
- if (i == ((pginfo->num_4k + 512 - 1) / 512) - 1) {
- rnum = pginfo->num_4k % 512; /* last shot */
+ if (i == ((pginfo->num_4k + MAX_RPAGES - 1) / MAX_RPAGES) - 1) {
+ rnum = pginfo->num_4k % MAX_RPAGES; /* last shot */
if (rnum == 0)
- rnum = 512; /* last shot is full */
+ rnum = MAX_RPAGES; /* last shot is full */
} else
- rnum = 512;
+ rnum = MAX_RPAGES;
if (rnum > 1) {
ret = ehca_set_pagebuf(e_mr, pginfo, rnum, kpage);
@@ -1066,7 +1069,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
0, /* pagesize 4k */
0, rpage, rnum);
- if (i == ((pginfo->num_4k + 512 - 1) / 512) - 1) {
+ if (i == ((pginfo->num_4k + MAX_RPAGES - 1) / MAX_RPAGES) - 1) {
/*
* check for 'registration complete'==H_SUCCESS
* and for 'page registered'==H_PAGE_REGISTERED
@@ -1215,7 +1218,7 @@ int ehca_rereg_mr(struct ehca_shca *shca,
int rereg_3_hcall = 0; /* 1: use 3 hipz calls for reregistration */
/* first determine reregistration hCall(s) */
- if ((pginfo->num_4k > 512) || (e_mr->num_4k > 512) ||
+ if ((pginfo->num_4k > MAX_RPAGES) || (e_mr->num_4k > MAX_RPAGES) ||
(pginfo->num_4k > e_mr->num_4k)) {
ehca_dbg(&shca->ib_device, "Rereg3 case, pginfo->num_4k=%lx "
"e_mr->num_4k=%x", pginfo->num_4k, e_mr->num_4k);
@@ -1306,7 +1309,7 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca,
struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0};
/* first check if reregistration hCall can be used for unmap */
- if (e_fmr->fmr_max_pages > 512) {
+ if (e_fmr->fmr_max_pages > MAX_RPAGES) {
rereg_1_hcall = 0;
rereg_3_hcall = 1;
}
--
1.5.2
^ permalink raw reply related
* Re: Tickless Hz/hrtimers/etc. on PowerPC
From: Michael Neuling @ 2007-07-12 15:49 UTC (permalink / raw)
To: Matt Sealey; +Cc: ppc-dev
In-Reply-To: <46955674.9090304@genesi-usa.com>
> Okay.
>
> What I didn't want to do is spend a day sifting some other development
> tree picking out what I think might be possibly sort of the right patches
> for it.
>
> I'd get it wrong because having not worked on it, I don't know what I am
> even looking for.
>
> And I don't want to run -rt or wireless-dev for the benefit of a single
> feature. What I am after is something like Ingo Molnar throws out..
> single patches done the old way, not git trees. It's so much easier to
> handle and integrate for example into a Gentoo ebuild or to make a
> tarball of accumulated patches from a certain release kernel.
I'm sooo with ya. I like my patches alphabetised, but no one ever does
it for me.
:-)
Mikey
^ permalink raw reply
* [PATCH 04/10] IB/ehca: use common error code mapping instead of specific ones
From: Joachim Fenkes @ 2007-07-12 15:49 UTC (permalink / raw)
To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier
Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200707121745.27592.fenkes@de.ibm.com>
From: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Instead of one error mapping function for each potential error source in
ehca_mrmw.c, use a centralized function that handles all cases, saving a
three-figure line count.
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_mrmw.c | 195 ++-----------------------------
drivers/infiniband/hw/ehca/ehca_mrmw.h | 14 ---
drivers/infiniband/hw/ehca/ehca_tools.h | 3 +
3 files changed, 15 insertions(+), 197 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index 98f2531..7c1656a 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -537,7 +537,7 @@ int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
"hca_hndl=%lx mr_hndl=%lx lkey=%x",
h_ret, mr, shca->ipz_hca_handle.handle,
e_mr->ipz_mr_handle.handle, mr->lkey);
- ret = ehca_mrmw_map_hrc_query_mr(h_ret);
+ ret = ehca2ib_return_code(h_ret);
goto query_mr_exit1;
}
mr_attr->pd = mr->pd;
@@ -597,7 +597,7 @@ int ehca_dereg_mr(struct ib_mr *mr)
"e_mr=%p hca_hndl=%lx mr_hndl=%lx mr->lkey=%x",
h_ret, shca, e_mr, shca->ipz_hca_handle.handle,
e_mr->ipz_mr_handle.handle, mr->lkey);
- ret = ehca_mrmw_map_hrc_free_mr(h_ret);
+ ret = ehca2ib_return_code(h_ret);
goto dereg_mr_exit0;
}
@@ -637,7 +637,7 @@ struct ib_mw *ehca_alloc_mw(struct ib_pd *pd)
ehca_err(pd->device, "hipz_mw_allocate failed, h_ret=%lx "
"shca=%p hca_hndl=%lx mw=%p",
h_ret, shca, shca->ipz_hca_handle.handle, e_mw);
- ib_mw = ERR_PTR(ehca_mrmw_map_hrc_alloc(h_ret));
+ ib_mw = ERR_PTR(ehca2ib_return_code(h_ret));
goto alloc_mw_exit1;
}
/* successful MW allocation */
@@ -680,7 +680,7 @@ int ehca_dealloc_mw(struct ib_mw *mw)
"mw=%p rkey=%x hca_hndl=%lx mw_hndl=%lx",
h_ret, shca, mw, mw->rkey, shca->ipz_hca_handle.handle,
e_mw->ipz_mw_handle.handle);
- return ehca_mrmw_map_hrc_free_mw(h_ret);
+ return ehca2ib_return_code(h_ret);
}
/* successful deallocation */
ehca_mw_delete(e_mw);
@@ -923,7 +923,7 @@ int ehca_dealloc_fmr(struct ib_fmr *fmr)
"hca_hndl=%lx fmr_hndl=%lx fmr->lkey=%x",
h_ret, e_fmr, shca->ipz_hca_handle.handle,
e_fmr->ipz_mr_handle.handle, fmr->lkey);
- ret = ehca_mrmw_map_hrc_free_mr(h_ret);
+ ret = ehca2ib_return_code(h_ret);
goto free_fmr_exit0;
}
/* successful deregistration */
@@ -964,7 +964,7 @@ int ehca_reg_mr(struct ehca_shca *shca,
if (h_ret != H_SUCCESS) {
ehca_err(&shca->ib_device, "hipz_alloc_mr failed, h_ret=%lx "
"hca_hndl=%lx", h_ret, shca->ipz_hca_handle.handle);
- ret = ehca_mrmw_map_hrc_alloc(h_ret);
+ ret = ehca2ib_return_code(h_ret);
goto ehca_reg_mr_exit0;
}
@@ -1079,7 +1079,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
shca->ipz_hca_handle.handle,
e_mr->ipz_mr_handle.handle,
e_mr->ib.ib_mr.lkey);
- ret = ehca_mrmw_map_hrc_rrpg_last(h_ret);
+ ret = ehca2ib_return_code(h_ret);
break;
} else
ret = 0;
@@ -1090,7 +1090,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
e_mr->ib.ib_mr.lkey,
shca->ipz_hca_handle.handle,
e_mr->ipz_mr_handle.handle);
- ret = ehca_mrmw_map_hrc_rrpg_notlast(h_ret);
+ ret = ehca2ib_return_code(h_ret);
break;
} else
ret = 0;
@@ -1254,7 +1254,7 @@ int ehca_rereg_mr(struct ehca_shca *shca,
h_ret, e_mr, shca->ipz_hca_handle.handle,
e_mr->ipz_mr_handle.handle,
e_mr->ib.ib_mr.lkey);
- ret = ehca_mrmw_map_hrc_free_mr(h_ret);
+ ret = ehca2ib_return_code(h_ret);
goto ehca_rereg_mr_exit0;
}
/* clean ehca_mr_t, without changing struct ib_mr and lock */
@@ -1351,7 +1351,7 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca,
h_ret, e_fmr, shca->ipz_hca_handle.handle,
e_fmr->ipz_mr_handle.handle,
e_fmr->ib.ib_fmr.lkey);
- ret = ehca_mrmw_map_hrc_free_mr(h_ret);
+ ret = ehca2ib_return_code(h_ret);
goto ehca_unmap_one_fmr_exit0;
}
/* clean ehca_mr_t, without changing lock */
@@ -1420,7 +1420,7 @@ int ehca_reg_smr(struct ehca_shca *shca,
shca->ipz_hca_handle.handle,
e_origmr->ipz_mr_handle.handle,
e_origmr->ib.ib_mr.lkey);
- ret = ehca_mrmw_map_hrc_reg_smr(h_ret);
+ ret = ehca2ib_return_code(h_ret);
goto ehca_reg_smr_exit0;
}
/* successful registration */
@@ -1539,7 +1539,7 @@ int ehca_reg_maxmr(struct ehca_shca *shca,
h_ret, e_origmr, shca->ipz_hca_handle.handle,
e_origmr->ipz_mr_handle.handle,
e_origmr->ib.ib_mr.lkey);
- return ehca_mrmw_map_hrc_reg_smr(h_ret);
+ return ehca2ib_return_code(h_ret);
}
/* successful registration */
e_newmr->num_pages = e_origmr->num_pages;
@@ -2043,177 +2043,6 @@ void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl,
/*----------------------------------------------------------------------*/
/*
- * map HIPZ rc to IB retcodes for MR/MW allocations
- * Used for hipz_mr_reg_alloc and hipz_mw_alloc.
- */
-int ehca_mrmw_map_hrc_alloc(const u64 hipz_rc)
-{
- switch (hipz_rc) {
- case H_SUCCESS: /* successful completion */
- return 0;
- case H_NOT_ENOUGH_RESOURCES: /* insufficient resources */
- case H_CONSTRAINED: /* resource constraint */
- case H_NO_MEM:
- return -ENOMEM;
- case H_BUSY: /* long busy */
- return -EBUSY;
- default:
- return -EINVAL;
- }
-} /* end ehca_mrmw_map_hrc_alloc() */
-
-/*----------------------------------------------------------------------*/
-
-/*
- * map HIPZ rc to IB retcodes for MR register rpage
- * Used for hipz_h_register_rpage_mr at registering last page
- */
-int ehca_mrmw_map_hrc_rrpg_last(const u64 hipz_rc)
-{
- switch (hipz_rc) {
- case H_SUCCESS: /* registration complete */
- return 0;
- case H_PAGE_REGISTERED: /* page registered */
- case H_ADAPTER_PARM: /* invalid adapter handle */
- case H_RH_PARM: /* invalid resource handle */
-/* case H_QT_PARM: invalid queue type */
- case H_PARAMETER: /*
- * invalid logical address,
- * or count zero or greater 512
- */
- case H_TABLE_FULL: /* page table full */
- case H_HARDWARE: /* HCA not operational */
- return -EINVAL;
- case H_BUSY: /* long busy */
- return -EBUSY;
- default:
- return -EINVAL;
- }
-} /* end ehca_mrmw_map_hrc_rrpg_last() */
-
-/*----------------------------------------------------------------------*/
-
-/*
- * map HIPZ rc to IB retcodes for MR register rpage
- * Used for hipz_h_register_rpage_mr at registering one page, but not last page
- */
-int ehca_mrmw_map_hrc_rrpg_notlast(const u64 hipz_rc)
-{
- switch (hipz_rc) {
- case H_PAGE_REGISTERED: /* page registered */
- return 0;
- case H_SUCCESS: /* registration complete */
- case H_ADAPTER_PARM: /* invalid adapter handle */
- case H_RH_PARM: /* invalid resource handle */
-/* case H_QT_PARM: invalid queue type */
- case H_PARAMETER: /*
- * invalid logical address,
- * or count zero or greater 512
- */
- case H_TABLE_FULL: /* page table full */
- case H_HARDWARE: /* HCA not operational */
- return -EINVAL;
- case H_BUSY: /* long busy */
- return -EBUSY;
- default:
- return -EINVAL;
- }
-} /* end ehca_mrmw_map_hrc_rrpg_notlast() */
-
-/*----------------------------------------------------------------------*/
-
-/* map HIPZ rc to IB retcodes for MR query. Used for hipz_mr_query. */
-int ehca_mrmw_map_hrc_query_mr(const u64 hipz_rc)
-{
- switch (hipz_rc) {
- case H_SUCCESS: /* successful completion */
- return 0;
- case H_ADAPTER_PARM: /* invalid adapter handle */
- case H_RH_PARM: /* invalid resource handle */
- return -EINVAL;
- case H_BUSY: /* long busy */
- return -EBUSY;
- default:
- return -EINVAL;
- }
-} /* end ehca_mrmw_map_hrc_query_mr() */
-
-/*----------------------------------------------------------------------*/
-/*----------------------------------------------------------------------*/
-
-/*
- * map HIPZ rc to IB retcodes for freeing MR resource
- * Used for hipz_h_free_resource_mr
- */
-int ehca_mrmw_map_hrc_free_mr(const u64 hipz_rc)
-{
- switch (hipz_rc) {
- case H_SUCCESS: /* resource freed */
- return 0;
- case H_ADAPTER_PARM: /* invalid adapter handle */
- case H_RH_PARM: /* invalid resource handle */
- case H_R_STATE: /* invalid resource state */
- case H_HARDWARE: /* HCA not operational */
- return -EINVAL;
- case H_RESOURCE: /* Resource in use */
- case H_BUSY: /* long busy */
- return -EBUSY;
- default:
- return -EINVAL;
- }
-} /* end ehca_mrmw_map_hrc_free_mr() */
-
-/*----------------------------------------------------------------------*/
-
-/*
- * map HIPZ rc to IB retcodes for freeing MW resource
- * Used for hipz_h_free_resource_mw
- */
-int ehca_mrmw_map_hrc_free_mw(const u64 hipz_rc)
-{
- switch (hipz_rc) {
- case H_SUCCESS: /* resource freed */
- return 0;
- case H_ADAPTER_PARM: /* invalid adapter handle */
- case H_RH_PARM: /* invalid resource handle */
- case H_R_STATE: /* invalid resource state */
- case H_HARDWARE: /* HCA not operational */
- return -EINVAL;
- case H_RESOURCE: /* Resource in use */
- case H_BUSY: /* long busy */
- return -EBUSY;
- default:
- return -EINVAL;
- }
-} /* end ehca_mrmw_map_hrc_free_mw() */
-
-/*----------------------------------------------------------------------*/
-
-/*
- * map HIPZ rc to IB retcodes for SMR registrations
- * Used for hipz_h_register_smr.
- */
-int ehca_mrmw_map_hrc_reg_smr(const u64 hipz_rc)
-{
- switch (hipz_rc) {
- case H_SUCCESS: /* successful completion */
- return 0;
- case H_ADAPTER_PARM: /* invalid adapter handle */
- case H_RH_PARM: /* invalid resource handle */
- case H_MEM_PARM: /* invalid MR virtual address */
- case H_MEM_ACCESS_PARM: /* invalid access controls */
- case H_NOT_ENOUGH_RESOURCES: /* insufficient resources */
- return -EINVAL;
- case H_BUSY: /* long busy */
- return -EBUSY;
- default:
- return -EINVAL;
- }
-} /* end ehca_mrmw_map_hrc_reg_smr() */
-
-/*----------------------------------------------------------------------*/
-
-/*
* MR destructor and constructor
* used in Reregister MR verb, sets all fields in ehca_mr_t to 0,
* except struct ib_mr and spinlock
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.h b/drivers/infiniband/hw/ehca/ehca_mrmw.h
index d936e40..fb69ede 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.h
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.h
@@ -121,20 +121,6 @@ void ehca_mrmw_set_pgsize_hipz_acl(u32 *hipz_acl);
void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl,
int *ib_acl);
-int ehca_mrmw_map_hrc_alloc(const u64 hipz_rc);
-
-int ehca_mrmw_map_hrc_rrpg_last(const u64 hipz_rc);
-
-int ehca_mrmw_map_hrc_rrpg_notlast(const u64 hipz_rc);
-
-int ehca_mrmw_map_hrc_query_mr(const u64 hipz_rc);
-
-int ehca_mrmw_map_hrc_free_mr(const u64 hipz_rc);
-
-int ehca_mrmw_map_hrc_free_mw(const u64 hipz_rc);
-
-int ehca_mrmw_map_hrc_reg_smr(const u64 hipz_rc);
-
void ehca_mr_deletenew(struct ehca_mr *mr);
#endif /*_EHCA_MRMW_H_*/
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h
index 03b185f..fd8238b 100644
--- a/drivers/infiniband/hw/ehca/ehca_tools.h
+++ b/drivers/infiniband/hw/ehca/ehca_tools.h
@@ -161,8 +161,11 @@ static inline int ehca2ib_return_code(u64 ehca_rc)
switch (ehca_rc) {
case H_SUCCESS:
return 0;
+ case H_RESOURCE: /* Resource in use */
case H_BUSY:
return -EBUSY;
+ case H_NOT_ENOUGH_RESOURCES: /* insufficient resources */
+ case H_CONSTRAINED: /* resource constraint */
case H_NO_MEM:
return -ENOMEM;
default:
--
1.5.2
^ permalink raw reply related
* [PATCH 02/10] IB/ehca: Fix HW level autodetection
From: Joachim Fenkes @ 2007-07-12 15:47 UTC (permalink / raw)
To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier
Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200707121745.27592.fenkes@de.ibm.com>
Autodetection was missing a few HW revisions, causing certain eHCA1
revisions to be treated like eHCA2. Fixed.
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_main.c | 29 +++++++++++++++++------------
1 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index d9a37dc..57c551e 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -282,22 +282,27 @@ int ehca_sense_attributes(struct ehca_shca *shca)
ehca_gen_dbg(" ... hardware version=%x:%x", hcaaver, revid);
- if ((hcaaver == 1) && (revid == 0))
- shca->hw_level = 0x11;
- else if ((hcaaver == 1) && (revid == 1))
- shca->hw_level = 0x12;
- else if ((hcaaver == 1) && (revid == 2))
- shca->hw_level = 0x13;
- else if ((hcaaver == 2) && (revid == 0))
- shca->hw_level = 0x21;
- else if ((hcaaver == 2) && (revid == 0x10))
- shca->hw_level = 0x22;
- else {
+ if (hcaaver == 1) {
+ if (revid <= 3)
+ shca->hw_level = 0x10 | (revid + 1);
+ else
+ shca->hw_level = 0x14;
+ } else if (hcaaver == 2) {
+ if (revid == 0)
+ shca->hw_level = 0x21;
+ else if (revid == 0x10)
+ shca->hw_level = 0x22;
+ else if (revid == 0x20 || revid == 0x21)
+ shca->hw_level = 0x23;
+ }
+
+ if (!shca->hw_level) {
ehca_gen_warn("unknown hardware version"
" - assuming default level");
shca->hw_level = 0x22;
}
- }
+ } else
+ shca->hw_level = ehca_hw_level;
ehca_gen_dbg(" ... hardware level=%x", shca->hw_level);
shca->sport[0].rate = IB_RATE_30_GBPS;
--
1.5.2
^ permalink raw reply related
* [PATCH 03/10] IB/ehca: fix memory leak in error path of ehca_get_dma_mr()
From: Joachim Fenkes @ 2007-07-12 15:48 UTC (permalink / raw)
To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier
Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200707121745.27592.fenkes@de.ibm.com>
From: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_mrmw.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index add79bd..98f2531 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -111,6 +111,7 @@ struct ib_mr *ehca_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
&e_maxmr->ib.ib_mr.lkey,
&e_maxmr->ib.ib_mr.rkey);
if (ret) {
+ ehca_mr_delete(e_maxmr);
ib_mr = ERR_PTR(ret);
goto get_dma_mr_exit0;
}
--
1.5.2
^ permalink raw reply related
* [PATCH 01/10] IB/ehca: Support for multiple event queues
From: Joachim Fenkes @ 2007-07-12 15:46 UTC (permalink / raw)
To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier
Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200707121745.27592.fenkes@de.ibm.com>
From: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
The eHCA driver can now handle multiple event queues (read: interrupt
sources) instead of one. The number of available EQs is selected via the
nr_eqs module parameter.
CQs are either assigned to the EQs based on the comp_vector index or, if the
dist_eqs module parameter is supplied, using a round-robin scheme.
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_classes.h | 13 +++-
drivers/infiniband/hw/ehca/ehca_cq.c | 16 +++-
drivers/infiniband/hw/ehca/ehca_eq.c | 139 ++++++++++++++++++-----------
drivers/infiniband/hw/ehca/ehca_irq.c | 36 +++-----
drivers/infiniband/hw/ehca/ehca_irq.h | 8 +-
drivers/infiniband/hw/ehca/ehca_iverbs.h | 9 +-
drivers/infiniband/hw/ehca/ehca_main.c | 118 ++++++++++++++++++++-----
drivers/infiniband/hw/ehca/ehca_qp.c | 2 +-
8 files changed, 233 insertions(+), 108 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index daf823e..b2d614a 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -72,7 +72,11 @@ struct ehca_eqe_cache_entry {
struct ehca_cq *cq;
};
+struct ehca_shca;
+
struct ehca_eq {
+ struct ehca_shca *shca;
+ char name[17];
u32 length;
struct ipz_queue ipz_queue;
struct ipz_eq_handle ipz_eq_handle;
@@ -100,6 +104,7 @@ struct ehca_sport {
struct ehca_sma_attr saved_attr;
};
+#define EHCA_MAX_NR_EQS 512
struct ehca_shca {
struct ib_device ib_device;
struct ibmebus_dev *ibmebus_dev;
@@ -108,14 +113,16 @@ struct ehca_shca {
struct list_head shca_list;
struct ipz_adapter_handle ipz_hca_handle;
struct ehca_sport sport[2];
- struct ehca_eq eq;
- struct ehca_eq neq;
+ struct ehca_eq **eqs;
+ struct ehca_eq *aeq; /* async event for qps */
+ struct ehca_eq *neq;
struct ehca_mr *maxmr;
struct ehca_pd *pd;
struct h_galpas galpas;
struct mutex modify_mutex;
u64 hca_cap;
int max_mtu;
+ atomic_t cur_eq_idx;
};
struct ehca_pd {
@@ -290,6 +297,8 @@ struct ehca_ucontext {
int ehca_init_pd_cache(void);
void ehca_cleanup_pd_cache(void);
+int ehca_init_eq_cache(void);
+void ehca_cleanup_eq_cache(void);
int ehca_init_cq_cache(void);
void ehca_cleanup_cq_cache(void);
int ehca_init_qp_cache(void);
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 01d4a14..97da51e 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -117,6 +117,8 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
struct ib_ucontext *context,
struct ib_udata *udata)
{
+ extern int ehca_nr_eqs;
+ extern int ehca_dist_eqs;
static const u32 additional_cqe = 20;
struct ib_cq *cq;
struct ehca_cq *my_cq;
@@ -134,6 +136,12 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
if (cqe >= 0xFFFFFFFF - 64 - additional_cqe)
return ERR_PTR(-EINVAL);
+ if (comp_vector < 0 || comp_vector >= ehca_nr_eqs) {
+ ehca_err(device, "Invalid comp_vector=%x ehca_nr_eqs=%x",
+ comp_vector, ehca_nr_eqs);
+ return ERR_PTR(-EINVAL);
+ }
+
my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL);
if (!my_cq) {
ehca_err(device, "Out of memory for ehca_cq struct device=%p",
@@ -153,7 +161,13 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
cq = &my_cq->ib_cq;
adapter_handle = shca->ipz_hca_handle;
- param.eq_handle = shca->eq.ipz_eq_handle;
+ if (!ehca_dist_eqs)
+ param.eq_handle = shca->eqs[comp_vector]->ipz_eq_handle;
+ else {
+ u32 eq_idx = atomic_inc_return(&shca->cur_eq_idx) % ehca_nr_eqs;
+ param.eq_handle = shca->eqs[eq_idx]->ipz_eq_handle;
+ ehca_dbg(device, "assigned comp_vector=%x", eq_idx);
+ }
do {
if (!idr_pre_get(&ehca_cq_idr, GFP_KERNEL)) {
diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c
index 4961eb8..d443bcb 100644
--- a/drivers/infiniband/hw/ehca/ehca_eq.c
+++ b/drivers/infiniband/hw/ehca/ehca_eq.c
@@ -8,6 +8,7 @@
* Reinhard Ernst <rernst@de.ibm.com>
* Heiko J Schick <schickhj@de.ibm.com>
* Hoang-Nam Nguyen <hnguyen@de.ibm.com>
+ * Joachim Fenkes <fenkes@de.ibm.com>
*
*
* Copyright (c) 2005 IBM Corporation
@@ -50,40 +51,54 @@
#include "hcp_if.h"
#include "ipz_pt_fn.h"
-int ehca_create_eq(struct ehca_shca *shca,
- struct ehca_eq *eq,
- const enum ehca_eq_type type, const u32 length)
+static struct kmem_cache *eq_cache;
+
+struct ehca_eq *ehca_create_eq(struct ehca_shca *shca,
+ const enum ehca_eq_type type, const u32 length)
{
- u64 ret;
+ struct ehca_eq *eq = NULL;
+ int ret;
+ u64 h_ret;
u32 nr_pages;
u32 i;
void *vpage;
struct ib_device *ib_dev = &shca->ib_device;
- spin_lock_init(&eq->spinlock);
- spin_lock_init(&eq->irq_spinlock);
- eq->is_initialized = 0;
+ if (!length) {
+ ehca_err(ib_dev, "EQ length must not be zero.");
+ return ERR_PTR(-EINVAL);
+ }
if (type != EHCA_EQ && type != EHCA_NEQ) {
- ehca_err(ib_dev, "Invalid EQ type %x. eq=%p", type, eq);
- return -EINVAL;
+ ehca_err(ib_dev, "Invalid EQ type %x", type);
+ return ERR_PTR(-EINVAL);
}
- if (!length) {
- ehca_err(ib_dev, "EQ length must not be zero. eq=%p", eq);
- return -EINVAL;
+
+ eq = kmem_cache_zalloc(eq_cache, GFP_KERNEL);
+ if (!eq) {
+ ehca_err(ib_dev, "Out of memory for ehca_eq struct device=%p",
+ ib_dev);
+ return ERR_PTR(-ENOMEM);
}
- ret = hipz_h_alloc_resource_eq(shca->ipz_hca_handle,
- &eq->pf,
- type,
- length,
- &eq->ipz_eq_handle,
- &eq->length,
- &nr_pages, &eq->ist);
+ spin_lock_init(&eq->spinlock);
+ spin_lock_init(&eq->irq_spinlock);
+ eq->is_initialized = 0;
+ eq->shca = shca;
- if (ret != H_SUCCESS) {
- ehca_err(ib_dev, "Can't allocate EQ/NEQ. eq=%p", eq);
- return -EINVAL;
+ h_ret = hipz_h_alloc_resource_eq(shca->ipz_hca_handle,
+ &eq->pf,
+ type,
+ length,
+ &eq->ipz_eq_handle,
+ &eq->length,
+ &nr_pages, &eq->ist);
+
+ if (h_ret != H_SUCCESS) {
+ ehca_err(ib_dev, "Can't allocate EQ/NEQ. eq=%p h_ret=%lx",
+ eq, h_ret);
+ ret = -EINVAL;
+ goto create_eq_exit0;
}
ret = ipz_queue_ctor(&eq->ipz_queue, nr_pages,
@@ -97,51 +112,51 @@ int ehca_create_eq(struct ehca_shca *shca,
u64 rpage;
if (!(vpage = ipz_qpageit_get_inc(&eq->ipz_queue))) {
- ret = H_RESOURCE;
+ ret = -ENOMEM;
goto create_eq_exit2;
}
rpage = virt_to_abs(vpage);
- ret = hipz_h_register_rpage_eq(shca->ipz_hca_handle,
- eq->ipz_eq_handle,
- &eq->pf,
- 0, 0, rpage, 1);
+ h_ret = hipz_h_register_rpage_eq(shca->ipz_hca_handle,
+ eq->ipz_eq_handle,
+ &eq->pf,
+ 0, 0, rpage, 1);
if (i == (nr_pages - 1)) {
/* last page */
vpage = ipz_qpageit_get_inc(&eq->ipz_queue);
- if (ret != H_SUCCESS || vpage)
+ if (h_ret != H_SUCCESS || vpage) {
+ ret = -ENOMEM;
goto create_eq_exit2;
+ }
} else {
- if (ret != H_PAGE_REGISTERED || !vpage)
+ if (h_ret != H_PAGE_REGISTERED || !vpage) {
+ ret = -ENOMEM;
goto create_eq_exit2;
+ }
}
}
ipz_qeit_reset(&eq->ipz_queue);
/* register interrupt handlers and initialize work queues */
- if (type == EHCA_EQ) {
- ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_eq,
- IRQF_DISABLED, "ehca_eq",
- (void *)shca);
- if (ret < 0)
- ehca_err(ib_dev, "Can't map interrupt handler.");
-
- tasklet_init(&eq->interrupt_task, ehca_tasklet_eq, (long)shca);
- } else if (type == EHCA_NEQ) {
- ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_neq,
- IRQF_DISABLED, "ehca_neq",
- (void *)shca);
- if (ret < 0)
- ehca_err(ib_dev, "Can't map interrupt handler.");
-
- tasklet_init(&eq->interrupt_task, ehca_tasklet_neq, (long)shca);
- }
+ if (type == EHCA_EQ)
+ snprintf(eq->name, sizeof(eq->name), "ehca_eq_%x", eq->ist);
+ else
+ snprintf(eq->name, sizeof(eq->name), "ehca_neq");
+
+ ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt,
+ IRQF_DISABLED, eq->name, (void *)eq);
+ if (ret < 0)
+ ehca_err(ib_dev, "Can't map interrupt handler.");
+
+ tasklet_init(&eq->interrupt_task,
+ (type == EHCA_EQ) ? ehca_tasklet_eq : ehca_tasklet_neq,
+ (long)eq);
eq->is_initialized = 1;
- return 0;
+ return eq;
create_eq_exit2:
ipz_queue_dtor(&eq->ipz_queue);
@@ -149,10 +164,13 @@ create_eq_exit2:
create_eq_exit1:
hipz_h_destroy_eq(shca->ipz_hca_handle, eq);
- return -EINVAL;
+create_eq_exit0:
+ kmem_cache_free(eq_cache, eq);
+
+ return ERR_PTR(ret);
}
-void *ehca_poll_eq(struct ehca_shca *shca, struct ehca_eq *eq)
+void *ehca_poll_eq(struct ehca_eq *eq)
{
unsigned long flags;
void *eqe;
@@ -164,13 +182,14 @@ void *ehca_poll_eq(struct ehca_shca *shca, struct ehca_eq *eq)
return eqe;
}
-int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq)
+int ehca_destroy_eq(struct ehca_eq *eq)
{
+ struct ehca_shca *shca = eq->shca;
unsigned long flags;
u64 h_ret;
spin_lock_irqsave(&eq->spinlock, flags);
- ibmebus_free_irq(NULL, eq->ist, (void *)shca);
+ ibmebus_free_irq(NULL, eq->ist, (void *)eq);
h_ret = hipz_h_destroy_eq(shca->ipz_hca_handle, eq);
@@ -181,6 +200,24 @@ int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq)
return -EINVAL;
}
ipz_queue_dtor(&eq->ipz_queue);
+ kmem_cache_free(eq_cache, eq);
return 0;
}
+
+int ehca_init_eq_cache(void)
+{
+ eq_cache = kmem_cache_create("ehca_cache_eq",
+ sizeof(struct ehca_eq), 0,
+ SLAB_HWCACHE_ALIGN,
+ NULL, NULL);
+ if (!eq_cache)
+ return -ENOMEM;
+ return 0;
+}
+
+void ehca_cleanup_eq_cache(void)
+{
+ if (eq_cache)
+ kmem_cache_destroy(eq_cache);
+}
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index 96eba38..7a4071a 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -389,32 +389,24 @@ static inline void reset_eq_pending(struct ehca_cq *cq)
return;
}
-irqreturn_t ehca_interrupt_neq(int irq, void *dev_id)
-{
- struct ehca_shca *shca = (struct ehca_shca*)dev_id;
-
- tasklet_hi_schedule(&shca->neq.interrupt_task);
-
- return IRQ_HANDLED;
-}
-
void ehca_tasklet_neq(unsigned long data)
{
- struct ehca_shca *shca = (struct ehca_shca*)data;
+ struct ehca_eq *neq = (struct ehca_eq *)data;
+ struct ehca_shca *shca = neq->shca;
struct ehca_eqe *eqe;
u64 ret;
- eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->neq);
+ eqe = (struct ehca_eqe *)ehca_poll_eq(neq);
while (eqe) {
if (!EHCA_BMASK_GET(NEQE_COMPLETION_EVENT, eqe->entry))
parse_ec(shca, eqe->entry);
- eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->neq);
+ eqe = (struct ehca_eqe *)ehca_poll_eq(neq);
}
ret = hipz_h_reset_event(shca->ipz_hca_handle,
- shca->neq.ipz_eq_handle, 0xFFFFFFFFFFFFFFFFL);
+ neq->ipz_eq_handle, 0xFFFFFFFFFFFFFFFFL);
if (ret != H_SUCCESS)
ehca_err(&shca->ib_device, "Can't clear notification events.");
@@ -422,11 +414,11 @@ void ehca_tasklet_neq(unsigned long data)
return;
}
-irqreturn_t ehca_interrupt_eq(int irq, void *dev_id)
+irqreturn_t ehca_interrupt(int irq, void *dev_id)
{
- struct ehca_shca *shca = (struct ehca_shca*)dev_id;
+ struct ehca_eq *eq = (struct ehca_eq *)dev_id;
- tasklet_hi_schedule(&shca->eq.interrupt_task);
+ tasklet_hi_schedule(&eq->interrupt_task);
return IRQ_HANDLED;
}
@@ -468,9 +460,9 @@ static inline void process_eqe(struct ehca_shca *shca, struct ehca_eqe *eqe)
}
}
-void ehca_process_eq(struct ehca_shca *shca, int is_irq)
+void ehca_process_eq(struct ehca_eq *eq, int is_irq)
{
- struct ehca_eq *eq = &shca->eq;
+ struct ehca_shca *shca = eq->shca;
struct ehca_eqe_cache_entry *eqe_cache = eq->eqe_cache;
u64 eqe_value;
unsigned long flags;
@@ -498,7 +490,7 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
do {
u32 token;
eqe_cache[eqe_cnt].eqe =
- (struct ehca_eqe *)ehca_poll_eq(shca, eq);
+ (struct ehca_eqe *)ehca_poll_eq(eq);
if (!eqe_cache[eqe_cnt].eqe)
break;
eqe_value = eqe_cache[eqe_cnt].eqe->entry;
@@ -535,7 +527,7 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
}
/* check eq */
spin_lock(&eq->spinlock);
- eq_empty = (!ipz_eqit_eq_peek_valid(&shca->eq.ipz_queue));
+ eq_empty = (!ipz_eqit_eq_peek_valid(&eq->ipz_queue));
spin_unlock(&eq->spinlock);
/* call completion handler for cached eqes */
for (i = 0; i < eqe_cnt; i++)
@@ -557,7 +549,7 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
goto unlock_irq_spinlock;
do {
struct ehca_eqe *eqe;
- eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->eq);
+ eqe = (struct ehca_eqe *)ehca_poll_eq(eq);
if (!eqe)
break;
process_eqe(shca, eqe);
@@ -569,7 +561,7 @@ unlock_irq_spinlock:
void ehca_tasklet_eq(unsigned long data)
{
- ehca_process_eq((struct ehca_shca*)data, 1);
+ ehca_process_eq((struct ehca_eq *)data, 1);
}
static inline int find_next_online_cpu(struct ehca_comp_pool* pool)
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.h b/drivers/infiniband/hw/ehca/ehca_irq.h
index 3346cb0..18d5397 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.h
+++ b/drivers/infiniband/hw/ehca/ehca_irq.h
@@ -50,12 +50,10 @@ struct ehca_shca;
int ehca_error_data(struct ehca_shca *shca, void *data, u64 resource);
-irqreturn_t ehca_interrupt_neq(int irq, void *dev_id);
-void ehca_tasklet_neq(unsigned long data);
-
-irqreturn_t ehca_interrupt_eq(int irq, void *dev_id);
+irqreturn_t ehca_interrupt(int irq, void *dev_id);
void ehca_tasklet_eq(unsigned long data);
-void ehca_process_eq(struct ehca_shca *shca, int is_irq);
+void ehca_tasklet_neq(unsigned long data);
+void ehca_process_eq(struct ehca_eq *eq, int is_irq);
struct ehca_cpu_comp_task {
wait_queue_head_t wait_queue;
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h
index 77aeca6..bf8fbf7 100644
--- a/drivers/infiniband/hw/ehca/ehca_iverbs.h
+++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h
@@ -117,13 +117,12 @@ enum ehca_eq_type {
EHCA_NEQ /* Notification Event Queue */
};
-int ehca_create_eq(struct ehca_shca *shca, struct ehca_eq *eq,
- enum ehca_eq_type type, const u32 length);
+struct ehca_eq *ehca_create_eq(struct ehca_shca *shca,
+ const enum ehca_eq_type type, const u32 length);
-int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq);
-
-void *ehca_poll_eq(struct ehca_shca *shca, struct ehca_eq *eq);
+int ehca_destroy_eq(struct ehca_eq *eq);
+void *ehca_poll_eq(struct ehca_eq *eq);
struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
struct ib_ucontext *context,
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 28ba2dd..d9a37dc 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -63,6 +63,8 @@ int ehca_port_act_time = 30;
int ehca_poll_all_eqs = 1;
int ehca_static_rate = -1;
int ehca_scaling_code = 0;
+int ehca_nr_eqs = 2;
+int ehca_dist_eqs = 0;
module_param_named(open_aqp1, ehca_open_aqp1, int, 0);
module_param_named(debug_level, ehca_debug_level, int, 0);
@@ -72,7 +74,9 @@ module_param_named(use_hp_mr, ehca_use_hp_mr, int, 0);
module_param_named(port_act_time, ehca_port_act_time, int, 0);
module_param_named(poll_all_eqs, ehca_poll_all_eqs, int, 0);
module_param_named(static_rate, ehca_static_rate, int, 0);
-module_param_named(scaling_code, ehca_scaling_code, int, 0);
+module_param_named(scaling_code, ehca_scaling_code, int, 0);
+module_param_named(nr_eqs, ehca_nr_eqs, int, 0);
+module_param_named(dist_eqs, ehca_dist_eqs, int, 0);
MODULE_PARM_DESC(open_aqp1,
"AQP1 on startup (0: no (default), 1: yes)");
@@ -95,6 +99,11 @@ MODULE_PARM_DESC(static_rate,
"set permanent static rate (default: disabled)");
MODULE_PARM_DESC(scaling_code,
"set scaling code (0: disabled/default, 1: enabled)");
+MODULE_PARM_DESC(nr_eqs,
+ "set number of event queues (default : 2)");
+MODULE_PARM_DESC(dist_eqs,
+ "enable distributing EQs across CQs "
+ "(0: disabled/default, 1: enabled)");
DEFINE_RWLOCK(ehca_qp_idr_lock);
DEFINE_RWLOCK(ehca_cq_idr_lock);
@@ -135,6 +144,12 @@ static int ehca_create_slab_caches(void)
return ret;
}
+ ret = ehca_init_eq_cache();
+ if (ret) {
+ ehca_gen_err("Cannot create EQ SLAB cache.");
+ goto create_slab_caches1;
+ }
+
ret = ehca_init_cq_cache();
if (ret) {
ehca_gen_err("Cannot create CQ SLAB cache.");
@@ -182,6 +197,9 @@ create_slab_caches3:
ehca_cleanup_cq_cache();
create_slab_caches2:
+ ehca_cleanup_eq_cache();
+
+create_slab_caches1:
ehca_cleanup_pd_cache();
return ret;
@@ -193,6 +211,7 @@ static void ehca_destroy_slab_caches(void)
ehca_cleanup_av_cache();
ehca_cleanup_qp_cache();
ehca_cleanup_cq_cache();
+ ehca_cleanup_eq_cache();
ehca_cleanup_pd_cache();
#ifdef CONFIG_PPC_64K_PAGES
if (ctblk_cache)
@@ -362,7 +381,7 @@ int ehca_init_device(struct ehca_shca *shca)
shca->ib_device.node_type = RDMA_NODE_IB_CA;
shca->ib_device.phys_port_cnt = shca->num_ports;
- shca->ib_device.num_comp_vectors = 1;
+ shca->ib_device.num_comp_vectors = ehca_nr_eqs;
shca->ib_device.dma_device = &shca->ibmebus_dev->ofdev.dev;
shca->ib_device.query_device = ehca_query_device;
shca->ib_device.query_port = ehca_query_port;
@@ -585,6 +604,15 @@ static ssize_t ehca_show_adapter_handle(struct device *dev,
}
static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL);
+static ssize_t ehca_show_nr_eqs(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", ehca_nr_eqs);
+}
+
+static DEVICE_ATTR(nr_eqs, S_IRUGO, ehca_show_nr_eqs, NULL);
+
static struct attribute *ehca_dev_attrs[] = {
&dev_attr_adapter_handle.attr,
&dev_attr_num_ports.attr,
@@ -601,6 +629,7 @@ static struct attribute *ehca_dev_attrs[] = {
&dev_attr_cur_mw.attr,
&dev_attr_max_pd.attr,
&dev_attr_max_ah.attr,
+ &dev_attr_nr_eqs.attr,
NULL
};
@@ -608,13 +637,27 @@ static struct attribute_group ehca_dev_attr_grp = {
.attrs = ehca_dev_attrs
};
+static void destroy_all_eqs(struct ehca_shca *shca)
+{
+ int ret, i;
+
+ for (i = 0; i < ehca_nr_eqs && shca->eqs[i]; i++) {
+ ret = ehca_destroy_eq(shca->eqs[i]);
+ if (ret)
+ ehca_err(&shca->ib_device, "Cannot destroy EQ "
+ "ret=%x i=%x eq=%p", ret, i, shca->eqs[i]);
+ }
+
+ kfree(shca->eqs);
+}
+
static int __devinit ehca_probe(struct ibmebus_dev *dev,
const struct of_device_id *id)
{
struct ehca_shca *shca;
const u64 *handle;
struct ib_pd *ibpd;
- int ret;
+ int ret, i;
handle = of_get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
if (!handle) {
@@ -648,19 +691,35 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
ret = ehca_init_device(shca);
if (ret) {
- ehca_gen_err("Cannot init ehca device struct");
+ ehca_gen_err("Cannot init ehca device struct");
goto probe1;
}
/* create event queues */
- ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048);
- if (ret) {
- ehca_err(&shca->ib_device, "Cannot create EQ.");
+ shca->eqs = kzalloc(ehca_nr_eqs * sizeof(*shca->eqs), GFP_KERNEL);
+ if (!shca->eqs) {
+ ehca_gen_err("Cannot alloc eqs array");
goto probe1;
}
- ret = ehca_create_eq(shca, &shca->neq, EHCA_NEQ, 513);
- if (ret) {
+ for (i = 0; i < ehca_nr_eqs; i++) {
+ shca->eqs[i] = ehca_create_eq(shca, EHCA_EQ, 2048);
+ if (IS_ERR(shca->eqs[i])) {
+ ehca_err(&shca->ib_device, "Cannot create EQ.");
+ ret = PTR_ERR(shca->eqs[i]);
+ shca->eqs[i] = NULL;
+ goto probe2;
+ }
+ }
+
+ shca->aeq = ehca_create_eq(shca, EHCA_EQ, 2048);
+ if (IS_ERR(shca->aeq)) {
+ ehca_err(&shca->ib_device, "Cannot create AEQ.");
+ goto probe2;
+ }
+
+ shca->neq = ehca_create_eq(shca, EHCA_NEQ, 513);
+ if (IS_ERR(shca->neq)) {
ehca_err(&shca->ib_device, "Cannot create NEQ.");
goto probe3;
}
@@ -747,16 +806,20 @@ probe5:
"Cannot destroy internal PD. ret=%x", ret);
probe4:
- ret = ehca_destroy_eq(shca, &shca->neq);
+ ret = ehca_destroy_eq(shca->neq);
if (ret)
ehca_err(&shca->ib_device,
"Cannot destroy NEQ. ret=%x", ret);
probe3:
- ret = ehca_destroy_eq(shca, &shca->eq);
+ ret = ehca_destroy_eq(shca->aeq);
if (ret)
ehca_err(&shca->ib_device,
- "Cannot destroy EQ. ret=%x", ret);
+ "Cannot destroy AEQ. ret=%x", ret);
+
+probe2:
+ if (shca->eqs)
+ destroy_all_eqs(shca);
probe1:
ib_dealloc_device(&shca->ib_device);
@@ -767,12 +830,11 @@ probe1:
static int __devexit ehca_remove(struct ibmebus_dev *dev)
{
struct ehca_shca *shca = dev->ofdev.dev.driver_data;
- int ret;
+ int ret, i;
sysfs_remove_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp);
if (ehca_open_aqp1 == 1) {
- int i;
for (i = 0; i < shca->num_ports; i++) {
ret = ehca_destroy_aqp1(&shca->sport[i]);
if (ret)
@@ -794,11 +856,14 @@ static int __devexit ehca_remove(struct ibmebus_dev *dev)
ehca_err(&shca->ib_device,
"Cannot destroy internal PD. ret=%x", ret);
- ret = ehca_destroy_eq(shca, &shca->eq);
+ if (shca->eqs)
+ destroy_all_eqs(shca);
+
+ ret = ehca_destroy_eq(shca->aeq);
if (ret)
- ehca_err(&shca->ib_device, "Cannot destroy EQ. ret=%x", ret);
+ ehca_err(&shca->ib_device, "Canot destroy AEQ. ret=%x", ret);
- ret = ehca_destroy_eq(shca, &shca->neq);
+ ret = ehca_destroy_eq(shca->neq);
if (ret)
ehca_err(&shca->ib_device, "Canot destroy NEQ. ret=%x", ret);
@@ -829,16 +894,20 @@ static struct ibmebus_driver ehca_driver = {
void ehca_poll_eqs(unsigned long data)
{
+ extern int ehca_nr_eqs;
struct ehca_shca *shca;
spin_lock(&shca_list_lock);
list_for_each_entry(shca, &shca_list, shca_list) {
- if (shca->eq.is_initialized) {
- /* call deadman proc only if eq ptr does not change */
- struct ehca_eq *eq = &shca->eq;
+ int i;
+ for (i = 0; i < ehca_nr_eqs; i++) {
+ struct ehca_eq *eq = shca->eqs[i];
int max = 3;
volatile u64 q_ofs, q_ofs2;
u64 flags;
+ if (!eq || !eq->is_initialized)
+ continue;
+ /* call deadman proc only if eq ptr does not change */
spin_lock_irqsave(&eq->spinlock, flags);
q_ofs = eq->ipz_queue.current_q_offset;
spin_unlock_irqrestore(&eq->spinlock, flags);
@@ -849,7 +918,7 @@ void ehca_poll_eqs(unsigned long data)
max--;
} while (q_ofs == q_ofs2 && max > 0);
if (q_ofs == q_ofs2)
- ehca_process_eq(shca, 0);
+ ehca_process_eq(eq, 0);
}
}
mod_timer(&poll_eqs_timer, jiffies + HZ);
@@ -863,6 +932,13 @@ int __init ehca_module_init(void)
printk(KERN_INFO "eHCA Infiniband Device Driver "
"(Rel.: SVNEHCA_0023)\n");
+ if (ehca_nr_eqs < 1 || ehca_nr_eqs > EHCA_MAX_NR_EQS) {
+ ehca_gen_err("Invalid option nr_eqs=%x. "
+ "Specify a number in range [1-%d].",
+ ehca_nr_eqs, EHCA_MAX_NR_EQS);
+ return -EINVAL;
+ }
+
if ((ret = ehca_create_comp_pool())) {
ehca_gen_err("Cannot create comp pool.");
return ret;
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 7467125..f6f4ef6 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -545,7 +545,7 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd,
}
parms.token = my_qp->token;
- parms.eq_handle = shca->eq.ipz_eq_handle;
+ parms.eq_handle = shca->aeq->ipz_eq_handle;
parms.pd = my_pd->fw_pd;
if (my_qp->send_cq)
parms.send_cq_handle = my_qp->send_cq->ipz_cq_handle;
--
1.5.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox