9

我在加载内核模块时遇到问题,有一个大数据结构,大约 2Gb 的内存大小 - 无论是我预分配表(以便它在我这样做时显示在 .bss 中,还是在加载时size -A module.ko尝试它,模块vmalloc()加载失败,出现insmod: error inserting 'module.ko': -1 Cannot allocate memory.

我尝试在用户模式 ​​linux 上调试问题,但我得到了一堆段错误(可以在 gdb 中继续,但最终会出现控制台消息overflow in relocation type 10 val <value in the ball park of 6G>'module' likely not compiled with -mcmodel=kernel. 我认为应该是正确的,对吧Kbuild-mcmodel

所以问题是:

  1. Linux内核模块大小是否有通用的2G限制?
  2. usernode linux中的内核模块是否有特定的2G限制(我认为过去我注意到大型内核模块需要干净,连续的内存块......)
  3. 我可以指定-mcmodel=large一个内核模块并期望它工作吗?

我已经在 64 位、2.6.32-5-amd64(主机)和 8Gb 内存和 2.6.32 in uml 和 4G 内存的 64 位 2.6.32-5-amd64(主机)上尝试过这个,所以这应该是一个普通的内存不足问题。

如果存在这样的限制,则可以在限制范围内工作的额外信用:)

4

3 回答 3

8

至于您的第一个问题 - 模块本身的限制是 64 兆字节。模块加载器将拒绝加载超过此大小的模块。从kernel/module.c

if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
        return ERR_PTR(-ENOMEM);

这对于 2.6.32 和较新的内核(最高 3.3)都是如此。

编辑:在内核版本 3.4 中,删除了 64 Mb 限制。现在实际限制仅取决于vmalloc()可以分配多少内存。

于 2011-06-11T04:33:06.587 回答
1

请记住,内核空间内存与用户空间内存不同——在 32 位 Linux 上,内核只有 1Gb 地址空间。在 64 位 Linux 上,内核有更多的日志空间地址空间,但内核文档表明只有 1536MB 可用于模块。

于 2011-06-10T16:55:26.023 回答
0

如果我将表定义为static- 模块加载确实会失败 - 这可能是因为Andrew Aylett的答案中提到的 1.5G 限制

但是,如果我进行动态vmalloc()调用,我能够在具有 8Gb 内存的主机上获得高达 7680Mb 的内存(直到内核杀死了一些关键进程并且我的 X 挂起)。

所以回答我的问题:

  1. 是的,但仅适用于编译为static
  2. 看起来不像。
  3. 没有必要这样做。

额外的信用:只是做vmalloc()

这仅适用于2.6.10之后的 linux 内核- 在此之前,vmalloc() 限制为 64 Mb。

于 2011-06-14T07:07:10.177 回答