zl程序教程

您现在的位置是:首页 >  系统

当前栏目

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

Linux 中断 本质
2023-09-27 14:26:31 时间

快速链接:
.
👉👉👉 个人博客笔记导读目录(全部) 👈👈👈


说明:
在默认情况下,本文讲述的都是ARMV8-aarch64架构,linux kernel 5.14


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,所以是不能睡眠的
在这里插入图片描述