Linux中的内核模块是否有大小限制?

问题描述:

我有一个加载内核模块的问题,有一个大的数据结构,大小2Gb的内存 - 我是否预先分配表(以便它在.bss中显示,当我做size -A module.ko或尝试vmalloc()它在加载时间,模块加载失败insmod: error inserting 'module.ko': -1 Cannot allocate memoryLinux中的内核模块是否有大小限制?

我试图调试在用户模式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. 是否有特定的2G限制在usernode Linux内核模块(我认为,在过去,我注意到一个较大的内核模块需要的内存干净的,连续的块...)
  3. 我可以指定-mcmodel=large为内核模块,并期望它的工作?

我已经试过这Debian的挤压,64位,2.6.32-5-AMD64(主机),8GB内存和2.6.32与4G内存UML,所以这应该是一个普通的内存不足问题。

周边的极限工作,如果这样的极限存在:)

+0

2GB代码+数据段?你开玩笑的吧!你不能只是''映射你的数据,而不是编译它? – 2011-06-10 12:20:43

+0

不幸的是,我没有骗你。 – Kimvais 2011-06-10 12:25:08

如果我定义表为static - 模块加载确实会失败 - 这可能是因为通过Andrew Aylett

在回答中提到的1.5G极限但是,如果我这样做动态vmalloc()电话,我能在具有8Gb内存的主机上启动7680Mb(直到内核杀死了一些关键进程和我的X挂机)。

因此,要回答我的问题:

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

附加题:只是做vmalloc()

这仅适用于Linux内核比2.6.10更新 - 在此之前,vmalloc()limit was 64 Mb.

请记住,内核空间内存附加题是从用户存储空间的不同 - 在32位Linux,内核只有1GB地址空间。在64位Linux上,内核有更多的空间地址空间,但kernel documentation表明只有1536MB可用于模块。

+0

在64位上,基本上没有地址空间限制(很好,限制是很多TB)。 – Roland 2011-06-10 18:16:03

+0

至于x86-64,内核空间中对内存区域的简要描述可能有所帮助:[Documentation/x86/x86_64/mm.txt](http://www.mjmwired.net/kernel/Documentation/x86/x86_64 /mm.txt)。上限可以从那里推导出来,但当然实际限值可能会更低。 – Eugene 2011-06-11 04:38:30

+0

谢谢,@Eugene:我已经更新了我的答案。 – 2011-06-11 20:21:05

至于你的第一个问题 - 模块本身的限制是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限制was removed。现在实际的限制仅取决于多少内存vmalloc()可以分配。