虽然标题叫软中断原理,当并不深入介绍软中断,仅仅记录以下软中断的结构类型;毕竟用户不会直接用到软中断。
软中断数据类型,是softirq_action结构体,只有一个成员函数指针,自然是用于绑定软中断要执行的函数:;
struct softirq_action
{
void (*action)(struct softirq_action *);
};
事实上内核用一个数组表示所有的软中断,数组名为 softirq_vec[] , 每个元素的类型为softirq_action ,共有 NR_SOFTIRQS 个元素:
static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;
关于之所有NR_SOFTIRQS个元素,我们拿出上节介绍的软中断类型就一目了然了:
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
};
注册软中断
内核使用软中断需要先注册(使用如下函数), 仅仅是把软中断插入到中断数组中:
void open_softirq(int nr, void (*action)(struct softirq_action *))
{
softirq_vec[nr].action = action;
}
引发软中断
函数如下,不再深入介绍,我们只需要知道,通过如下函数引发中断后,内核就会通过do_softirq() 函数循环处理中断数组中的所有中断;至于如何禁用中断、如何清除软中断位图等操作也不再深入。
/*
* This function must run with irqs disabled!
*/
inline void raise_softirq_irqoff(unsigned int nr)
{
__raise_softirq_irqoff(nr);
if (!in_interrupt() && should_wake_ksoftirqd())
wakeup_softirqd();
}