You need to enable JavaScript to run this app. kobject_create_and_add创建的kobject初始引用计数到底有几个?
优惠活动
大模型
产品
解决方案
定价
更多

kobject_create_and_add创建的kobject初始引用计数到底有几个?

kobject_create_and_add引用计数相关问题说明

最初推断的认知偏差

你根据LDD3规则推导“kobject_create_and_add创建的对象需要两次引用释放”的结论,核心问题在于误读了LDD3对kobject引用计数的表述,混淆了总引用计数数值和驱动需要负责释放的引用数量两个概念:

  • LDD3成书基于2.6.10早期内核,书中提到“kobject_init、kobject_add会提升引用计数”时,没有明确说明引用的所有权归属,也没有区分“初始化赋值”和“累加提升”的区别。
  • 实际内核实现中,kobject_init对刚分配的kobject执行的是kref_init操作,会将引用计数初始化为1,并非在已有计数基础上累加提升——这个初始的1,是直接归属于初始化调用者的引用。
  • 当kobject_add成功把kobject挂载到sysfs树后,kobject核心确实会额外获取1个引用,让总计数从1上升到2,但这个引用是sysfs子系统用来保护目录结构、属性文件访问安全的,所有权完全属于内核kobject子系统,和驱动模块没有关系。

示例代码实现的合理性

kobject_create_and_add作为kobject子系统提供的通用封装API,严格遵循统一的所有权传递规则:只要函数返回了有效的kobject指针,调用方就仅持有1个需要负责的引用,仅需要在模块退出流程中对应调用一次kobject_put即可完成自身的引用释放。

剩下的1个内核持有的引用,完全由kobject子系统自动维护、自动释放:

  • 当驱动调用kobject_put释放自己持有的引用后,kobject子系统会自动启动销毁流程,先将该kobject从父目录的sysfs链表中摘除
  • 等待所有打开该kobject属性文件的用户态进程关闭文件句柄后,再释放核心自己持有的那部分引用
  • 当总引用计数降到0时,自动触发对应的release回调,释放kobject占用的内存

整个流程不需要驱动额外执行第二次put,也不需要手动调用kobject_del,所有内部的引用增减、树结构调整逻辑都由kobject核心统一处理,这也是官方示例代码这么写的原因。

容易产生混淆的历史背景

LDD3描述的是早期2.6内核的kobject实现,当时的核心逻辑还没有做到完全自动的引用维护:早期版本中kobject_add挂载时获取的引用,需要驱动显式调用kobject_del触发释放,如果只调用put确实会出现计数残留、kobject无法销毁的问题。但经过多个内核版本的迭代,kobject核心已经把这些内部维护逻辑封装了起来,驱动只需要遵循“拿到一个引用、释放一次”的简单规则即可,不需要再感知内部的引用增减细节。


内容的提问来源于stack exchange,提问作者rapiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.04 03:36:07