最近のLinuxカーネル(3.4.4)用にコンパイルしようとしている非常に大きなドライバーモジュールがあります。insmod
2.6.27.25カーネルで同じモジュールを正常にコンパイルできます。GCCのバージョンも異なり、4.7.0と4.3.0です。このモジュールは非常に複雑であり、すべてのコードとすべてのmakefileを単純に調べることはできないことに注意してください。
モジュールを「挿入」するとCannot allocate memory
、次のトレースが表示されます。
vmap allocation for size 30248960 failed: use vmalloc=<size> to increase size.
vmalloc: allocation failure: 30243566 bytes
insmod: page allocation failure: order:0, mode:0xd2
Pid: 5840, comm: insmod Tainted: G O 3.4.4-5.fc17.i686 #1
Call Trace:
[<c092702a>] ? printk+0x2d/0x2f
[<c04eff8d>] warn_alloc_failed+0xad/0xf0
[<c05178d9>] __vmalloc_node_range+0x169/0x1d0
[<c0517994>] __vmalloc_node+0x54/0x60
[<c0490825>] ? sys_init_module+0x65/0x1d80
[<c0517a60>] vmalloc+0x30/0x40
[<c0490825>] ? sys_init_module+0x65/0x1d80
[<c0490825>] sys_init_module+0x65/0x1d80
[<c050cda6>] ? handle_mm_fault+0xf6/0x1d0
[<c0932b30>] ? spurious_fault+0xae/0xae
[<c0932ce7>] ? do_page_fault+0x1b7/0x450
[<c093665f>] sysenter_do_call+0x12/0x28
-- clip --
明らかな答えは、モジュールが割り当てているメモリが多すぎるということのようですが、次のようになります。
- このモジュールのサイズに関係なく、古いカーネルバージョンには問題はありません。
- このモジュールの一部を整理してメモリ消費量を大幅に削減すると、新しいカーネルでも常に同じエラーメッセージが表示されます。
- 他の多くのモジュールをアンロードできますが、影響はありません(とにかく関連性がありますか?モジュールごとの合計メモリ使用量に関してLinuxにグローバルな制限があります)
したがって、限られたメモリに直接関係しない新しいカーネルに問題があるのではないかと疑っています。
新しいカーネルは約30,000KBvmalloc()
の不満を言っていますが、古いカーネルでは、lsmodは4,800KBのサイズを提供します。これらの数字は直接関連している必要がありますか?ビルド中に問題が発生し、要求されているRAMが多すぎる可能性はありますか?両方のセクションサイズをコンパイルすると、.ko
大きな違いは見られません。
だから私は問題がどこから来ているのかを理解しようとしています。ダンプされたスタックを確認すると、一致するコードが見つかりません。からの障害vmalloc()
は、によって行われsys_init_module()
ているようinit_module()
ですkernel/module.c
。しかし、コードは一致しません。からオブジェクトコードを確認する.ko
と、init_module()
コードも一致しません。
カーネルを十分に理解していないため、多かれ少なかれブロックされており、すべてのビルドシステムとモジュールのロードを理解するのは非常に困難です。一部の関数が欠落していると思われるため、モジュールがロードされる前にエラーが発生insmod
し、この時点ではこれらのエラーは報告されません。