【问题标题】:kzalloc() - Maxmum size at a single call?kzalloc() - 一次调用的最大大小?
【发布时间】:2012-08-19 03:34:00
【问题描述】:

我们可以在一次调用中使用 kzalloc() 分配的最大大小是多少?

这是一个非常常见的问题。如果我可以验证该值,请告诉我。

【问题讨论】:

    标签: memory-management linux-kernel kernel


    【解决方案1】:

    上限(可以在单个 kmalloc / kzalloc 请求中分配的字节数)是以下函数: 处理器——实际上是页面大小——和 好友系统空闲列表的数量 (MAX_ORDER)。

    在 x86 和 ARM 上,标准页面大小为 4 Kb,MAX_ORDER 为 11,单次调用的 kmalloc 上限为 4 MB!

    详细信息,包括解释和测试代码,在这里: http://kaiwantech.wordpress.com/2011/08/17/kmalloc-and-vmalloc-linux-kernel-memory-allocation-api-limits/

    【讨论】:

    • 一个你没有提到的警告:随着时间的推移,可用的物理内存可能会变得“碎片化”。 IE。可能有 4Mb 或更多可用内存,但如果没有 4Mb 的 连续 可用内存,kmalloc() 无法满足 4Mb 的分配。从历史上看,这是一个大问题。我不知道当前的建议是什么……我读到的最新消息是系统管理员对现代服务器上 64Kb 的 kmalloc()-or-equiv 故障进行故障排除。 utcc.utoronto.ca/~cks/space/blog/linux/2012/06/16
    【解决方案2】:

    与 kmalloc() 没有什么不同。这是您应该问(或搜索)的问题,因为 kzalloc 只是一个设置 GFP_ZERO 的薄包装器。

    最多大约 PAGE_SIZE(至少 4k)没问题:p。除此之外......你说得对,很多人都问过,这绝对是你必须考虑的事情。显然它取决于内核版本 - 曾经有一个硬性 128k 限制,但现在已经增加(或者可能完全放弃)。不过,这只是硬性限制,您实际可以获得的内容取决于给定的系统。 (而且非常肯定在内核版本上)。

    也许读What is the difference between vmalloc and kmalloc?

    您始终可以通过检查 kzalloc() 的返回值来“验证”分配,但到那时您可能已经记录了分配失败的回溯。除此之外,不 - 我认为没有提前检查的好方法。

    【讨论】:

    • linux中有没有类似kzalloc_try()的调用
    • 我想说不。如果您想避免回溯,似乎确实有一个 GFP_NOWARN 标志。但是如果你想把你的代码放到主线内核中……希望被告知离开并重写它。听起来您需要阅读 LDD3 - 第 8 章涵盖了基本的内存分配。 lwn.net/Kernel/LDD3 足够老了,它甚至没有提到 kzalloc(),但我认为它真的会帮助你理解。 (可能有更近期的书籍可以付费购买)。
    【解决方案3】:

    但是,这取决于您的内核版本和配置。这些限制通常位于 linux/slab.h 中,通常描述如下(本示例在 linux 2.6.32 下):

    #define KMALLOC_SHIFT_HIGH  ((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
                                 (MAX_ORDER + PAGE_SHIFT - 1) : 25)
    #define KMALLOC_MAX_SIZE    (1UL << KMALLOC_SHIFT_HIGH)
    #define KMALLOC_MAX_ORDER   (KMALLOC_SHIFT_HIGH - PAGE_SHIFT)
    

    您可以使用以下代码对其进行测试:

    #include <linux/module.h>
    #include <linux/slab.h>
    int init_module()
    {
    
        printk(KERN_INFO "KMALLOC_SHILFT_LOW:%d, KMALLOC_SHILFT_HIGH:%d, KMALLOC_MIN_SIZE:%d, KMALLOC_MAX_SIZE:%lu\n",
                KMALLOC_SHIFT_LOW,  KMALLOC_SHIFT_HIGH, KMALLOC_MIN_SIZE, KMALLOC_MAX_SIZE);
        return 0;
    }
    
    void cleanup_module()
    {
        return;
    }
    

    最后在linux 2.6.32 32bits下的结果是:3、22、8、4194304,表示最小大小为8字节,最大大小为4MB。

    PS。 你也可以查看kmalloc分配的内存的实际大小,只需要使用ksize(),即

    void *p = kmalloc(15, GFP_KERNEL);
    printk(KERN_INFO "%u\n", ksize(p)); /* this will print "16" under my kernel */
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-11
      • 1970-01-01
      • 1970-01-01
      • 2014-12-03
      • 2021-08-14
      • 2015-10-24
      • 2015-12-29
      • 2017-12-27
      相关资源
      最近更新 更多