baron · 17 小时前

Linux Kernel5.10的软中断(softirq)的本质

Linux Kernel的中断的底半部分实现有三种,分别是:

软中断
tasklet
工作队列
软中断
软中断的本质是什么?
其实就是在硬件中断(也叫中断顶半部分)执行完毕后,通过wakeup_softirqd()的方式唤醒一个softirq队列,然后中断程序返回,softirq队列也在适当的时候开始执行。

irq_handler —> gic_handle_irq() —> handle_domain_irq() —> __handle_domain_irq() —> 基本处理完硬件中断后,调用—>irq_exit() —> —> __irq_exit_rcu() —> invoke_softirq() ----> __do_softirq()—>到此处(1)硬件中断处理完成(即中断上半部分执行完成),gic_handle_irq()主函数返回;(2) 唤醒softirq队列,中断底半部分开始执行

系统中有哪些软中断(softirq队列里有什么),也是固定的,Linux Kernel中定义的软中断的定义如下:

  1. (linux/include/linux/interrupt.h)
  2. enum
  3. {
  4. HI_SOFTIRQ=0,
  5. TIMER_SOFTIRQ,
  6. NET_TX_SOFTIRQ,
  7. NET_RX_SOFTIRQ,
  8. BLOCK_SOFTIRQ,
  9. IRQ_POLL_SOFTIRQ,
  10. TASKLET_SOFTIRQ,
  11. SCHED_SOFTIRQ,
  12. HRTIMER_SOFTIRQ,
  13. RCU_SOFTIRQ, / Preferable RCU should always be the last softirq /
  14. NR_SOFTIRQS
  15. };
  16. (linux/kernel/softirq.c)
  17. 74 static void wakeup_softirqd(void)
  18. 75 {
  19. 76 / Interrupts are disabled: no need to stop preemption /
  20. 77 struct task_struct *tsk = __this_cpu_read(ksoftirqd);
  21. 78
  22. 79 if (tsk && tsk->state != TASK_RUNNING)
  23. 80 wake_up_process(tsk);
  24. 81 }

那么软中断,如何注册、如何使用? 这重要吗? 系统就这么几种软中断,又不让你去实现。我们的驱动中也一般不用,用的时候过来抄一抄即可,可搜索以下API

注册软中断 open_softirq
触发软中断 raise_softirq
执行软中断 do_softirq
思考:软中断 是否可以睡眠?

个人认为,要看你的系统的配置。如下图所示,如果是else里的配置,ksoftirqd也是task,故是可以睡眠的。如果是if里的配置,softirq就是一段程序而已,不是进程,没有task_struct,所以是不能睡眠的

d0020c987bb502e09f66b1fd0aeb47cd.png

添加威♥:sami01_2023,回复ARM中文,领取ARM中文手册

推荐阅读
关注数
9491
文章数
256
vx: coding_the_world
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息