【问题标题】:What is the difference between devm_kzalloc() and kzalloc() in linux driver programminglinux驱动程序编程中的devm_kzalloc()和kzalloc()有什么区别
【发布时间】:2012-09-04 04:51:27
【问题描述】:

我在设备驱动程序编程中找到了devm_kzalloc()kzalloc()。但我不知道何时/何地使用这些功能。任何人都可以指定这些功能的重要性及其用法。

【问题讨论】:

  • 嗨,如果我们使用 devm_kzalloc() 则无需释放此内存(参考:link)。那么我们是否可以将程序中的所有 kzalloc() 函数替换为 devm_kzalloc() ,因为我们可以减少释放动态分配的内存的负担..?
  • 我相信devres.txt 会回答大多数问题。 'devres.txt' 应该是您的 Linux 版本(从 2.6.31+ 开始)的最新版本。
  • 没有。您不能用托管类似物替换 所有 分配,因为必须仔细考虑对象的生命周期。

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


【解决方案1】:

kzalloc()kmalloc() 一样分配内核内存,但它也会对分配的内存进行零初始化。 devm_kzalloc() 被管理 kzalloc()。分配有托管功能的内存与设备相关联。当设备与系统分离或设备驱动程序被卸载时,该内存将自动释放。如果为设备分配了多个托管资源(内存或其他资源),则最后分配的资源首先被释放。

托管资源对于确保驱动程序的正确运行非常有帮助,无论是在任何时候初始化失败,还是成功初始化,然后删除设备。

请注意,托管资源(无论是内存还是其他一些资源)旨在用于负责探测设备的代码。它们通常是用于打开设备的代码的错误选择,因为设备可以在不与系统断开连接的情况下关闭。关闭设备需要手动释放资源,这违背了托管资源的目的。

kzalloc() 分配的内存应该用kfree() 释放。使用devm_kzalloc() 分配的内存会自动释放。它可以通过devm_kfree() 释放,但这通常表明托管内存分配不适合该任务。

【讨论】:

  • 值得一提的是,托管资源的用例是->probe() 或类似的回调。在像->open() 这样的回调中使用它们会很糟糕,坏主意。在使用文件操作的情况下,对象的生命周期也存在问题。
  • 我已经扩展了我的回复以提及它,谢谢。如果有其他原因避免在 open() 中使用托管资源,请发布链接。
【解决方案2】:

简而言之,devm_kzalloc() 和 kzalloc() 都用于设备驱动程序中的内存分配,但不同之处在于,如果您通过 kzalloc() 分配内存,而不是在设备驱动程序的生命周期为结束或当它从内核中卸载时,但如果您对 devm_kzalloc() 执行相同操作,则无需担心释放内存,设备库本身会自动释放该内存。

它们都做了完全相同的事情,但是通过使用 devm_kzalloc,程序员释放内存的开销很小

举个例子来解释一下,第一个例子是使用kzalloc

static int pxa3xx_u2d_probe(struct platform_device *pdev)
{
    int err;
    u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL);     1
    if (!u2d)
         return -ENOMEM;
    u2d->clk = clk_get(&pdev->dev, NULL);
    if (IS_ERR(u2d->clk)) {
        err = PTR_ERR(u2d->clk);                                    2
        goto err_free_mem;
    }
...
    return 0;
err_free_mem:
    kfree(u2d);
    return err;
}
static int pxa3xx_u2d_remove(struct platform_device *pdev)
{
    clk_put(u2d->clk);               
    kfree(u2d);                                                     3
    return 0;
}

在此示例中,您可以在函数 pxa3xx_u2d_remove() 中执行此操作, kfree(u2d)(由 3 指示的行)用于释放 u2d 分配的内存 现在使用 devm_kzalloc() 查看相同的代码

static int pxa3xx_u2d_probe(struct platform_device *pdev)
{
    int err;
    u2d = devm_kzalloc(&pdev->dev, sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL);
    if (!u2d)
        return -ENOMEM;
    u2d->clk = clk_get(&pdev->dev, NULL);
    if (IS_ERR(u2d->clk)) {
         err = PTR_ERR(u2d->clk);
         goto err_free_mem;
    }
...
    return 0;
err_free_mem:
    return err;
}
static int pxa3xx_u2d_remove(struct platform_device *pdev)
{
    clk_put(u2d->clk);
    return 0;
}

没有 kfree() 来释放函数,因为 devm_kzalloc() 也是如此

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-29
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多