软中断概念在嵌入式开发可以有两个不同的解释:
其一,软中断在处理器设计中是处理器异常之一,程序软件使用指定指令(如arm的SWI指令)引发该异常从而陷入内核态执行,最典型的软件应用就是系统调用。
其二,在kernel代码中实现了一套软中断机制,区别于硬件中断的硬件触发软件处理,而是软件触发软件处理。
今天来学习的是kernel下的软中断机制,
根据注释可以看出,kernel并不希望开发者来添加新的softirq,如果有需求,可以利用由softirq实现的tasklet实现需求。
下面来看softirq的注册 触发 和 分发处理
1 软中断注册
在kernel启动start_kernel中就注册了定时器的softirq,如下:
其一,软中断在处理器设计中是处理器异常之一,程序软件使用指定指令(如arm的SWI指令)引发该异常从而陷入内核态执行,最典型的软件应用就是系统调用。
其二,在kernel代码中实现了一套软中断机制,区别于硬件中断的硬件触发软件处理,而是软件触发软件处理。
今天来学习的是kernel下的软中断机制,
学习最常用的硬件中断,我们最关心的是中断触发(硬件)-中断分发-中断处理这个流程如何完成,对于软中断我们也需要搞明白这几点。
首先来看下kernel中跟软中断相关的结构体变量,在kernel/softirq.c中,如下:
static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;
softirq_vec数组表示kernel下所有注册的软中断。
struct softirq_action
{
void (*action)(struct softirq_action *);
};
数组下标表示软中断号,softirq_action则代表软中断处理函数。
softirq_vec类似于kernel下表征硬件中断的irq_desc。
/* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
frequency threaded job scheduling. For almost all the purposes
tasklets are more than enough. F.e. all serial device BHs et
al. should be converted to tasklets, not to softirqs.
*/
enum
{
HI_SOFTIRQ=0,
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
BLOCK_SOFTIRQ,
BLOCK_IOPOLL_SOFTIRQ,
TASKLET_SOFTIRQ,
SCHED_SOFTIRQ,
HRTIMER_SOFTIRQ,
RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
NR_SOFTIRQS
};
kernel下定义了10种软中断,其中包括应用于定时器 tasklet 网络收发(NAPI) 块设备读写等。根据注释可以看出,kernel并不希望开发者来添加新的softirq,如果有需求,可以利用由softirq实现的tasklet实现需求。
下面来看softirq的注册 触发 和 分发处理
1 软中断注册
softirq注册使用函数open_softirq,类似于硬件中断的register_irq。定义在kernel/softirq.c中
void open_softirq(int nr, void (*action)(struct softirq_action *))
{
softirq_vec[nr].action = action;
}
很简单,添加softirq_vec对应下标的处理函数即可。在kernel启动start_kernel中就注册了定时器的softirq,如下:
void __init init_timers(void)
{
int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
(void *)(long)smp_processor_id());
init_timer_stats();
BUG_ON(err != NOTIFY_OK);
register_cpu_notifi