我在设备驱动程序中发现了devm_kzalloc()
和kzalloc()
,但我不知道何时/在哪里使用这些函数。请问有人能够说明这些函数的重要性和用法吗?
我在设备驱动程序中发现了devm_kzalloc()
和kzalloc()
,但我不知道何时/在哪里使用这些函数。请问有人能够说明这些函数的重要性和用法吗?
kzalloc()
分配内核内存,类似于kmalloc()
,但它也将分配的内存置零。 devm_kzalloc()
是管理kzalloc()
的函数。使用管理函数分配的内存与设备相关联。当设备从系统中分离或设备的驱动程序卸载时,该内存会自动释放。如果为设备分配了多个管理资源(内存或其他资源),则最后分配的资源最先释放。
管理资源对于确保驱动程序在任何点初始化失败和成功初始化后设备移除的正确操作非常有帮助。
请注意,管理资源(无论是内存还是其他资源)应用于负责探测设备的代码中。通常不应用于用于打开设备的代码,因为设备可以在未断开连接的情况下关闭。关闭设备需要手动释放资源,这违反了管理资源的目的。
使用kzalloc()
分配的内存应通过kfree()
释放。使用devm_kzalloc()
分配的内存会自动释放。虽然可以使用devm_kfree()
释放此内存,但这通常意味着管理内存分配不适合当前任务。
->probe()
或类似的回调函数。在像 ->open()
这样的回调函数中使用它们是一个非常糟糕的想法。此外,在文件操作中存在对象生命周期的问题。 - 0andriystatic 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;
}