内核对象kobject和sysfs(2)——kref分析
内核对象kobject和sysfs(2)——kref分析
在介绍ref之前,先贴上kref的结构:
struct kref {
atomic_t refcount;
};
可以看到,kref只是包含一个原子量的数而已,并没有别的成员提供自动回收的功能。实际上,kref只是记录了某个模块的引用次数,初始状态为1.当引用计数为0的时候,将调用自定义的释放函数。
下面我们介绍内核提供的kref的操作函数:
kref初始化函数kref_init:
static inline void kref_init(struct kref *kref)
{
atomic_set(&kref->refcount, 1);
}
从函数原型可以看到,实际上kref初始化的时候就被初始化为1了,kref
kref的增加引用的函数kref_get:
static inline void kref_get(struct kref *kref)
{
/* If refcount was 0 before incrementing then we have a race
* condition when this kref is freeing by some other thread right now.
* In this case one should use kref_get_unless_zero()
*/
WARN_ON_ONCE(atomic_inc_return(&kref->refcount) < 2);
}
由于初始化已经是1,所以即使是第一次增加引用,引用计数也不会小于2,如果小于了2,则说明程序出了问题,将给出一个警告。
kref的释放引用的函数:
static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref))
{
return kref_sub(kref, 1, release);
}
static inline int kref_sub(struct kref *kref, unsigned int count,
void (*release)(struct kref *kref))
{
WARN_ON(release == NULL);
if (atomic_sub_and_test((int) count, &kref->refcount)) {
release(kref);
return 1;
}
return 0;
}
可以看到,释放函数,有两个参数,其中一个是kref,另外一个是一个函数指针。这个函数,则是自定义的释放函数。在kref_sub函数内,当条件满足,将会调用自定义的release函数。
atomic_sub_and_test函数kref减去count,如果结果是0,则返回真,否则,返回假。
对于初学者,读到这里,其实可以停下来,去写一个自定义的内嵌kref的内核模块进行测试kref的功能。下面给出编程步骤:
- 自定义一个结构体,内嵌kref。注意,一定要内嵌;
- 初始化函数内申请资源构造自定义的结构体;
- 初始化kref;
- 在卸载函数内,释放引用函数。
在这样的简单的一个模块里,验证自定义的release函数是否会被调用,是初学者深刻理解kref的必经之路。
但是,这里我想提出一个问题。前面说过,kref是为了自动回收资源来用的,但是上面的例子里,明显回收资源还是需要自己调用kref_put,这不是反而变得麻烦了么?
实际,在实际的驱动中,kref_get可能会出现在各种地方。其实,我们可以注意到,如果不使用kref机制,那么在卸载函数里,我们需要强制回收资源。但是如果使用了kref的功能,那么实际上,在卸载函数里,并不一定真正回收资源。因为此时kref的引用不一定为0.这在热插拔中的应用非常普遍。
内核对象kobject和sysfs(2)——kref分析的更多相关文章
- 内核对象kobject和sysfs(3)——kobj分析
内核对象kobject和sysfs(3)--kobj分析 在分析kobj之前,先总结下kobj的功能: 实现结构的动态管理: 实现内核对象到sysfs的映射: 实现自定义属性的管理. 关注一下kobj ...
- 内核对象kobject和sysfs(4)——kset分析
内核对象kobject和sysfs(4)--kset分析 从狭义上来说,kset就是kobj的一个再封装而已.在封装之后,提供了针对kset之下所有kobj统一管理的一些方法. 我们还是从结构说起: ...
- 内核对象kobject和sysfs(1)——概述
内核对象kobject和sysfs(1)--概述 问题: 在走读驱动代码时,经常看见kref,kobj,sysfs这些结构,这些结构到底有什么作用?如何理解并使用这些结构呢?这将在接下来的这一系列文章 ...
- sysfs - 用于导出内核对象(kobject)的文件系统
sysfs - _The_ filesystem for exporting kernel objects.sysfs - 用于导出内核对象(kobject)的文件系统Patrick Mochel & ...
- [4]Windows内核情景分析---内核对象
写过Windows应用程序的朋友都常常听说"内核对象"."句柄"等术语却无从得知他们的内核实现到底是怎样的, 本篇文章就揭开这些技术的神秘面纱. 常见的内核对象 ...
- Linux 内核文档翻译 - kobject.txt
原文地址:Linux 内核文档翻译 - kobject.txt 作者:qh997 Everything you never wanted to know about kobjects, ksets, ...
- Linux内核文档翻译——kobject.txt
==================================================================== Everything you never wanted to ...
- 第9章 用内核对象进行线程同步(4)_死锁(DeadLock)及其他
9.7 线程同步对象速查表 对象 何时处于未触发状态 何时处于触发状态 成功等待的副作用 进程 进程仍在运行的时候 进程终止的时(ExitProcess.TerminateProcess) 没有 线程 ...
- 第9章 用内核对象进行线程同步(1)_事件对象(Event)
9.1 等待函数 (1)WaitForSingleObject(hObject,dwMilliseonds); ①dwMilliseconds为INFINITE时表示无限等待 ②dwMilliseco ...
随机推荐
- 日常踩坑 searter
目录 es7中的async, await Django生成二维码并转为base64 Django配置404页面 很傻逼的坑 no module named pil 其他 es7中的async, awa ...
- Realm的简单使用
Realm个人理解: 它主要是一套移动端数据库框架,将对数据库表的操作转换为对对象的操作,如果是学过Java ORM框架的同学使用Realm起来应该上手比较快一点.而且据我所知Realm不仅支持Obj ...
- ui-router 父子state共享数据
如果ui-view是嵌套的,那么在子view中,可以直接引用 $scope.$parent 即可.
- Linux命令 文件备份归档恢复
cp [功能说明] 文件的备份 英文xxxx #cp命令将源文件复制到另外安全的地方,复制的文件和源文件是两个相互独立的文件,对认识一个文件的操作不影响另一个文件,但与符号链接文件中的硬链接是有区别 ...
- API 接口规范
整体规范建议采用RESTful 方式来实施. 1. 协议 API与用户的通信协议,总是使用HTTPs协议,确保交互数据的传输安全. 2. 域名 应该尽量将API部署在专用域名之下. https://a ...
- ecshop调用指定分类和个数的文章列表
举例如首页调用方法: 1.先打开index.php文件找到以下代码: $smarty->assign('new_articles', index_get_new_articles()); // ...
- Rest模式get,put,post,delete含义与区别(转)
POST /uri 创建 DELETE /uri/xxx 删除 PUT /uri/xxx 更新或创建 GET /uri/xxx 查看 GET操作是安全的.所谓安全是指不管进行多 ...
- 手动ecache处理
手动ecache处理: import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.E ...
- Java程序设计---io流读取文件内容并将其逆值输出到控制台
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileR ...
- 新技术探究之 GraphQL
What? GraphQL 是一种类似于 SQL 的结构化查询语言,由 facebook 于2012年创造,于2015年开源.SQL 在服务端定义,GraphQL 在客户端定义,也就是说 GraphQ ...