22

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

4

2 回答 2

49

kzalloc() allocates kernel memory like kmalloc(), but it also zero-initializes the allocated memory. devm_kzalloc() is managed kzalloc(). The memory allocated with managed functions is associated with the device. When the device is detached from the system or the driver for the device is unloaded, that memory is freed automatically. If multiple managed resources (memory or some other resource) were allocated for the device, the resource allocated last is freed first.

Managed resources are very helpful to ensure correct operation of the driver both for initialization failure at any point and for successful initialization followed by the device removal.

Please note that managed resources (whether it's memory or some other resource) are meant to be used in code responsible for the probing the device. They are generally a wrong choice for the code used for opening the device, as the device can be closed without being disconnected from the system. Closing the device requires freeing the resources manually, which defeats the purpose of managed resources.

The memory allocated with kzalloc() should be freed with kfree(). The memory allocated with devm_kzalloc() is freed automatically. It can be freed with devm_kfree(), but it's usually a sign that the managed memory allocation is not a good fit for the task.

于 2014-02-28T02:07:07.257 回答
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() 也是如此

于 2016-11-01T19:59:15.890 回答