Linux MIPS Architecture development
 help / color / mirror / Atom feed
* is remap_pfn_range should align to 2(n) * (page size) ?
@ 2008-05-09  6:54 zhuzhenhua
  2008-05-09  9:56 ` Ralf Baechle
  0 siblings, 1 reply; 8+ messages in thread
From: zhuzhenhua @ 2008-05-09  6:54 UTC (permalink / raw)
  To: linux-mips

[-- Attachment #1: Type: text/plain, Size: 391 bytes --]

hello all
           i have a sensor driver want to malloc 2.xM SDRAM to capture
data(using DMA),  so i used  remap_pfn_range to malloc 3M.
But in /proc/meminfo, it showes free memory reduce 4M. i also check the
/proc/buddyinfo, it seemes too.
(i am looking inside kernel code, but not get clear at now).

 is remap_pfn_range should align to  2(n) * (page size) ?

thanks for any hints

zzh

[-- Attachment #2: Type: text/html, Size: 500 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: is remap_pfn_range should align to 2(n) * (page size) ?
  2008-05-09  6:54 is remap_pfn_range should align to 2(n) * (page size) ? zhuzhenhua
@ 2008-05-09  9:56 ` Ralf Baechle
  2008-05-12  2:18   ` zhuzhenhua
  0 siblings, 1 reply; 8+ messages in thread
From: Ralf Baechle @ 2008-05-09  9:56 UTC (permalink / raw)
  To: zhuzhenhua; +Cc: linux-mips

On Fri, May 09, 2008 at 02:54:29PM +0800, zhuzhenhua wrote:

>            i have a sensor driver want to malloc 2.xM SDRAM to capture
> data(using DMA),  so i used  remap_pfn_range to malloc 3M.
> But in /proc/meminfo, it showes free memory reduce 4M. i also check the
> /proc/buddyinfo, it seemes too.
> (i am looking inside kernel code, but not get clear at now).
> 
>  is remap_pfn_range should align to  2(n) * (page size) ?

This has nothing to do with remap_pfn_range but with the power of two
sized buckets used by the global free page pool.  Any allocation with
get_free_pages will be rounded up to the next power of two.  If that's a
real concern for you you could allocate a 4MB page then split the page
into a 2MB and two 1MB pages and free the 1MB page again.

  Ralf

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: is remap_pfn_range should align to 2(n) * (page size) ?
  2008-05-09  9:56 ` Ralf Baechle
@ 2008-05-12  2:18   ` zhuzhenhua
  2008-05-12 11:22     ` Ralf Baechle
  0 siblings, 1 reply; 8+ messages in thread
From: zhuzhenhua @ 2008-05-12  2:18 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips

