一个中断处理程序,一般分为两部分执行,上部分,很紧要,要立刻执行,且代码要简短,不要浪费太多的时间,然后再结尾,把下部分要处理的,不紧急的部分,以下半部的形式激活,成为软中断,然后就开中断,去执行刚才激活的软中断,当然,如果允许,在中断处理的上半部,看情况,也可以开中断。但是在软中断处理的过程,一定要开中断。同时,要保证,每个cpu上要保证,只能有一个软中断处理程序执行,不能并行执行。
在do_IRQ的最后,调用了irq_exit函数
/*
* Exit an interrupt context. Process softirqs if needed and possible:
*/
void irq_exit(void)
{
account_system_vtime(current);
trace_hardirq_exit();
sub_preempt_count(IRQ_EXIT_OFFSET);//硬中断处理结束标志
if (!in_interrupt() && local_softirq_pending())
invoke_softirq();//处理软中断
preempt_enable_no_resched();
}
in_interrupt() 是关键,保证在非硬中断中处理软中断,同时保证一个cpu只能执行一个软中断。
# define invoke_softirq() do_softirq()
asmlinkage 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();
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);
local_irq_enable();//开硬中断
h = softirq_vec;
do {//循环处理软中断
if (pending & 1) {
h->action(h);
rcu_bh_qsctr_inc(cpu);
}
h++;
pending >>= 1;
} while (pending);
local_irq_disable();//关硬中断
pending = local_softirq_pending();
if (pending && --max_restart)//处理由于中断嵌套产生的软中断,循环10次,还有的话,就要跳出了
goto restart;
if (pending)//循环10次,还有悬而未决的软中断,就要唤醒内核线程来执行软中断了
wakeup_softirqd();
trace_softirq_exit();
account_system_vtime(current);
_local_bh_enable();//开软中断
}
现在的叫法很乱。
比如说,硬中断,软中断。
当把外部中断看成是硬中断的时候,那么int指令和由于除0,缺页异常产生的中断叫做软中断。
当把一个外部中断处理程序的紧急部分称作硬中断的时候,那么他的下半部就叫做软中断。
阅读(867) | 评论(0) | 转发(0) |