有32路软中断,
static struct softirq_action softirq_vec[32] __cacheline_aligned_in_smp;
结构体类型
struct softirq_action
{
void (*action)(struct softirq_action *);
void *data;
};
看处理软中断的函数
define invoke_softirq() do_softirq()
smlinkage void do_softirq(void)
{
__u32 pending;
unsigned long flags;
if (in_interrupt())
return;
local_irq_save(flags);
pending = local_softirq_pending();
if (pending)
__do_softirq();//关键处理函数
local_irq_restore(flags);
}
/*
* We restart softirq processing MAX_SOFTIRQ_RESTART times,
* and we fall back to softirqd after that.
*
* This number has been established via experimentation.
* The two things to balance is latency against fairness -
* we want to handle softirqs as soon as possible, but they
* should not be able to lock up the box.
*/
#define MAX_SOFTIRQ_RESTART 10
asmlinkage void __do_softirq(void)
{
struct softirq_action *h;
__u32 pending;
int max_restart = MAX_SOFTIRQ_RESTART;
int cpu;
pending = local_softirq_pending();//取得软中断pending位
account_system_vtime(current);
__local_bh_disable((unsigned long)__builtin_return_address(0));//关软中断处理
trace_softirq_enter();
cpu = smp_processor_id();
restart:
/* Reset the pending bitmask before enabling irqs */
set_softirq_pending(0);//清软中断的pengding位
local_irq_enable();//开中断
h = softirq_vec;//取32路软中断的头
do {
if (pending & 1) {
h->action(h);
rcu_bh_qsctr_inc(cpu);
}
h++;
pending >>= 1;
} while (pending);//循环处理pending置位的softirq_vec结构体
local_irq_disable();//处理完毕后,关中断
pending = local_softirq_pending();//再取一次软中断的pending位,可能在处理软中断的时候,有被置位(因为开中断了)
if (pending && --max_restart)
goto restart;//如果置位了,则再遍历处理一次软中断
//max_restart设定成10,就是说,最多处理10次,如果还有pending,那么
if (pending)
wakeup_softirqd();//唤醒内核线程去处理其他的软中断。
trace_softirq_exit();
account_system_vtime(current);
_local_bh_enable();//开软中断
}
之所以在软中断处理函数的开头和结尾一个关中断一个开软中断,是为了保证软中断处理的串行化,就是不然软中断嵌套执行。
阅读(1058) | 评论(0) | 转发(0) |