【问题标题】:Is there a size limit for kernel module in linux?linux中的内核模块有大小限制吗?
【发布时间】:2011-09-12 11:13:07
【问题描述】:

我在加载内核模块时遇到问题,有一个大数据结构,大约 2Gb 的内存大小 - 我是否预先分配表(以便在我执行 size -A module.ko 或尝试 @ 时它显示在 .bss 中987654322@它在加载时,模块加载失败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 在 uml 中用 4G 内存尝试过这个,所以这应该 是一个普通的内存不足问题。

解决限制的额外功劳,如果存在这样的限制:)

【问题讨论】:

  • 2GB代码+数据段?你开玩笑的吧!你不能只mmap你的数据而不编译它吗?
  • 很遗憾,我没有骗你。

标签: linux-kernel kernel-module vmalloc


【解决方案1】:

请记住,内核空间内存与用户空间内存不同——在 32 位 Linux 上,内核只有 1Gb 地址空间。在 64 位 Linux 上,内核有一个 log 更多的空间地址空间,但kernel documentation 建议只有 1536MB 可用于模块。

【讨论】:

  • 在 64 位上,基本上没有地址空间限制(嗯,限制是很多 TB)。
  • 对于 x86-64,内核空间中内存区域的简要描述可能会有所帮助:Documentation/x86/x86_64/mm.txt。可以从那里推断出上限,尽管实际的限制当然可以更低。
  • 如果我做一个动态的vmalloc(),似乎我可以得到尽可能多的内存(并且可用) - 请参阅我的测试代码paste.pocoo.org/show/406020
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    所以回答我的问题:

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

    额外的功劳:只需vmalloc()

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-21
      • 2012-04-11
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多