【问题标题】:kmalloc many struct, should I kmalloc them all at a time or respectivelykmalloc 许多结构,我应该一次或分别对它们进行kmalloc
【发布时间】:2017-02-17 21:26:48
【问题描述】:

我正在阅读设备驱动程序的源代码。

它尝试 kmalloc 16 struct foo

spin_lock_bh(&sq->lock);
for (i=0; i<16; i++) {
        msg = kmalloc(sizeof(*msg), GFP_ATOMIC);
        if (!msg)
                break;
        msg->next = sq->msg_first;
        sq->msg_first = msg; 
        sq->nr_msgs++;
}    
spin_unlock_bh(&sq->lock);

那么,kmalloc(sizeof(*msg) * 16, GFP_ATOMIC) 会更好吗?为什么?

【问题讨论】:

  • 这是来自工作设备驱动程序的真正源代码吗?对lock 进行了锁定,但是随后对另一个spinlock_t 变量sq-&gt;avmi_lock 进行了解锁。这看起来不正确。
  • would it be better ... - 这在很大程度上取决于您的需求。实际上,您正在为消息选择容器类型list(每个元素分配,每个元素都需要包含到下一个元素的链接)或array / vector(所有元素一次分配,任何元素都可以通过整数索引访问)。

标签: c memory linux-kernel kernel linux-device-driver


【解决方案1】:

如果没有看到源代码,很难说出任何确定的东西。以这种方式进行内存分配的基本原理可能与我们在这里提出的任何方法大不相同。

一个合理的理由可能是这样。如您所见,分配的项目在单链表中链接在一起。这可能只是一个初始项目池,可以随着驱动程序的运行而扩展或缩短。初始池中的某些项目可能会在以后被删除和释放。如果您要在一次分配中分配此内存,您将无法做到这一点。由于项目被链接到一个链表中,我认为这不会像Tsyvarev 建议的那样用作数组。

我必须说,理由往往可以用一个词来描述:因为。因为代码的作者认为这样做更方便,或更清晰等等。不幸的是,这种情况一直都在发生。只要这些地方不重要(即不在热门路径中),就可以了。你无法解决所有问题。

编辑
正如下面的回复中所指出的,分配是最多 16 个项目。这可能是一个深思熟虑的设计决定。如果分配在某个时候失败,它就会跳出分配循环,在 16 个项目中分配尽可能多的项目。这实际上符合这些项目可能构成初始池的想法最多 16 项。

【讨论】:

  • “因为”也称为“设计选择”。
  • 当然。只是那些设计选择很少在代码中注释掉。
【解决方案2】:

此代码尝试将 up 分配给 16 个struct foos。但是如果没有足够的内存,它仍然会分配一些。您建议的更改是尝试分配 16 struct foos,如果您不能这样做,则失败。如果只有部分分配空间怎么办?

此外,分配器在一次分配时必须找到一个连续的内存区域,而在多次分配时它可以处理碎片化的内存。

【讨论】:

    猜你喜欢
    • 2011-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    相关资源
    最近更新 更多