加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

将模块移植到较新的Linux内核:无法分配内存

发布时间:2020-12-14 01:11:10 所属栏目:Linux 来源:网络整理
导读:我有一个非常大的驱动程序模块,我正在尝试编译最近的 Linux内核(3.4.4).我可以使用2.6.27.25内核成功编译和insmod相同的模块. GCC版本也不同,4.7.0对4.3.0.请注意,此模块非常复杂,我不能简单地浏览所有代码和所有makefile. 当“插入”模块时,我得到一个无法
我有一个非常大的驱动程序模块,我正在尝试编译最近的 Linux内核(3.4.4).我可以使用2.6.27.25内核成功编译和insmod相同的模块.
GCC版本也不同,4.7.0对4.3.0.请注意,此模块非常复杂,我不能简单地浏览所有代码和所有makefile.

当“插入”模块时,我得到一个无法使用以下跟踪分配内存:

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,000 KB的vmalloc(),但是对于旧内核,lsmod给我的大小为4,800 KB.这些数字应该直接相关吗?是否有可能在构建过程中出现问题并且要求RAM太多?当我编译两个.ko的部分大小时,我没有看到很大的差异.

所以我试图了解问题的来源.当我检查转储堆栈时,我无法找到匹配的代码段.似乎错误的vmalloc()是由sys_init_module()完成的,它是来自kernel / module.c的init_module().但代码不匹配.当我从.ko检查目标代码时,init_module()代码也不匹配.

我或多或少被阻止,因为我不太了解内核,并且所有构建系统和模块加载都很难理解.在加载模块之前发生错误,因为我怀疑某些功能缺失,而insmod此时不会报告这些错误.

解决方法

我相信分配是在 layout_and_allocate完成的,由load_module调用.两者都是静态函数,因此它们可能是内联的,因此不在堆栈中.
所以它不是由您的代码完成的分配,而是由Linux完成的分配以加载您的代码.

如果你的旧内核是4.8MB而新的内核是30MB,它可以解释它失败的原因.
所以问题是为什么它如此之大.

大小可能是由于代码量(不太可能增长太多)或静态分配的数据.
一个可能的解释是你有一个大的静态分配数组,其大小在Linux中定义.如果大小显着增加,您的阵列将会增长.
猜测 – 一个大小为NR_CPUS的数组.

您应该能够使用诸如nm或objdump之类的命令来查找这样的数组.但是我不知道究竟是怎么做到的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读