本文介紹 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在分配成功會自動清零
