Почему запланированный тасклет из обработчика прерываний не будет запущен

У меня есть обработчик прерываний, который планирует тасклет следующим образом (псевдокод) -

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" никогда не появляется. Отпечатки в функции тасклета не печатаются.

  • Что может быть причиной того, что этот тасклет не был запланирован?

  • Что может вызвать зависание ядра?

1 ответ

Планирование тасклетов НЕ должно выполняться в обработчике IRQ. Вы можете проверить код schedule_tasklet() в lxr. В обработчике IRQ вызов schedule_tasklet() только устанавливает бит для softirq и связывает ваш тасклет.

Когда вызывается irq_exit(), он проверяет, находится ли он все еще в контексте прерывания (вложенное прерывание). Если нет, и есть какой-либо активированный тасклет, он вызовет обработчики softirq, которые, в свою очередь, вызовут тасклет.

Другие вопросы по тегам