[-- Attachment #1: Type: text/plain, Size: 1165 bytes --]

On 5/9/08, Ralf Baechle <ralf@linux-mips.org> wrote:
>
> On Fri, May 09, 2008 at 02:54:29PM +0800, zhuzhenhua wrote:
>
> >            i have a sensor driver want to malloc 2.xM SDRAM to capture
> > data(using DMA),  so i used  remap_pfn_range to malloc 3M.
> > But in /proc/meminfo, it showes free memory reduce 4M. i also check the
> > /proc/buddyinfo, it seemes too.
> > (i am looking inside kernel code, but not get clear at now).
> >
> >  is remap_pfn_range should align to  2(n) * (page size) ?
>
>
> This has nothing to do with remap_pfn_range but with the power of two
> sized buckets used by the global free page pool.  Any allocation with
> get_free_pages will be rounded up to the next power of two.  If that's a
> real concern for you you could allocate a 4MB page then split the page
> into a 2MB and two 1MB pages and free the 1MB page again.
>
>
>   Ralf


thanks for your reply , i see in get_frree_pages and free_pages there is a
get_order(size).
but i don't understand  " allocate a 4MB page then split the page
into a 2MB and two 1MB pages and free the 1MB page again."
is there any function to split it?

thanks for any hints

Best Regards


zzh

[-- Attachment #2: Type: text/html, Size: 1764 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: is remap_pfn_range should align to 2(n) * (page size) ?
  2008-05-12  2:18   ` zhuzhenhua
@ 2008-05-12 11:22     ` Ralf Baechle
  2008-05-13 11:44       ` zhuzhenhua
  0 siblings, 1 reply; 8+ messages in thread
From: Ralf Baechle @ 2008-05-12 11:22 UTC (permalink / raw)
  To: zhuzhenhua; +Cc: linux-mips

On Mon, May 12, 2008 at 10:18:27AM +0800, zhuzhenhua wrote:

> > This has nothing to do with remap_pfn_range but with the power of two
> > sized buckets used by the global free page pool.  Any allocation with
> > get_free_pages will be rounded up to the next power of two.  If that's a
> > real concern for you you could allocate a 4MB page then split the page
> > into a 2MB and two 1MB pages and free the 1MB page again.

> thanks for your reply , i see in get_frree_pages and free_pages there is a
> get_order(size).
> but i don't understand  " allocate a 4MB page then split the page
> into a 2MB and two 1MB pages and free the 1MB page again."
> is there any function to split it?

No, you'd have to code that yourself.  Take a look at split_page() which
splits an order n page into order 0 pages.  You'd want something similar
but splitting for some non-zero order.

  Ralf

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: is remap_pfn_range should align to 2(n) * (page size) ?
  2008-05-12 11:22     ` Ralf Baechle
@ 2008-05-13 11:44       ` zhuzhenhua
  2008-05-13 17:23         ` Ralf Baechle
  0 siblings, 1 reply; 8+ messages in thread
From: zhuzhenhua @ 2008-05-13 11:44 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips

[-- Attachment #1: Type: text/plain, Size: 4385 bytes --]

On 5/12/08, Ralf Baechle <ralf@linux-mips.org> wrote:
>
> On Mon, May 12, 2008 at 10:18:27AM +0800, zhuzhenhua wrote:
>
> > > This has nothing to do with remap_pfn_range but with the power of two
> > > sized buckets used by the global free page pool.  Any allocation with
> > > get_free_pages will be rounded up to the next power of two.  If that's
> a
> > > real concern for you you could allocate a 4MB page then split the page
> > > into a 2MB and two 1MB pages and free the 1MB page again.
>
>
> > thanks for your reply , i see in get_frree_pages and free_pages there is
> a
> > get_order(size).
> > but i don't understand  " allocate a 4MB page then split the page
> > into a 2MB and two 1MB pages and free the 1MB page again."
> > is there any function to split it?
>
>
> No, you'd have to code that yourself.  Take a look at split_page() which
> splits an order n page into order 0 pages.  You'd want something similar
> but splitting for some non-zero order.
>
>
>   Ralf


thanks for your advice, i found in newest kernel version, in some arch , the
dma_alloc_coherent will call split_page.
because my kernel version is 2.6.14, so i first patch a split_page patch as
follow:
http://www.kernel.org/pub/linux/kernel/people/npiggin/patches/lockless/2.6.16-rc5/broken-out/mm-split-highorder.patch

but it seemes that there is still no split_page in
dma_alloc_coherent/dma_alloc_noncoherent
so i copy from other arch code to arch/mips/mm/dma-noncoherent.c (attach at
the end of mail)
and now my driver just use dma_alloc_coherent malloc 3M directly, and it
seemes ok.
i just wonder why mips arch dma_alloc_coherent/dma_alloc_nocoherent do not
call split_page while other arch calling.

thanks for any hints.

Best Regards

zzh






modify on dma-noncoherent.c
--- dma-noncoherent.c    2008-05-13 19:31:58.131375500 +0800
+++ dma-noncoherent-split.c    2008-05-13 19:31:51.039745500 +0800
@@ -16,27 +16,59 @@

 #include <asm/cache.h>
 #include <asm/io.h>
+
+static struct page *__dma_alloc(struct device *dev, size_t size,
+                dma_addr_t *handle, gfp_t gfp)
+{
+    struct page *page, *free, *end;
+    int order;
+
+    size = PAGE_ALIGN(size);
+    order = get_order(size);
+    page = alloc_pages(gfp, order);
+    if (!page)
+        return NULL;
+    split_page(page, order);
+
+    *handle = page_to_phys(page);
+    free = page + (size >> PAGE_SHIFT);
+    end = page + (1 << order);

-/*
- * Warning on the terminology - Linux calls an uncached area coherent;
- * MIPS terminology calls memory areas with hardware maintained coherency
- * coherent.
- */
+    /*
+     * Free any unused pages
+     */
+    while (free < end) {
+        __free_page(free);
+        free++;
+    }
+
+    return page;
+}
+
+static void __dma_free(struct device *dev, size_t size,
+               struct page *page, dma_addr_t handle)
+{
+    struct page *end = page + (PAGE_ALIGN(size) >> PAGE_SHIFT);

+    while (page < end)
+        __free_page(page++);
+}
 void *dma_alloc_noncoherent(struct device *dev, size_t size,
     dma_addr_t * dma_handle, unsigned int __nocast gfp)
 {
+    struct page *page;
     void *ret;
     /* ignore region specifiers */
     gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);

     if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
         gfp |= GFP_DMA;
-    ret = (void *) __get_free_pages(gfp, get_order(size));
-
+    page = __dma_alloc(dev, size, dma_handle, gfp);
+    if (page)
+        ret = KSEG1ADDR(page_to_phys(page));
+    printk("ret in dma_alloc_noncoherent = 0x%x\n",ret);
     if (ret != NULL) {
         memset(ret, 0, size);
-        *dma_handle = virt_to_phys(ret);
     }

     return ret;
@@ -63,19 +95,17 @@
 void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
     dma_addr_t dma_handle)
 {
-    free_pages((unsigned long) vaddr, get_order(size));
+    void *addr = KSEG0ADDR(vaddr);
+    struct page *page;
+    BUG_ON(!virt_addr_valid(addr));
+    page = virt_to_page(addr);
+    __dma_free(dev, size, page, dma_handle);
 }

 EXPORT_SYMBOL(dma_free_noncoherent);

 void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-    dma_addr_t dma_handle)
-{
-    unsigned long addr = (unsigned long) vaddr;
-
-    addr = CAC_ADDR(addr);
-    free_pages(addr, get_order(size));
-}
+    dma_addr_t dma_handle) __attribute__((alias("dma_free_noncoherent")));

 EXPORT_SYMBOL(dma_free_coherent);

