Решение проблемы со спинлоком

В драйверах устройств Linux. Когда он вводит спин-блокировки, он дает следующий пример:

Ваш драйвер работает и только что снял блокировку, которая контролирует доступ к его устройству. Пока блокировка удерживается, устройство выдает прерывание, которое запускает ваш обработчик прерывания. Обработчик прерывания перед обращением к устройству также должен получить блокировку. Снятие спин-блокировки в обработчике прерываний — вполне законная вещь; это одна из причин того, что операции спин-блокировки не спят. Но что произойдет, если подпрограмма обработки прерывания будет выполняться на том же процессоре, что и код, первоначально снявший блокировку? Пока обработчик прерывания вращается, код без прерывания не сможет запуститься, чтобы снять блокировку. Этот процессор будет вращаться вечно.

Как решить эту проблему? Использование семафоров? Пожалуйста помоги.


person foo_l    schedule 30.05.2012    source источник


Ответы (1)


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

Редактировать 0:

Не помню точных деталей там, но теория такова:

  • В системах UP вам вообще не нужны спин-блокировки — достаточно отключить прерывания от кода BH, который обращается к данным, совместно используемым с обработчиками прерываний.
  • В системах SMP вам нужна спин-блокировка для защиты от того же кода BH, выполняющегося на других ядрах, и, если вы имеете дело с аппаратным обеспечением, вы также хотите отключить прерывания на том же ядре, чтобы избежать взаимоблокировки с процедурой IRQ.
  • Обработчик прерываний всегда должен отключать прерывания, удерживая любые блокировки, чтобы избежать взаимной блокировки с самим собой.

Надеюсь это поможет.

person Nikolai Fetissov    schedule 30.05.2012
comment
Спасибо за ответ. В подпрограмме прерывания следует использовать spin_lock_irqsave в однопроцессорных системах, а в многопроцессорных системах у меня есть возможность использовать spin_lock,spin_lock_irqsave,spin_lock_irq. Правильно ли я понимаю? - person foo_l; 31.05.2012