Могут ли ISR мигрировать на другие процессоры при вытеснении? - PullRequest
5 голосов
/ 19 мая 2011

В более старых версиях ядра Linux подпрограммы обработки прерываний (ISR) для аппаратных IRQ в системе SMP выполнялись на ЦПУ, с которого они начинались, от начала до конца.Если прервано каким-либо другим кодом, ISR впоследствии возобновит работу на том же процессоре.

Но в последних ядрах большинство ISR должны выполняться по умолчанию в контексте специальных потоков ядра (* 1004).* «Обычные» потоки ядра могут мигрировать на другой ЦП при вытеснении. Таким образом, вопрос в том, могут ли ISR также делать такие вещи сейчас, по какой-либо причине?и балансировка IRQ между процессорами. Мне любопытно, что обработчик прерываний уже запущен, но прерван.

То есть, предположим, что ISR уже начал выполняться на CPU # 1.некоторый код с более высоким приоритетом. Когда последний выполнил свою работу, ISR возобновляет выполнение - но на CPU № 2. Возможны ли такие ситуации?

Всегда приветствуются указатели на соответствующие документы, обсуждения и т. д..

1 Ответ

3 голосов
/ 04 ноября 2011

Потоки ISR получают то же сходство, что и процедуры ISR, поэтому в случае вытеснения поток ISR не будет перепланирован на произвольный ЦП.

Кроме того, поведение принудительного превращения ISR в потоки не включено по умолчанию в соответствии с информацией в указанной вами ссылке. Это обусловлено параметром командной строки threadirqs. Обработка параметров командной строки заботится о потоках ISR таким образом, что традиционным ISR не нужно заботиться о перепланировании. Согласно следующему коду в kernel / irq / manage.c, вытеснение отключено для этих потоков:

/*
 * Interrupts which are not explicitely requested as threaded
 * interrupts rely on the implicit bh/preempt disable of the hard irq
 * context. So we need to disable bh here to avoid deadlocks and other
 * side effects.
 */
static void
irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action)
{
        local_bh_disable();
        action->thread_fn(action->irq, action->dev_id);
        irq_finalize_oneshot(desc, action, false);
        local_bh_enable();
}
...