kref 与引用计数

这页讲的是:内核里很多对象并不是“谁先用完谁就随手 free”,因为同一对象可能被很多路径同时持有。学这页的重点,是理解引用计数不是小技巧,而是生命周期安全的核心规则之一。

这块是什么

kref 与引用计数,讲的是当一个对象会被多个子系统、回调、异步工作或用户入口同时指向时,内核如何通过“还有多少人正在用它”来决定它何时仍然有效、何时才真正可以释放。它把对象生命从“看上去好像没人用了”变成“系统明确知道现在能不能收”。

可以把它理解成:一把公共会议室钥匙被多人借用,只要还有人没还,就不能把锁芯拆掉。真正能收走,得等最后一个借用者也放手。

它负责什么

保护对象生命周期

  • 让对象在仍被使用时继续存活
  • 避免“有人还在用,东西已经被释放”
  • 让释放时机更明确
  • 降低悬空指针和 use-after-free 风险

衔接多条执行路径

  • 同一对象可能被同步和异步路径同时持有
  • 不同模块可能共享同一对象引用
  • 引用计数让这些关系能被统一表达
  • 避免只靠口头约定猜谁还在用

支撑安全释放

  • 最后一个引用放下时才触发真正清理
  • 把释放与仍在使用之间切出明确边界
  • 帮助模块退出、设备移除和后台清理更安全
  • 让生命周期从感觉问题变成可度量关系

为什么不能只靠“我觉得这里应该没人用了”

如果只靠感觉会怎样引用计数的价值
对象可能被多个地方共享某条路径提前释放,别的路径就会踩空。明确记录还有多少活跃持有者。
异步工作还没结束看起来主流程已经走完,后台却还会回来访问。把“后台还在用”也计入对象存活条件。
模块和驱动正处于退出中退出逻辑容易和仍在运行的路径打架。让最后释放时机更晚、更安全。
回调关系复杂对象到底归谁释放会变得模糊。用统一规则替代含糊约定。

关键概念

概念现在怎么理解
引用计数记录某个对象当前仍被多少活跃路径持有。
kref内核里常见的引用计数辅助机制,可先理解成管理对象存活的一把统一尺子。
获取引用表示“我现在也要使用这个对象,你先别释放它”。
放下引用表示“我用完了,我这一份持有关系可以去掉”。
最终释放只有最后一个引用离开时,真正清理对象才安全。

为什么重要

常见误解

它不负责什么

和其他模块的关系

相关模块关系
Core API引用计数本身就是公共底座里最重要的生命周期工具之一。
模块加载与生命周期模块退出前常要确认对象引用都已释放,否则退出会不安全。
probe、remove 与资源清理设备撤场时尤其容易暴露“对象还在被谁引用”的问题。
workqueue / 异步执行后台路径最容易让对象看似该死、其实还活着。

读完这页后,你应该能回答

后面适合继续问:kref 和 kobject 的关系怎么理解?为什么引用计数容易和异步回调缠在一起?什么情况下会出现泄漏而不是过早释放?