linux内核内存申请函数:devm_kzalloc函数的实现进行解析
struct regmap_device *regmap_device_register//寄存器设备驱动注册(struct regmap_properties *props,struct regmap_fops *rops,struct device *parent,void *client, void *drvdata)
{struct regmap_device *rd;int ret = 0, i;char device_name[32];unsigned char data;pr_info("regmap_device_register: name = %s\n", props->name);rd = devm_kzalloc(parent, sizeof(*rd), GFP_KERNEL);//向内核申请内存:devm_kzalloc() 是具有资源管理的 kzalloc()。使用资源管理(resource-managed)函数分配的内存,是会与所属设备相关联。当设备从系统中分离或者设备驱动被卸载,该内存会被自动释放。if (!rd) {pr_info("regmap_device memory allocate fail\n");return NULL;}
.
.
.}
设备注册函数过程一般会用到内存申请,如上。下面我们参考资料分析一下过程。
///
前言
Linux Kernel devm_* API源码分析
本文通过对devm_kzalloc函数的实现进行解析,帮助理解devm系列api的用法。
devm系列api的主要特别之处:
使用devm系列申请到的资源可以由系统自动释放,解放双手
一、devm_kzalloc & devm_kfree代码
struct devres {
struct devres_node node;
/* -- 3 pointers */
unsigned long long data[]; /* guarantee ull alignment */
};
struct devres_node {
struct list_head entry;
dr_release_t release;
#ifdef CONFIG_DEBUG_DEVRES
const char *name;
size_t size;
#endif
};
void * devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
{
struct devres *dr;
/* use raw alloc_dr for kmalloc caller tracing */
dr = alloc_dr(devm_kzalloc_release, size, gfp);
if (unlikely(!dr))
return NULL;
set_node_dbginfo(&dr->node, "devm_kzalloc_release", size);
devres_add(dev, dr->data);
return dr->data;
}
static __always_inline struct devres * alloc_dr(dr_release_t release,
size_t size, gfp_t gfp)
{
size_t tot_size = sizeof(struct devres) + size;
struct devres *dr;
dr = kmalloc_track_caller(tot_size, gfp);
if (unlikely(!dr))
return NULL;
memset(dr, 0, tot_size);
INIT_LIST_HEAD(&dr->node.entry);
dr->node.release = release;
return dr;
}
/*alloc_dr函数负责分配内存,返回的devres就包含分配到的内存,通过devres.data来访问即可.
devres_add(dev, dr->data);函数将数据与device进行绑定,实际调用add_dr,在这里将资源的节点头添加到device的devres_head链表中*/
/**
* devres_add - Register device resource
* @dev: Device to add resource to
* @res: Resource to register
*
* Register devres @res to @dev. @res should have been allocated
* using devres_alloc(). On driver detach, the associated release
* function will be invoked and devres will be freed automatically.
*/
void devres_add(struct device *dev, void *res)
{
struct devres *dr = container_of(res, struct devres, data);
unsigned long flags;
spin_lock_irqsave(&dev->devres_lock, flags);
add_dr(dev, &dr->node);
spin_unlock_irqrestore(&dev->devres_lock, flags);
}
static void add_dr(struct device *dev, struct devres_node *node)
{
devres_log(dev, node, "ADD");
BUG_ON(!list_empty(&node->entry));
list_add_tail(&node->entry, &dev->devres_head);
}
/*现在资源与dev的绑定已经完成,下面就找一找是如何释放资源的.
device_release_driver -> devres_release_all->release_nodes*/
static int release_nodes(struct device *dev, struct list_head *first,
struct list_head *end, unsigned long flags)
__releases(&dev->devres_lock)
{
LIST_HEAD(todo);
int cnt;
struct devres *dr, *tmp;
cnt = remove_nodes(dev, first, end, &todo);
spin_unlock_irqrestore(&dev->devres_lock, flags);
/* Release. Note that both devres and devres_group are
* handled as devres in the following loop. This is safe.
*/
list_for_each_entry_safe_reverse(dr, tmp, &todo, node.entry) {
devres_log(dev, &dr->node, "REL");
dr->node.release(dev, dr->data);
kfree(dr);
}
return cnt;
}
二、资源释放
kzalloc()实现了kmalloc()+memset()的功能,而 devm_kzalloc() 是具有资源管理的 kzalloc()。使用资源管理(resource-managed)函数分配的内存,是会与所属设备相关联。当设备从系统中分离或者设备驱动被卸载,该内存会被自动释放。也可以通过devm_kfree()来释放内存。
static inline void *kzalloc(size_t size, gfp_t flags)
{
return kmalloc(size, flags | __GFP_ZERO);
}
linux内核内存申请函数:devm_kzalloc函数的实现进行解析相关推荐
- linux 内核 内存申请函数 kmalloc、kzalloc、vmalloc 区别
我们都知道在用户空间动态申请内存用的函数是 malloc(),这个函数在各种操作系统上的使用是一致的,对应的用户空间内存释放函数是 free().注意:动态申请的内存使用完后必须要释放,否则会造成内存 ...
- linux内核函数kmalloc,Linux内核内存分配函数之devm_kmalloc和devm_kzalloc
本文介绍Linux内核内存分配函数devm_kmalloc()和devm_kzalloc(). 一.devm_kmalloc 文件:drivers/base/devres.c,定义如下: /** * ...
- 【Linux 内核 内存管理】memblock 分配器编程接口 ⑤ ( memblock_free 函数 | memblock_remove_range 函数 )
文章目录 一.memblock_free 函数分析 二.memblock_remove_range 函数分析 memblock 分配器提供了如下编程接口 : ① 添加内存 : memblock_add ...
- Linux内核多线程实现方法 —— kthread_create函数
Linux内核多线程实现方法 -- kthread_create函数 内核经常需要在后台执行一些操作,这种任务就可以通过内核线程(kernle thread)完成独立运行在内核空间的标准进 ...
- 【Linux 内核 内存管理】内存管理架构 ④ ( 内存分配系统调用过程 | 用户层 malloc free | 系统调用层 brk mmap | 内核层 kmalloc | 内存管理流程 )
文章目录 一.内存分配系统调用过程 ( 用户层 | 系统调用 | 内核层 ) 二.内存管理流程 一.内存分配系统调用过程 ( 用户层 | 系统调用 | 内核层 ) " 堆内存 " ...
- 【Linux 内核 内存管理】内存管理架构 ② ( 用户空间内存管理 | malloc | ptmalloc | 内核空间内存管理 | sys_brk | sys_mmap | sys_munmap)
文章目录 一.用户空间内存管理 ( malloc / free / ptmalloc / jemalloc / tcmalloc ) 二.内核空间内存管理 1.内核内存管理系统调用 ( sys_brk ...
- 【Linux 内核 内存管理】RCU 机制 ② ( RCU 机制适用场景 | RCU 机制特点 | 使用 RCU 机制保护链表 )
文章目录 一.RCU 机制适用场景 二.RCU 机制特点 三.使用 RCU 机制保护链表 一.RCU 机制适用场景 在上一篇博客 [Linux 内核 内存管理]RCU 机制 ① ( RCU 机制简介 ...
- 【Linux 内核 内存管理】物理分配页 ⑨ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | retry 标号代码分析 )
文章目录 一.retry 标号代码分析 二.retry 标号完整代码 在 [Linux 内核 内存管理]物理分配页 ② ( __alloc_pages_nodemask 函数参数分析 | __allo ...
- 【Linux 内核 内存管理】物理分配页 ⑦ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | 判断页阶数 | 读取 mems_allowed | 分配标志位转换 )
文章目录 一.__alloc_pages_slowpath 慢速路径调用函数 二.判断页阶数 三.读取进程 mems_allowed 成员 四.分配标志位转换 五.__alloc_pages_slow ...
最新文章
- Linux中文件上传使用rz
- 最大公约数 数学,结论 第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛
- 项目war包部署到第三方Tomcat,访问路径必须加上项目名称的坑
- 寻找下一款Prisma APP:深度学习在图像处理中的应用探讨
- 为什么TCP连接至少3次握手
- c++:json字符串拼接,json对象组装
- leetcode题解(二叉树和递归问题)
- 关于《精通Unix下C语言编程与项目实践》的试读策划
- css ios动画,我的CSS动画未在iOS的
- spring boot controller 初始化_使用 Spring 快速创建 web 应用的两种方式
- sunplus8202v 无线游戏手柄——续
- 域控查看ldap端口命令_LDAP基础安装与简单入门使用
- 旋转矩阵与欧拉角的相互转换及代码
- HDU 5183 Negative and Positive (NP) (hashmap+YY)
- exsi添加gpu卡 v100s和a100 配置直通模式虚机电源启动失败
- NPOI 操作word 创建页眉页脚,页眉中插入图片
- 人民币对美元汇率中间价报6.7802元 上调167个基点
- 订阅技术类型的公众号 究竟是为了什么?
- 数据结构测试题——树和二叉树(一)
- 母亲节板报图片计算机方案,母亲节电子手抄报图片素材
热门文章
- 回溯法求解旅行商问题
- java工作描述_java工程师工作描述状况是干什么的?需要身怀哪些技能呢?
- 001-STM32+BC26/260Y基本控制篇(自建物联网平台)--基础知识-MQTT协议
- Ubuntu 快速 安装 Nginx + 配置文件
- C语言使用函数交换两个数的值
- IDEA中Maven项目打包方式
- RabbitMq 测试报错channel error(reply-code=405
- HarmonyOS实战经验合集之ArkUI(一)
- CSS轮播图中小圆点的定位问题
- Impinj英频杰超高频Indy R2000开发资料代码