Разработка ядра Linux
Шрифт:
Этот фрагмент кода является сердцем обработчика отложенных прерываний. Он проверяет и выполняет все ожидающие отложенные прерывания.
• Присваивает локальной переменной pending значение, возвращаемое макросом
• Когда значение битовой маски отложенных прерываний сохранено, оригинальная битовая маска очищается [38] .
• Переменной
38
На самом деле эта операция выполняется при всех запрещенных на локальном процессоре прерываниях, что не показано в упрощенной версии. Если бы прерывания не были запрещены, то в период времени между сохранением и очисткой маски могло бы быть сгенерировано новое отложенное прерывание (которое бы ожидало на выполнение), что привело бы к неверной очистке бита соответствующего отложенного прерывания.
• Если первый бит маски, которая хранится в переменной
• Указатель
• Осуществляется логический сдвиг битовой маски, хранящейся в переменной
• Указатель
• Последовательное повторение производится до тех пор, пока битовая маска не станет равной нулю. В этот момент больше нет ожидающих отложенных прерываний, и наша работа выполнена. Заметим, что такой проверки достаточно для того, чтобы гарантировать, что указатель
Использование отложенных прерываний
Отложенные прерывания зарезервированы для наиболее важных и критичных ко времени выполнения обработчиков нижних половин в системе. Сейчас только две подсистемы — подсистема SCSI и сетевая подсистема — напрямую используют механизм softirq. В дополнение к этому, таймеры ядра и тасклеты построены на базе отложенных прерываний. Если есть желание добавить новое отложенное прерывание, то стоит себя спросить, почему будет недостаточно использования тасклетов. Тасклеты могут создаваться динамически, а также их легче использовать в связи с более простыми требованиями к блокировкам. Кроме того, их производительность все еще остается очень хорошей. Тем не менее для задач, критичных ко времени выполнения, которые способны сами обеспечивать эффективные блокировки, использование механизма softirq — будет правильным решением.
Отложенные прерывания должны объявляться на этапе компиляции с помощью соответствующего перечисления (
Создание нового отложенного прерывания состоит в добавлении новой записи в этот перечень (
Таблица 7.2. Список отложенных прерываний
Отложенное прерывание | Приоритет | Описание |
---|---|---|
HI_SOFTIRQ | 0 | Высокоприоритетные тасклеты |
TIMER_SOFTIRQ | 1 | Обработчик нижних половин таймеров |
NET_TX_SOFTIRQ | 2 | Отправка сетевых пакетов |
NET_RX_SOFTIRQ | 3 | Прием сетевых пакетов |
SCSI_SOFTIRQ | 4 | Обработчик нижних половин подсистемы SCSI |
TASKLET_SOFTIRQ | 5 | Тасклеты |
Далее во время выполнения должен быть зарегистрирован обработчик отложенного прерывания с помощью вызова
Обработчик отложенного прерывания выполняется при разрешенных прерываниях и не может переходить в состояние ожидания (sleep). Во время выполнения обработчика отложенные прерывания на данном процессоре запрещаются. Однако на другом процессоре обработчики отложенных прерываний могут выполняться. На самом деле, если вдруг генерируется отложенное прерывание в тот момент, когда выполняется его обработчик, то такой же обработчик может быть запущен на другом процессоре одновременно с первым обработчиком. Это означает, что любые совместно используемые данные, которые используются в обработчике отложенного прерывания, и даже глобальные данные, которые используются только в самом обработчике, должны соответствующим образом блокироваться (как показано в следующих двух разделах). Это очень важный момент, и именно по этой причине использование тасклетов обычно предпочтительнее. Простое предотвращение конкурентного выполнения обработчиков — это далеко не идеал. Если обработчик отложенного прерывания просто захватит блокировку, которая предотвращает его выполнение параллельно самому себе, то для использования отложенных прерываний не остается почти никакого смысла. Следовательно, большинство обработчиков отложенных прерываний используют данные, уникальные для каждого процессора (и следовательно, не требующие блокировок), или какие-нибудь другие ухищрения, чтобы избежать явного использования блокировок и обеспечить отличную масштабируемость.
Главная причина использования отложенных прерываний — масштабируемость. Если нет необходимости масштабироваться на бесконечное количество процессоров, то лучше использовать механизм тасклетов. Тасклеты — это отложенные прерывания, для которых обработчик не может выполняться параллельно на нескольких процессорах.
После того как обработчик добавлен в перечень и зарегистрирован с помощью вызова
Этот вызов сгенерирует отложенное прерывание с индексом