中断, softirq, tasklet的区别
2017-01-18
1. 中断流程
假定 CONFIGMULTIIRQHANDLER=y, handlearchirq 为 gichandle_irq.
linux-3.10.86/arch/arm/kernel/setup.c
__irq_svc @entry-armv.S
| |--svc_entry 保存spsr_<exception> 到r5
| |--irq_handler
| | |--handle_arch_irq => gic_handle_irq
| | | |--irq_find_mapping 完成 an hw irq number到a linux irq的转换
| | | |--handle_IRQ(irqnr, regs) if not IPI
| | | | |--generic_handle_irq -> generic_handle_irq_desc -> handle_fasteoi_irq
| | | | | |--raw_spin_lock(&desc->lock);
| | | | | |--handle_irq_event
| | | | | | |--raw_spin_unlock(&desc->lock);
| | | | | | |--handle_irq_event_percpu -> action->handler
| | | | | | |--raw_spin_lock(&desc->lock);
| | | | | |--chip->irq_eoi
| | | | | |--raw_spin_unlock(&desc->lock);
| | | | |--irq_exit(); 这里中断还是禁用的吗? 答:是的, ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED
| | | | | |--WARN_ON_ONCE(!irqs_disabled());
| | | | | |--if( ... ) invoke_softirq()
| | | | | | |--do_softirq -> __do_softirq
| | | | | | | |--local_irq_enable //修改CPSR I bit, 打开中断
| | | | | | | |--h->action(h)
| | | | | | | |--local_irq_disable //这里为何又禁止中断???
| | | | |--set_irq_regs(old_regs) 这里开启中断? 答:不是.
| |--svc_exit r5, irq = 1 @entry-header.S
假定发生中断前, 是处于svc模式的, 所以, 上面流程为_irqsvc. 中断上半部分 中断是关闭的, 何时重新使能中断, 上面都已标出. 使能之后, 就开始处理软中断了.
2. tasklet的特点
两个类型相同的tasklet不能同时运行, 即使在不同的处理器上也是如此, 因为代码上检查的并不是per cpu的变量.
void __init softirq_init(void)
{
...
open_softirq(TASKLET_SOFTIRQ, tasklet_action);
open_softirq(HI_SOFTIRQ, tasklet_hi_action);
}
代码:linux-3.10/kernel/softirq.c
static void tasklet_action(struct softirq_action *a)
{
struct tasklet_struct *t
...
if (tasklet_trylock(t)) {
...
t->func(t->data);
}
}
#ifdef CONFIG_SMP
static inline int tasklet_trylock(struct tasklet_struct *t)
{
return !test_and_set_bit(TASKLET_STATE_RUN, &(t)->state);
}
#endif
3. softirq的特点
softirq的pending变量是per-cpu的, 并不会阻止相同的handler同时运行在不同的cpu上.
linux-3.10.86/kernel/softirq.c
__do_softirq
{
pending = local_softirq_pending();
set_softirq_pending(0);
do {
if (pending & 1) {
->action
}
pending >>= 1;
}while (pending);
}
本文地址: https://awakening-fong.github.io/posts/arm/interrupt_softirq_in_arm
转载请注明出处: https://awakening-fong.github.io
若无法评论, 请打开JavaScript, 并通过proxy.
blog comments powered by Disqus