You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核驱动如何处理设备移除?字符设备USB拔插场景实现方案

问题解答

1. 内核原生引用计数及回调机制

Linux内核原生提供了struct kref结构实现轻量级引用计数,完全可以满足你的需求,无需自行造轮子:

  • 在你的字符设备管理结构体中嵌入struct kref成员,每个设备实例独立持有,无全局依赖,支持任意数量USB设备接入
  • 在file_operations的open回调中调用kref_get()对引用计数加1
  • 在file_operations的release回调中调用kref_put()对引用计数减1,kref_put()的第二个参数就是所有引用全部释放后自动触发的回调函数,你可以在这个回调里完成管理结构体内存释放、mutex销毁等操作

内核不会直接统计单个字符设备的打开句柄数,但kref本身就是为这类单对象引用计数场景设计的,完全匹配你的需求。

2. 方案可行性

这是USB字符驱动热拔插场景的标准实现方案,完全可行,符合内核设计规范:

  • 所有IO操作入口(read/write/ioctl)首先检查设备在位标记,标记为已拔出时直接返回-ENODEV错误即可
  • 引用计数保证只要有未完成的IO或者未关闭的句柄,管理结构体的内存就不会被释放,正在持有的mutex可以正常完成解锁操作,不会出现野指针访问问题

3. USB拔出时移除字符设备的标准流程

在USB驱动的disconnect回调中按以下顺序执行:

  • 原子设置设备在位标记为「已拔出」,该标记需要在IO操作的公共判断路径里被访问,保证新进入的系统调用直接返回错误
  • 调用cdev_del()接口从内核中注销该字符设备,彻底阻止新的open请求打开该设备
  • 调用kref_put()释放你在创建设备时持有的初始引用计数

注意:此时不要直接释放管理结构体的内存,也不要销毁mutex,所有释放逻辑都放到kref的释放回调里执行,等所有已打开的句柄全部关闭、所有运行中的IO全部完成后,回调会自动触发执行资源清理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:15:12