我有一个中断处理程序,它按如下方式调度一个tasklet(伪代码) -
struct tasklet_struct mytasklet;
void my_tasklet_function(unsigned long arg1) {
...
pr_alert("Inside tasklet function\n");
...
}
int my_probe() {
....
....
tasklet_init(&mytasklet, my_tasklet_function, arg1);
....
/* Register interrupt handler my_irq_handler*/
....
}
irqreturn_t my_irq_handler(int irq, void *data) {
...
status = read_reg(base_addr, intr_status_reg_offset)
write_reg(base_addr, intr_status_reg_offset, status);
if (status & INTR_MASK_1) {
....
pr_alert("intr 1 came\n");
}
...
...
pr_alert("Schedule tasklet\n");
tasklet_schedule(&mytasklet);
pr_alert("Exit irq\n");
return IRQ_HANDLED;
}
观察到内核在以下打印后挂起
intr 1 came
Schedule tasklet
“退出irq”打印件从不显示。不打印tasklet功能中的打印件。
这个tasklet没有被安排的原因是什么?
什么可能导致内核挂起?
答案 0 :(得分:0)
不应在IRQ处理程序中完成tasklet调度。 您可以检查lxr中的schedule_tasklet()代码。 在IRQ处理程序中,调用schedule_tasklet()只设置softirq的位,并链接你的tasklet。
当调用irq_exit()时,它将检查它是否仍处于中断上下文(嵌套中断)。如果没有,并且启用了任何tasklet,它将调用softirq处理程序,而后者将调用tasklet。