2016-11-04 4 views
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 

Печать «Выход из irq» никогда не появляется. Отпечатки в этой функции не печатаются.

  • В чем может быть причина, по которой этот талисман не намечается?

  • Что может привести к зависанию ядра?

+0

Показать, как инициализируется объект 'mytasklet' (определенный). – Tsyvarev

+0

Обновлен код для инициализации mytasklet –

+0

Вы уверены, что ваш обработчик прерываний вызывается * после того, как * tasklet инициализируется? (То есть вы регистрируете обработчик irq * после того, как * функция 'my_probe()' вызывается или * после * 'tasklet_init' в этой функции.) – Tsyvarev

ответ

0

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

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

Смежные вопросы