[Armadillo:06485] Re: ドライバ・モジュールのメモリサイズの制限について
mizo
email@hidden
2011年 1月 7日 (金) 14:01:59 JST
溝渕です。
ecom 草川 wrote:
> 草川と申します。お世話になります。
>
> 現在、簡単なドライバ・モジュールを作成してDMA転送の検討を行って
> おります。そのモジュールでは、3MByteの連続した動的メモリを2つ
> 確保しようとしているのですが insmod で組込んでみると、1つ目は確保
> できるのですが、2つ目は失敗してしまいます。
>
> free コマンドで確認しても、メモリ全体の空きはかなりあるように思
> えるのですが、どこかで、モジュール用のメモリーに、何らかの制限が
> 設けられているのでしょうか?
dma_alloc_coherent()は"連続した"領域を確保しようとします。メモリに十分な
空きがあっても、連続した領域が無ければ失敗します。
「Linux Device Drivers, Third Edition」
の
「Chapter 15: Memory Mapping and DMA」「Do-it-yourself allocation」
に詳しい説明と対応方法がありますが、
起動時にカーネルパラメータより、"mem="オプションを仕様すると、メモリ先頭
からmemの引数分以外の領域をカーネルが予約します。
例えば、Armadillo-440の実メモリは128MBなので、
mem=120M
とし、
buf = ioremap(0x07800000/*120MB*/, 0x00800000/*8MB*/);
とすると8MBの領域が確保できるようです。
# 私は試したことはありませんが…。
以上お試しください。
> また、もしそのような制限がある場合には、それを変更する方法はあり
> ますでしょうか?
>
>
> 動作環境は以下の通りです。
>
> armadillo-440
> atmark-dist-20101118
> linux-2.6.26-at12
> atde3
>
> 検討したソース(メモリ確保部分)は概要、以下の通りです。
>
> #include <linux/pci.h>
> #include <asm/arch/dma.h>
>
> #define DMA_MEM_SIZE (3*1024*1024)
>
> unsigned int start_addr_1;
> unsigned int start_addr_2;
> unsigned int start_paddr_1;
> unsigned int start_paddr_2;
>
> /* メモリ確保(1) */
> start_addr_1 = dma_alloc_coherent(
> 0,
> PAGE_ALIGN(DMA_MEM_SIZE),
> &start_paddr_1,
> GFP_DMA | GFP_KERNEL );
> if (!start_addr_1) {
> printk(KERN_ERR "DMA Alloc Error(1)\n");
> return;
> }
> /* メモリ確保(2) */
> start_addr_2 = dma_alloc_coherent(
> 0,
> PAGE_ALIGN(DMA_MEM_SIZE),
> &start_paddr_2,
> GFP_DMA | GFP_KERNEL );
> if (!start_addr_2) {
> printk(KERN_ERR "DMA Alloc Error(2)\n");
> return;
> }
>
> また、insmod 前のfreeコマンド、cat /proc/meminfo コマンドと、
> insmod時のエラー出力は以下の通りです。
>
> // ==> ここから
>
> [email@hidden]# free
> total used free shared buffers
> Mem: 126104 43544 82560 0 348
> Swap: 0 0 0
> Total: 126104 43544 82560
>
> [email@hidden]# cat /proc/meminfo
> MemTotal: 126104 kB
> MemFree: 82532 kB
> Buffers: 348 kB
> Cached: 6124 kB
> SwapCached: 0 kB
> Active: 3824 kB
> Inactive: 4232 kB
> SwapTotal: 0 kB
> SwapFree: 0 kB
> Dirty: 0 kB
> Writeback: 0 kB
> AnonPages: 1592 kB
> Mapped: 2644 kB
> Slab: 2880 kB
> SReclaimable: 532 kB
> SUnreclaim: 2348 kB
> PageTables: 156 kB
> NFS_Unstable: 0 kB
> Bounce: 0 kB
> WritebackTmp: 0 kB
> CommitLimit: 63052 kB
> Committed_AS: 10680 kB
> VmallocTotal: 122880 kB
> VmallocUsed: 48 kB
> VmallocChunk: 122832 kB
>
> [email@hidden]# insmod test.ko
> ...
>
> busybox: page allocation failure. order:10, mode:0xd1
> [<c02e0238>] (dump_stack+0x0/0x14) from [<c007ad8c>] (__alloc_pages_internal+0x348/0x428)
> [<c007aa44>] (__alloc_pages_internal+0x0/0x428) from [<c007ae94>] (__alloc_pages+0x14/0x18)
> [<c007ae80>] (__alloc_pages+0x0/0x18) from [<c002f5c8>] (__dma_alloc+0xf0/0x44c)
> [<c002f4d8>] (__dma_alloc+0x0/0x44c) from [<c002f978>] (dma_alloc_coherent+0x24/0x30)
> [<c002f954>] (dma_alloc_coherent+0x0/0x30) from [<bf002050>] (test_init+0x50/0x98 [test])
> [<bf002000>] (test_init+0x0/0x98 [test]) from [<c006c344>] (sys_init_module+0xf4/0x1aec)
> [<c006c250>] (sys_init_module+0x0/0x1aec) from [<c002ab80>] (ret_fast_syscall+0x0/0x2c)
> Mem-info:
> DMA per-cpu:
> CPU 0: hi: 0, btch: 1 usd: 0
> Normal per-cpu:
> CPU 0: hi: 42, btch: 7 usd: 39
> Active:939 inactive:1059 dirty:4 writeback:0 unstable:0
> free:20591 slab:749 mapped:665 pagetables:39 bounce:0
> DMA free:3220kB min:132kB low:164kB high:196kB active:0kB inactive:0kB present:1
> 2192kB pages_scanned:0 all_unreclaimable? no
> lowmem_reserve[]: 0 115 115
> Normal free:79144kB min:1304kB low:1628kB high:1956kB active:3756kB inactive:423
> 6kB present:117856kB pages_scanned:0 all_unreclaimable? no
> lowmem_reserve[]: 0 0 0
> DMA: 1*4kB 2*8kB 0*16kB 2*32kB 1*64kB 0*128kB 0*256kB 0*512kB 3*1024kB 0*2048kB 0*4096kB = 3220kB
> Normal: 174*4kB 70*8kB 26*16kB 11*32kB 1*64kB 2*128kB 8*256kB 2*512kB 8*1024kB 6*2048kB 13*4096kB = 79144kB
> 1618 total pagecache pages
> Swap cache: add 0, delete 0, find 0/0
> Free swap = 0kB
> Total swap = 0kB
> 32768 pages of RAM
> 20686 free pages
> 2340 reserved pages
> 749 slab pages
> 1725 pages shared
> 0 pages swap cached
> DMA Alloc Error(2) //<== ここでエラーとなっております
> sys_init_module: 'test'->init suspiciously returned 26, it should follow 0/-E convention
> sys_init_module: loading module anyway...
> [<c02e0238>] (dump_stack+0x0/0x14) from [<c006ca18>] (sys_init_module+0x7c8/0x1aec)
> [<c006c250>] (sys_init_module+0x0/0x1aec) from [<c002ab80>] (ret_fast_syscall+0x0/0x2c)
>
> [email@hidden]#
>
> // <== ここまで
>
> 以上、ご教授、よろしくお願い致します。
armadillo メーリングリストの案内