0

我有一个中断处理程序,它按如下方式安排一个小任务(伪代码) -

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

“退出中断”打印永远不会出现。tasklet 函数中的打印不打印。

  • 这个小任务没有被安排的原因是什么?

  • 什么可能导致内核挂起?

4

1 回答 1

0

tasklet 调度不应该在 IRQ 处理程序中完成。你可以查看 lxr 中的 schedule_tasklet() 代码。在 IRQ 处理程序中,调用 schedule_tasklet() 仅设置 softirq 的位,并链接您的 tasklet。

当 irq_exit() 被调用时,它会检查它是否还在中断上下文中(嵌套中断)。如果没有,并且启用了任何 tasklet,它将调用 softirq 处理程序,而该处理程序又将调用 tasklet。

于 2017-12-04T12:31:22.330 回答