【linux kernel】linux中断管理—软中断

linux中断管理—软中断

一、简介

​ 软中断是linux预留给系统中对时间要求最为严苛和最重要的中断下半部使用的。并且,驱动中只有一些对时间极其敏感的模块使用了。例如:块设备和网络子系统。linux系统中定义了几种软中断类型。如下所示(/include/interrupt.h):

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
};

​ 如果不需要真正高频率的线程任务调度,请避免分配新的软中断。意味着,linux内核不希望开发者新去扩充软中断类型,可以使用tasklet来替代。

​ 在linux内核中,定义了一个数组softirq_vec[]来描述软中断。类似硬件中断描述数组irq_desc[]

如下定义(/kernel/softirq.c):

static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;

​ 其中每个数组的元素为struct softirq_action类型。对于linux来说,系统中的10软中断则一一对应10个softirq_action。如下定义(/include/linux/interrupt.h):

struct softirq_action
{
	void	(*action)(struct softirq_action *);
};

二、软中断相关API总结

​ (2-1)注册软中断

​ 通过调用open_softirq()函数接口可以注册一个软中断。如下定义(/kernel/softirq.c):

void open_softirq(int nr, void (*action)(struct softirq_action *))
{
	softirq_vec[nr].action = action;
}
  • nr :软中断的序号。

​ 该函数较为简单,且没有过多的保护机制。可见,softirq_vec数组是一个多CPU共享的数组。因系统在启动时是串行运行的,对于软中断的初始化过程,不会产生冲突。

(2-2)主动触发一个软中断

​ 通过使用raise_softirq()函数可以主动触发一个软中断。定义定义(/kernel/softirq.c):

void raise_softirq(unsigned int nr)
{
	unsigned long flags;

	local_irq_save(flags);
	raise_softirq_irqoff(nr);
	local_irq_restore(flags);
}

​ 还可以使用raise_softirq_irqoff()函数触发。但是该函数运行在关闭本地中断的情况下(意味着该函数可以在进程上下文调用),如下定义(/kernel/softirq.c):

/*
 * This function must run with irqs disabled!
 */
inline void raise_softirq_irqoff(unsigned int nr)
{
	__raise_softirq_irqoff(nr);

	if (!in_interrupt())
		wakeup_softirqd();
}


你可能感兴趣的:(小生聊【Linux,kernel】,linux,C语言,linux,kernel,软中断)