Как ядро обрабатывает блокировку в контексте процесса при возникновении прерывания?
Прежде всего, извините за немного двусмысленности в вопросе... Что я хочу понять, это сценарий ниже
Предположим, что porcess работает, он удерживает одну блокировку. Теперь после получения блокировки генерируется прерывание HW, так как ядро будет обрабатывать эту ситуацию, будет ли оно ждать блокировки? если да, что, если обработчику прерываний необходим доступ к этой блокировке или к общим данным, защищенным этой блокировкой в процессе?
2 ответа
Ядро Linux имеет несколько функций для получения спин-блокировок, чтобы справиться с такими проблемами, как та, которую вы здесь поднимаете. В частности, есть spin_lock_irq()
, который отключает прерывания (на процессоре, на котором выполняется процесс) и получает спин-блокировку. Это может использоваться, когда код знает, что прерывания разрешены до получения спин-блокировки; в случае, если функция может быть вызвана в разных контекстах, есть также spin_lock_irqsave()
, который скрывает текущее состояние прерываний перед их отключением, так что они могут быть включены spin_unlock_irqrestore()
,
В любом случае, если блокировка используется как в контексте процесса, так и в контексте прерывания (что является хорошей и очень распространенной схемой, если есть данные, которые необходимо разделить между контекстами), тогда контекст процесса должен отключать прерывания (локально на ЦП, это работает) при получении спинлока, чтобы избежать тупиков. Фактически, lockdep ("CONFIG_PROVE_LOCKING") проверит это и предупредит, если спин-блокировка используется способом, который чувствителен к блокировке "прерывание, в то время как контекст процесса удерживает блокировку".
Позвольте мне объяснить некоторые основные свойства обработчика прерываний или нижней половины.
- Обработчик не может передавать данные в пространство пользователя или из него, потому что он не выполняется в контексте процесса.
- Обработчики также не могут делать что-либо, что будет находиться в спящем режиме, например, вызывать wait_event, выделять память для чего-либо, кроме GFP_ATOMIC, или блокировать семафор
- обработчики не могут вызвать расписание
Я пытаюсь сказать, что обработчик прерываний работает в атомарном контексте. Они не могут спать, потому что их нельзя перенести. прерывания не имеют контекста процесса поддержки
Выше по конструкции. Вы можете делать все, что вы хотите в коде, просто будьте готовы к последствиям
Предположим, вы получили блокировку в обработчике прерываний (плохой дизайн). Когда происходит прерывание, процесс сохраняет свой регистр в стеке и запускает ISR. теперь, после получения блокировки, вы окажетесь в тупике, поскольку ISR не знает, что делает процесс.
Процесс не сможет возобновить выполнение, пока это не будет сделано с помощью ISR
В вытесняющем ядре ISR и процесс могут быть вытеснены, но для не вытесняющего ядра вы мертвы.