Предотвращение ядра Linux во время spin_lock и mutex_lock

Когда процесс в пространстве ядра содержит spin_lock, процесс не может быть выгружен из-за любого из следующих условий:

  • Когда время фрагмента процесса исчерпается
  • Когда процесс с высоким приоритетом становится исполняемым
  • При возникновении прерывания

Однако процесс может дать процессор, если он блокирует, спит или явно вызывает schedule(). Правильно ли я понимаю?

Когда процесс в пространстве ядра держит mutex_lock, может ли процесс быть выгружен из-за вышеперечисленных условий, перечисленных как 1, 2 и 3.

Ответ 1

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

  • Существует сам spin_lock, который существует только для предоставления мьютекса между двумя или более процессорными ядрами. Любой процессор, который блокирует блокировку блокировки, в основном застревает, пока другой процессор не освободит его. Спин-блокировки не предназначены для однопроцессорных систем, кроме как для увеличения вероятности полного тупика, поэтому обычно удаляются при компиляции ядра.

  • Чтобы обеспечить локальный процессор mutex, spin_lock() вызывает preempt_disable() (в системах с предварительным упреждением планирования), чтобы предотвратить запуск любого другого потока во время блокировки; Аналогично, spin_lock_irqsave() также выполняет эквивалент local_irq_save(), чтобы отключить прерывания, чтобы что-то еще не выполнялось на локальном процессоре.

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

Случай с mutex_lock совершенно другой - затрагиваются только потоки, пытающиеся получить доступ к блокировке, и если поток попадает в заблокированный мьютекс, тогда произойдет перепланирование. По этой причине mutex_locks не могут использоваться в контексте прерывания (или других атомных).