我在设备驱动程序编程中找到了devm_kzalloc()
和kzalloc()
。但我不知道何时/何地使用这些功能。任何人都可以请说明这些功能的重要性及其用法。
答案 0 :(得分:28)
kzalloc()
分配内核内存,如kmalloc()
,但它也会对分配的内存进行零初始化。管理devm_kzalloc()
kzalloc()
。分配有托管功能的内存与设备关联。当设备与系统分离或卸载设备的驱动程序时,将自动释放该内存。如果为设备分配了多个受管资源(内存或其他资源),则首先释放最后分配的资源。
托管资源对于确保驱动程序在任何时候初始化失败以及设备删除后成功初始化都能正确运行非常有用。
请注意,托管资源(无论是内存还是其他资源)都应在负责探测设备的代码中使用。对于用于打开设备的代码,它们通常是错误的选择,因为设备可以在不与系统断开的情况下关闭。关闭设备需要手动释放资源,这会破坏托管资源的目的。
分配有kzalloc()
的内存应使用kfree()
释放。分配有devm_kzalloc()
的内存将自动释放。它可以通过devm_kfree()
释放,但通常表明托管内存分配不适合该任务。
答案 1 :(得分:1)
简单来说,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()
也是如此