[parisc-linux] [patch 2/2] backport of sba sg list management to ccio-dma
Joel Soete
soete.joel at scarlet.be
Fri Oct 26 07:20:55 MDT 2007
> On Thu, Oct 25, 2007 at 09:13:18AM +0200, Joel Soete wrote:
> ...
> > I attached 2 test files (GetOrder-o.c using the original kernel get_iovp_order
> > routine and GetOrder-f.c using supposed faster release) and here are some
> > results:
> ...
> > I didn't check in more details the difference of results between not-optimized
> > and optimized (-O2) compile but it's clear it's faster ;-)
>
> Thanks for running those...I didn't expect it to be 40x faster (in the
> first pair of runs).
>
> > (why not push this in upstream? [I mean ./include/asm-generic/page.h])
>
> Erm, push what?
Sorry for shortcut, here is more detailed idea:
get_iovp_order came to me when reading the ia64/hp sba implementation where
you can read:
arch/ia64/hp/common/sba_iommu.c:
/**
* For most cases the normal get_order is sufficient, however it limits us
* to PAGE_SIZE being the minimum mapping alignment and TC flush granularity.
* It only incurs about 1 clock cycle to use this one with the static variable
* and makes the code more intuitive.
*/
static SBA_INLINE int
get_iovp_order (unsigned long size)
[snip]
but it's ia64 and I look for something I could test on parisc and this generic
code looked to me ideal:
include/asm-generic/page.h
/* Pure 2^n version of get_order */
static __inline__ __attribute_const__ int get_order(unsigned long size)
{
int order;
size = (size - 1) >> (PAGE_SHIFT - 1);
order = -1;
do {
size >>= 1;
order++;
} while (size);
return order;
}
just want to change PAGE_SHIFT with IOVP_SHIFT to make the drill ;-)
(this was this first idea)
static CCIO_INLINE int
get_iovp_order(unsigned long size)
{
int order;
size = (size - 1) >> (IOVP_SHIFT - 1);
order = -1;
do {
size >>= 1;
order++;
} while (size);
return order;
}
which make you though to ffs() which in turn make me proposed following:
static CCIO_INLINE int
get_iovp_order(unsigned long size)
{
return fls((size - 1) >> (IOVP_SHIFT));
}
(test case comparison loop shows well it's the same even for size=0)
I did some test with different values of IOVP_SHIFT and even with this case
IOVP_SHIFT==PAGE_SHIFT which is to me get_order().
static __inline__ __attribute_const__ int get_order(unsigned long size)
{
return fls((size - 1) >> (PAGE_SHIFT));
}
or imho even better
return (size ? fls((size - 1) >> (PAGE_SHIFT)): 0);
Is it a bit more clear?
(I just hope you will not ask me to make the mathematical demonstration ;-))
What's your opinion?
> The code I was referring to is parisc assembly.
> That doesn't belong in asm-generic.
> Or did you somehow overlook that?
>
> ...
> > > I'm not sure we have to handle that case...or if we do, make sure it's
> > handled correctly in get_iovp_order().
> > >
> > I just hope so that linux check to never call get_order(0) ;-)
>
> "hope?" Bad idea. :)
> Please add an ASSERT or verify ccio can never invokes get_order(0).
>
Yep or apply same idea as above but for get_iovp_order (i.e. return (size ?
fls((size - 1) >> (IOVP_SHIFT)): 0)
(Test doesn't show any lost of perf ;-)
> thanks,
> grant
>
>
All additional comment will be welcome.
Tx,
J.
---
Pack Scarlet One, ADSL 6 Mbps + Telephonie, a partir de EUR 29,95...
http://www.scarlet.be/
More information about the parisc-linux
mailing list