Обработчик одного отложенного прерывания никогда не вытесняет другой обработчик softirq. Б действительности, единственное событие, которое может вытеснить обработчик softirq, — это аппаратное прерывание. Однако на другом процессоре одновременно с обработчиком отложенного прерывания может выполняться другой (и даже этот же) обработчик отложенного прерывания.
Выполнение отложенных прерываний
Зарегистрированное отложенное прерывание должно быть отмечено для того, чтобы его можно было выполнить. Это называется генерацией отложенного прерывания ( rise softirq ). Обычно обработчик аппаратного прерывания перед возвратом отмечает свои обработчики отложенных прерываний. Затем в подходящий момент времени отложенное прерывание выполняется. Ожидающие выполнения обработчики отложенных прерываний проверяются и выполняются в следующих ситуациях.
• После обработки аппаратного прерывания.
• В контексте потока пространства ядра ksoftirqd
.
• В любом коде ядра, который явно проверяет и выполняет ожидающие обработчики отложенных прерываний, как, например, это делает сетевая подсистема.
Независимо от того, каким способом выполняется отложенное прерывание, его выполнение осуществляется в функции do_softirq()
. Эта функция по-настоящему проста. Если есть ожидающие отложенные прерывания, то функция do_softirq()
в цикле проверяет их все и вызывает ожидающие обработчики. Давайте рассмотрим упрощенный вариант наиболее важной части функции do_softirq()
.
u32 pending = softirq_pending(cpu);
if (pending) {
struct softirq_action *h = softirq_vec;
softirq_pending(cpu) = 0;
do {
if (pending & 1)
h->action(h);
h++;
pending >>= 1;
} while (pending);
}
Этот фрагмент кода является сердцем обработчика отложенных прерываний. Он проверяет и выполняет все ожидающие отложенные прерывания.
• Присваивает локальной переменной pending значение, возвращаемое макросом softirq_pending()
. Это значение — 32-х разрядная битовая маска ожидающих на выполнение отложенных прерываний. Если установлен бит с номером n
, то отложенное прерывание с этим номером ожидает на выполнение.
• Когда значение битовой маски отложенных прерываний сохранено, оригинальная битовая маска очищается [38] На самом деле эта операция выполняется при всех запрещенных на локальном процессоре прерываниях, что не показано в упрощенной версии. Если бы прерывания не были запрещены, то в период времени между сохранением и очисткой маски могло бы быть сгенерировано новое отложенное прерывание (которое бы ожидало на выполнение), что привело бы к неверной очистке бита соответствующего отложенного прерывания.
.
• Переменной h
присваивается указатель на первый элемент массива softirq_vec
.
• Если первый бит маски, которая хранится в переменной pending
, установлен, то вызывается функция h->action(h)
.
• Указатель h
увеличивается на единицу, и теперь он указывает на второй элемент массива softirq_vec
.
• Осуществляется логический сдвиг битовой маски, хранящейся в переменной pending
, вправо на один разряд. Эта операция отбрасывает самый младший бит и сдвигает все оставшиеся биты на одну позицию вправо. Следовательно, второй бит теперь стал первым и т.д.
• Указатель h
теперь указывает на второй элемент массива, а в битовой маске — второй бит стал первым. Теперь необходимо повторить все ранее проделанные шаги.
• Последовательное повторение производится до тех пор, пока битовая маска не станет равной нулю. В этот момент больше нет ожидающих отложенных прерываний, и наша работа выполнена. Заметим, что такой проверки достаточно для того, чтобы гарантировать, что указатель h
всегда указывает на законную запись в массиве softirq_vec
, так как битовая маска pending имеет 32 бит и цикл не может выполниться больше 32 раз.
Использование отложенных прерываний
Отложенные прерывания зарезервированы для наиболее важных и критичных ко времени выполнения обработчиков нижних половин в системе. Сейчас только две подсистемы — подсистема SCSI и сетевая подсистема — напрямую используют механизм softirq. В дополнение к этому, таймеры ядра и тасклеты построены на базе отложенных прерываний. Если есть желание добавить новое отложенное прерывание, то стоит себя спросить, почему будет недостаточно использования тасклетов. Тасклеты могут создаваться динамически, а также их легче использовать в связи с более простыми требованиями к блокировкам. Кроме того, их производительность все еще остается очень хорошей. Тем не менее для задач, критичных ко времени выполнения, которые способны сами обеспечивать эффективные блокировки, использование механизма softirq — будет правильным решением.
Читать дальше