Меня всегда учили, что спать с удерживанием спин-блокировки в коде ядра - нет-нет.Причина этого заключается в следующем сценарии:
- Поток A получает блокировку, выполняет некоторую работу и вызывает функцию ядра, которая переходит в спящий режим, освобождая процессор.
- Поток Bтеперь запускается, что пытается получить блокировку, но не может, поскольку она удерживается потоком A.
- Это тупик.Поток A не может быть разбужен, поскольку поток B постоянно вращается, а поток B не может прогрессировать, так как не может получить блокировку.
Я поддерживаю драйвер, который использует многоблокировки и внутри некоторых из заблокированных секций - очевидные вещи, такие как распределение памяти, copy_to_user()
и т. д.
Однако я не совсем уверен, что у меня есть ошибка в моих руках.Используя вышеописанный сценарий, поток A является контекстом пользователя (а именно внутри реализации read()
), а поток B является контекстом прерывания (внутри ISR).Блокировка блокируется через spin_lock_irqsave()
.В результате поток B не может работать, пока поток A удерживает блокировку, что делает невозможным взаимоблокировку.
Я также учел следующее:
- Поток A = контекст прерывания.Здесь Поток A не может спать (и не спит), поэтому мы никогда не попадаем в состояние взаимоблокировки.
- Поток A и B оба являются контекстом пользователя (то есть одновременные вызовы
read()
).Это не может произойти из-за наличия других механизмов.
Есть ли что-то, чего мне не хватает?В том, что я описал выше, есть ли реальная опасность, связанная со сном, удерживая замок?