[-- Attachment #2: Type: text/html, Size: 6926 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: is remap_pfn_range should align to 2(n) * (page size) ?
  2008-05-13 11:44       ` zhuzhenhua
@ 2008-05-13 17:23         ` Ralf Baechle
  2008-05-14  1:19           ` zhuzhenhua
  0 siblings, 1 reply; 8+ messages in thread
From: Ralf Baechle @ 2008-05-13 17:23 UTC (permalink / raw)
  To: zhuzhenhua; +Cc: linux-mips

On Tue, May 13, 2008 at 07:44:06PM +0800, zhuzhenhua wrote:

> thanks for your advice, i found in newest kernel version, in some arch , the
> dma_alloc_coherent will call split_page.
> because my kernel version is 2.6.14, so i first patch a split_page patch as
> follow:
> http://www.kernel.org/pub/linux/kernel/people/npiggin/patches/lockless/2.6.16-rc5/broken-out/mm-split-highorder.patch
> 
> but it seemes that there is still no split_page in
> dma_alloc_coherent/dma_alloc_noncoherent
> so i copy from other arch code to arch/mips/mm/dma-noncoherent.c (attach at
> the end of mail)
> and now my driver just use dma_alloc_coherent malloc 3M directly, and it
> seemes ok.
> i just wonder why mips arch dma_alloc_coherent/dma_alloc_nocoherent do not
> call split_page while other arch calling.

I have not identified the waste of memory as a big problem for typical
MIPS systems yet.

The 3MB requirement of your device is sort of odd because it's not a power
of two.  Have you considered splitting the allocation into a 2MB and a 1MB
allocation or would that be undersirable?

  Ralf

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: is remap_pfn_range should align to 2(n) * (page size) ?
  2008-05-13 17:23         ` Ralf Baechle
@ 2008-05-14  1:19           ` zhuzhenhua
  2008-05-14  7:33             ` Geert Uytterhoeven
  0 siblings, 1 reply; 8+ messages in thread
From: zhuzhenhua @ 2008-05-14  1:19 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips

[-- Attachment #1: Type: text/plain, Size: 1761 bytes --]

On Wed, May 14, 2008 at 1:23 AM, Ralf Baechle <ralf@linux-mips.org> wrote:

> On Tue, May 13, 2008 at 07:44:06PM +0800, zhuzhenhua wrote:
>
> > thanks for your advice, i found in newest kernel version, in some arch ,
> the
> > dma_alloc_coherent will call split_page.
> > because my kernel version is 2.6.14, so i first patch a split_page patch
> as
> > follow:
> >
> http://www.kernel.org/pub/linux/kernel/people/npiggin/patches/lockless/2.6.16-rc5/broken-out/mm-split-highorder.patch
> >
> > but it seemes that there is still no split_page in
> > dma_alloc_coherent/dma_alloc_noncoherent
> > so i copy from other arch code to arch/mips/mm/dma-noncoherent.c (attach
> at
> > the end of mail)
> > and now my driver just use dma_alloc_coherent malloc 3M directly, and it
> > seemes ok.
> > i just wonder why mips arch dma_alloc_coherent/dma_alloc_nocoherent do
> not
> > call split_page while other arch calling.
>
> I have not identified the waste of memory as a big problem for typical
> MIPS systems yet.
>
> The 3MB requirement of your device is sort of odd because it's not a power
> of two.  Have you considered splitting the allocation into a 2MB and a 1MB
> allocation or would that be undersirable?
>
>  Ralf
>

Thanks for your reply.
Our board is for embedded system , It only have 32M sdram and we don't want
to
 waste 1M sdram.  My sensor driver need about 2.5xM memory to capture a
picture
 by DMA (our DMA controller do not support scatter/gather).

I also can use bootargs "mem=29M" to keep 3M sdram.  but it's not flexible
as
passing a param to driver module(calling dma_alloc_coherent). maybe my
situation
is not common for MIPS arch. so that's is no split_page in
dma_alloc_coherent.
and now after patch,it seemes ok for me.

Best Regards

zzh

[-- Attachment #2: Type: text/html, Size: 2393 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: is remap_pfn_range should align to 2(n) * (page size) ?
  2008-05-14  1:19           ` zhuzhenhua
@ 2008-05-14  7:33             ` Geert Uytterhoeven
  0 siblings, 0 replies; 8+ messages in thread
From: Geert Uytterhoeven @ 2008-05-14  7:33 UTC (permalink / raw)
  To: zhuzhenhua; +Cc: Ralf Baechle, linux-mips

On Wed, 14 May 2008, zhuzhenhua wrote:
> On Wed, May 14, 2008 at 1:23 AM, Ralf Baechle <ralf@linux-mips.org> wrote:
> > On Tue, May 13, 2008 at 07:44:06PM +0800, zhuzhenhua wrote:
> > > thanks for your advice, i found in newest kernel version, in some arch ,
> > the
> > > dma_alloc_coherent will call split_page.
> > > because my kernel version is 2.6.14, so i first patch a split_page patch
> > as
> > > follow:
> > >
> > http://www.kernel.org/pub/linux/kernel/people/npiggin/patches/lockless/2.6.16-rc5/broken-out/mm-split-highorder.patch
> > >
> > > but it seemes that there is still no split_page in
> > > dma_alloc_coherent/dma_alloc_noncoherent
> > > so i copy from other arch code to arch/mips/mm/dma-noncoherent.c (attach
> > at
> > > the end of mail)
> > > and now my driver just use dma_alloc_coherent malloc 3M directly, and it
> > > seemes ok.
> > > i just wonder why mips arch dma_alloc_coherent/dma_alloc_nocoherent do
> > not
> > > call split_page while other arch calling.
> >
> > I have not identified the waste of memory as a big problem for typical
> > MIPS systems yet.
> >
> > The 3MB requirement of your device is sort of odd because it's not a power
> > of two.  Have you considered splitting the allocation into a 2MB and a 1MB
> > allocation or would that be undersirable?
> >
> 
> Thanks for your reply.
> Our board is for embedded system , It only have 32M sdram and we don't want
> to
>  waste 1M sdram.  My sensor driver need about 2.5xM memory to capture a
> picture
>  by DMA (our DMA controller do not support scatter/gather).
> 
> I also can use bootargs "mem=29M" to keep 3M sdram.  but it's not flexible
> as
> passing a param to driver module(calling dma_alloc_coherent). maybe my
> situation
> is not common for MIPS arch. so that's is no split_page in
> dma_alloc_coherent.
> and now after patch,it seemes ok for me.

One other issue is that bootargs "mem=29M" is guaranteed to give you 3
MiB for your device, while dma_alloc_coherent() may fail if memory is
too fragmented.

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-05-14  7:34 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-09  6:54 is remap_pfn_range should align to 2(n) * (page size) ? zhuzhenhua
2008-05-09  9:56 ` Ralf Baechle
2008-05-12  2:18   ` zhuzhenhua
2008-05-12 11:22     ` Ralf Baechle
2008-05-13 11:44       ` zhuzhenhua
2008-05-13 17:23         ` Ralf Baechle
2008-05-14  1:19           ` zhuzhenhua
2008-05-14  7:33             ` Geert Uytterhoeven

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox