在 Linux 内核中断上下文中取消 delayed_work 的核心难点是:中断上下文禁止阻塞操作,因此不能使用会阻塞的 sync 版取消函数,只能用非同步的 cancel_delayed_work(),同时要解决竞态和后续重新调度的问题。以下是完整的实现方案和注意事项。
一、中断上下文取消 delayed_work 的核心函数
只能使用:
bool cancel_delayed_work(struct delayed_work *dwork);
· 返回值:true 表示工作项还在队列中,成功发起取消请求;false 表示工作项已执行/已完成/未调度
· 特点:非阻塞,仅发起取消请求,不等待工作项执行完毕,适合中断上下文
与之对比,禁止在中断上下文使用:
bool cancel_delayed_work_sync(struct delayed_work *dwork); // 会阻塞,中断上下文调用会触发内核Oops
二、中断上下文取消 + 后续处理的完整示例
该示例包含中断处理函数中取消 delayed_work、避免竞态、重新调度的完整逻辑,适配内核 5.0+:
今天时间仓促,无法在公众号整理发出,余下完整方案请参阅星球分享:
https://t.zsxq.com/EqxEh
或通过加入星球获取完整方案:
星球部分技术分享目录