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

时间:2011-06-10 12:13:38

标签: linux-kernel kernel-module vmalloc

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

我尝试在usermode linux上调试问题,但是我得到了一堆segfaults(可以在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限制(我认为过去我注意到大型内核模块需要一个干净,连续的内存块...)< / LI>
  3. 我可以为内核模块指定-mcmodel=large并期望它能够正常工作吗?
  4. 我已经尝试过debian squeeze,64位,2.6.32-5-amd64(主机),内存为8Gb,内存为2.6.32,内存为4G,所以这应该是一个普通的内存不足问题。

    如果存在此类限制,则可以额外获得限制:

3 个答案:

答案 0 :(得分:7)

至于你的第一个问题 - 模块本身的限制是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()可以分配的内存量。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

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

所以回答我的问题:

  1. 是的,但仅适用于以static
  2. 编译的数据
  3. 看起来不像。
  4. 没有必要这样做。
  5. 额外信用:只需vmalloc()

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