Re: [patch 2/2] backport of sba sg list management to ccio-dma
Grant Grundler <[email protected]> Sun, 28 Oct 2007 00:41:58 -0600
| Newsgroups | gmane.linux.ports.hppa |
|---|---|
| Message-ID | <[email protected]> |
On Fri, Oct 26, 2007 at 03:20:55PM +0200, Joel Soete wrote:
...
> > > (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]
Understood - ia64 has an instruction to implement FFS/FLS. PA-RISC does not.
> 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;
> }
Prove this code is faster than the __ffs asm in include/asm-parisc/bitops.h
and we can talk about it. Unless gcc has gotten phenomenally better, I'm
not inclined to believe the generic code will be faster.
> 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)
Sure - submit a patch for that. That sounds fine to me.
> 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));
> }
This looks fine to me.
I've not checked if all possible values map correctly.
Can you try (for n in 0-31), and verify (2^n) and (2^n)+1 values are the
same for the above and the original get_order() function?
> or imho even better
>
> return (size ? fls((size - 1) >> (PAGE_SHIFT)): 0);
fls is inlined already and does the same test for size.
Adding another test here doesn't help.
The first one you posted is correct.
> Is it a bit more clear?
> (I just hope you will not ask me to make the mathematical demonstration ;-))
I don't need a mathematical demonstration...just a short test to demonstrate
(2^n) and (2^n+1) still produce the same results.
> What's your opinion?
In general, sounds good to me! :)
hth,
grant