Чтение онлайн

на главную - закладки

Жанры

Разработка ядра Linux
Шрифт:

Давайте продолжим рассмотрение каждого из механизмов в отдельности, пользуясь этой устойчивой путаницей в названиях.

Механизм отложенных прерываний (softirq)

Обсуждение существующих методов обработки нижних половин начнем с механизма softirq. Обработчики на основе механизма отложенных прерываний используются редко. Тасклеты — это более часто используемая форма обработчика нижних половин. Поскольку тасклеты построены на основе механизма softirq, с механизма softirq и стоит начать. Код, который касается обработчиков отложенных прерываний, описан в файле

kernel/softirq.c
.

Реализация отложенных прерываний

Отложенные

прерывания определяются статически во время компиляции. В отличие от тасклетов, нельзя динамически создать или освободить отложенное прерывание. Отложенные прерывания представлены с помощью структур
softirq_action
, определенных в файле
<linux/interrupt.h>
в следующем виде.

/*

* структура, представляющая одно отложенное прерывание

*/

struct softirq_action {

 void (*action)(struct softirq_action*);

/* функция, которая должна выполниться */

 void *data; /* данные для передачи в функцию */

};

Массив из 32 экземпляров этой структуры определен в файле

kernel/softirq.с
в следующем виде.

static struct softirq_action softirq_vec[32];

Каждое зарегистрированное отложенное прерывание соответствует одному элементу этого массива. Следовательно, имеется возможность создать 32 обработчика softirq. Заметим, что это количество фиксировано. Максимальное число обработчиков softirq не может быть динамически изменено. В текущей версии ядра из 32 элементов используется только шесть [37] .

37

Большинство драйверов использует для обработки своих нижних половин механизм тасклетов. Тасклеты построены на механизме softirq, как это будет показано ниже.

Обработчик softirq

Прототип обработчика отложенного прерывания, поля

action
, выглядит следующим образом.

void softirq_handler(struct softirg_action*);

Когда ядро выполняет обработчик отложенного прерывания, то функция

action
вызывается С указателем на соответствующую структуру
softirq_action
в качестве аргумента. Например, если переменная
my_softirq
содержит указатель на элемент массива
softirq_vec
, то ядро вызовет функцию-обработчик соответствующего отложенного прерывания в следующем виде.

my_softirq->action(my_softirq);

Может быть, несколько удивляет, что ядро передает в обработчик указатель на всю структуру, а не только на поле data. Этот прием позволяет в будущем вводить дополнительные поля в структуру без необходимости внесения изменений в существующие обработчики. Обработчик может получить доступ к значению ноля

data
простым разыменованием указателя на структуру и чтением ее поля
data
.

Обработчик одного отложенного прерывания никогда не вытесняет другой обработчик 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
.

38

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

• Если первый бит маски, которая хранится в переменной

pending
, установлен, то вызывается функция
h->action(h)
.

• Указатель

h
увеличивается на единицу, и теперь он указывает на второй элемент массива
softirq_vec
.

• Осуществляется логический сдвиг битовой маски, хранящейся в переменной

pending
, вправо на один разряд. Эта операция отбрасывает самый младший бит и сдвигает все оставшиеся биты на одну позицию вправо. Следовательно, второй бит теперь стал первым и т.д.

Поделиться:
Популярные книги

Сумеречный стрелок 8

Карелин Сергей Витальевич
8. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Сумеречный стрелок 8

Мимик нового Мира 13

Северный Лис
12. Мимик!
Фантастика:
боевая фантастика
юмористическая фантастика
рпг
5.00
рейтинг книги
Мимик нового Мира 13

Отмороженный 10.0

Гарцевич Евгений Александрович
10. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный 10.0

Бывший муж

Рузанова Ольга
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Бывший муж

Безнадежно влип

Юнина Наталья
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Безнадежно влип

Гром над Академией Часть 3

Машуков Тимур
4. Гром над миром
Фантастика:
фэнтези
5.25
рейтинг книги
Гром над Академией Часть 3

Убийца

Бубела Олег Николаевич
3. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.26
рейтинг книги
Убийца

По осколкам твоего сердца

Джейн Анна
2. Хулиган и новенькая
Любовные романы:
современные любовные романы
5.56
рейтинг книги
По осколкам твоего сердца

Жена фаворита королевы. Посмешище двора

Семина Дия
Фантастика:
фэнтези
5.00
рейтинг книги
Жена фаворита королевы. Посмешище двора

Последняя Арена 7

Греков Сергей
7. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 7

Возвращение Безумного Бога 4

Тесленок Кирилл Геннадьевич
4. Возвращение Безумного Бога
Фантастика:
фэнтези
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Возвращение Безумного Бога 4

Варлорд

Астахов Евгений Евгеньевич
3. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Варлорд

Авиатор: назад в СССР

Дорин Михаил
1. Авиатор
Фантастика:
попаданцы
альтернативная история
5.25
рейтинг книги
Авиатор: назад в СССР

Кодекс Охотника. Книга III

Винокуров Юрий
3. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Кодекс Охотника. Книга III