本文介绍 Linux 内核内存分配函数devm_kmalloc()
和devm_kzalloc()
。
一、devm_kmalloc
文件:drivers/base/devres.c
,定义如下:
void * devm_kmalloc(struct device *dev, size_t size, gfp_t gfp)
{
struct devres *dr;
dr = alloc_dr(devm_kmalloc_release, size, gfp, dev_to_node(dev));
...
set_node_dbginfo(&dr->node, "devm_kzalloc_release", size);
devres_add(dev, dr->data);
return dr->data;
}
devm_kmalloc()
函数通过alloc_dr()
申请设备资源,alloc_dr()
调用流程如下:
alloc_dr()->
kmalloc_node_track_caller()->
kmalloc_track_caller()->
__kmalloc_track_caller()->
__do_kmalloc()
然后通过devres_add()
添加到设备资源列表中。
后续在设备资源管理(device resourcce management
)中详细介绍。
二、devm_kzalloc
文件:include/linux/device.h
,定义如下:
static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
{
return devm_kmalloc(dev, size, gfp | __GFP_ZERO);
}
devm_kzalloc()
函数使用的参数和返回值同devm_kmalloc()
。区别:内存分配成功后清零。
注:
1)devm_kmalloc()
和devm_kzalloc()
是具有资源管理的kmalloc()
和kzalloc()
。与所属设备关联,在probe
函数中使用。当设备驱动被卸载时,该内存被自动释放,也可使用devm_kfree()
函数直接释放。
2)kmalloc()
和kzalloc()
申请的内存必须调用kfree()
释放。
三、devm_kfree
文件:drivers/base/devres.c
,定义如下:
void devm_kfree(struct device *dev, void *p)
{
int rc;
rc = devres_destroy(dev, devm_kmalloc_release, devm_kmalloc_match, p);
WARN_ON(rc);
}
总结
函数devm_kmalloc()和devm_kzalloc()对比kzalloc()一样都是内核内存分配函数,但是devm_kzalloc()是跟设备有关的,当设备驱动程序卸载时,内存会被自动释放。另外,当内存不在使用时,可以使用函数devm_kfree()释放。
而kzalloc()则需要手动释放(使用kfree(),但如果工程师检查不仔细,则有可能造成内存泄漏。也就是在驱动的探针函数中调用devm_kzalloc(),在除去函数中调用devm_kfree()函数
函数devm_kmalloc()和devm_kzalloc()区别在于devm_kzalloc在分配成功会自动清零