Внутреннее устройство ядра Linux 2.4


Блокировки (Spinlocks), Read-write блокировки и Big-Reader блокировки; - часть 2


Блокировка big-reader представляет собой разновидность блокировки read-write сильно оптимизированной для облегчения доступа "на чтение" в ущерб доступу "на запись". На текущий момент существует пока только две таких блокировки, первая из которых используется только на платформе sparc64 (global irq), и вторая - для сетевой поддержки (networking). В любом другом случае, когда логика доступа не вписывается ни в один из этих двух сценариев, следует использовать базовые блокировки. Процесс не может быть блокирован до тех пор, пока владеет какой либо блокировкой (spinlock).

Блокировки могут быть трех подтипов: простые, _irq() и _bh().

  1. Простые spin_lock()/spin_unlock(): если известно, что в момент прохождения критической секции прерывания всегда запрещены или отсутствует конкуренция с контекстом прерывания (например с обработчиком прерывания), то можно использовать простые блокировки. Они не касаются состояния флага разрешения прерываний на текущем CPU.
  2. spin_lock_irq()/spin_unlock_irq(): если известно, что в момент прохождения критической секции прерывания всегда разрешены, то можно использовать эту версию блокировок, которая просто запрещает (при захвате) и разрешает (при освобождении) прерывания на текущем CPU. Например, rtc_read() использует spin_lock_irq(&rtc_lock) (внутри read() прерывания всегда разрешены) тогда как rtc_interrupt() использует spin_lock(&rtc_lock) (iвнутри обработчика прерывания всегда запрещены). Обратите внимание на то, что rtc_read() использует spin_lock_irq(), а не более универсальный вариант spin_lock_irqsave() поскольку на входе в системный вызов прерывания всегда разрешены.
  3. spin_lock_irqsave()/spin_unlock_irqrestore(): более строгая форма, используется, когда состояние флага прерываний неизвестно, но только если вопрос в прерываниях вообще. Не имеет никакого смысла, если обработчик прерываний не выполняет критический код.

Не следует использовать простые spin_lock(), когда процесс конкурирует с обработчиком прерываний, потому что когда процесс выполняет spin_lock(), а затем происходит прерывание на этом же CPU, возникает ситуация "вечного ожидания": процесс, выполнивший spin_lock() будет прерван и не сможет продолжить работу, пока обработчик прерываний не вернет управление, а обработчик прерываний не сможет вернуть управление, поскольку будет стоять в ожидании снятия блокировки.




- Начало -  - Назад -  - Вперед -