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中定义的软中断的定义如下:
- (linux/include/linux/interrupt.h)
- enum
- {
- HI_SOFTIRQ=0,
- TIMER_SOFTIRQ,
- NET_TX_SOFTIRQ,
- NET_RX_SOFTIRQ,
- BLOCK_SOFTIRQ,
- IRQ_POLL_SOFTIRQ,
- TASKLET_SOFTIRQ,
- SCHED_SOFTIRQ,
- HRTIMER_SOFTIRQ,
- RCU_SOFTIRQ, / Preferable RCU should always be the last softirq /
- NR_SOFTIRQS
- };
- (linux/kernel/softirq.c)
- 74 static void wakeup_softirqd(void)
- 75 {
- 76 / Interrupts are disabled: no need to stop preemption /
- 77 struct task_struct *tsk = __this_cpu_read(ksoftirqd);
- 78
- 79 if (tsk && tsk->state != TASK_RUNNING)
- 80 wake_up_process(tsk);
- 81 }
那么软中断,如何注册、如何使用? 这重要吗? 系统就这么几种软中断,又不让你去实现。我们的驱动中也一般不用,用的时候过来抄一抄即可,可搜索以下API
注册软中断 open_softirq
触发软中断 raise_softirq
执行软中断 do_softirq
思考:软中断 是否可以睡眠?
个人认为,要看你的系统的配置。如下图所示,如果是else里的配置,ksoftirqd也是task,故是可以睡眠的。如果是if里的配置,softirq就是一段程序而已,不是进程,没有task_struct,所以是不能睡眠的
添加威♥:sami01_2023,回复ARM中文,领取ARM中文手册