- •Лекция 1. 7.02.2014
- •Монтирование файловой системы.
- •Лекция 2. 10.02.2014
- •Лекция 3. 17.02.2014
- •Открытые файлы.
- •Лекция 4. 24.02.2014
- •Лекция 5. 3.03.2014 Файлы.
- •Регистрация и дерегистрация фс
- •Лекция 6. 17.03.2014
- •Организация виртуальной файловой системы (vfs)
- •Функции для работы с элементами фс proc.
- •Лекция 7. 24.03.2014
- •Файловая система specfs.
- •Терминалы.
- •Терминальный ввод-вывод.
- •Лекция 8. 31.03.2014
- •Типы флагов структуры termios.
- •Принятые соглашения и стандарты.
- •Простые способы открытия псевдотерминалов.
- •Лекция 9. 7.04.2014
- •Лекция 10. 14.04.2014
- •Реализация доступа к устройствам.
- •Структура контроллера внешнего устройства.
- •Южный и северный мосты.
- •Последовательные и параллельные интерфейсы.
- •Лекция 11. 21.04.2014
- •Управление вводом-выводом.
- •Прерывания.
- •Лекция 12. 28.04.2014 Контроллер прерывания.
- •Лекции 13-14. 5.05.2014, 12.05.2014
- •Проблемы прямого доступа к памяти.
- •Управление устройствами.
- •Многослойная модель системы ввода-вывода.
- •Пространство имен устройств.
- •Доступ к драйверу символьного устройства.
- •Доступ к драйверу блочного устройства.
- •Дополнительная информация о драйверах.
- •Лекция 15. 19.05.2014
- •Типичные точки входа в драйвер устройства.
- •Файлы устройств.
- •Буферизация ввода-вывода.
- •Схемы обменной буферизации
- •Обслуживание прерываний.
- •Лекция 16. 26.05.14
- •Лекция 17. 02.06.14
Лекция 16. 26.05.14
Супервизор – операционная система в стадии выполнения.
Лист 1 (из прошлого семестра) – ввод/вывод
Для того, чтобы передать команду устройству ввода-вывода, нужен драйвер. Это может быть многоуровневый драйвер с какими-то драйверными фильтрами.
Разрыв на рисунке возникает потому что фактически система отключается от управления устройством и передает управление контроллеру. Возобновит работу при получении сигнала прерывания от устройства ввода-вывода.
Задействован обработчик прерываний. Обработчики прерываний входят в состав драйверов соответствующих устройств.
В системе бывают быстрые и медленные прерывания. Быстрые прерывания выполняют какой-то очень незначительный набор действий и не задерживают выполнение других действий в системе.
Вложенные прерывания связаны с дополнительной опасностью в системе. В современных системах все усложняется тем, что каждый процессор выполняет собственные прерывания. На разных процессорах могут выполняться обработчики одного и того же прерывания. Возникает опасность взаимоблокировок в ядре. Это очень большая проблема, поэтому все системы пытаются уйти от этого следующим образом. Тот код, который необходимо выполнить, чтобы обслужить запрос, делятся на две части: top half и bottom half.
Аппаратное прерывание может потенциально прерывать выполнение другого важного кода, даже другие обработчики прерываний. Поэтому обработчики прерываний не могут долго выполнять большое количество действий и именно поэтому, чтобы сократить количество выполняемых действий на высоком уровне приоритета, обработчики прерываний делятся на две части.
Топ-халф, как правило, делает: почти всегда обработчик должен отправить устройству уведомление, что прерывание получено, затем необходимо скопировать данные из регистров устройства, поскольку данная работа чувствительна ко времени. Копирование данных должно выполняться как можно быстрее, поэтому оно выполняется в топе. Кроме того, верхняя половина выполняется при запрещенных (всех или части) прерываниях локального процессора. Перед своим завершением топ активизирует отложенное выполнение нижней половины, которая выполнит оставшуюся часть работы прерывания. Активизирует значит ставит в DPC (очередь на выполнение). Функция верхней половины завершаются return и ядро завершает взаимодействие с аппаратурой контроллера прерывания и разрешает последующие прерывания, восстанавливая маску прерываний контроллера командой iret. После этого отложенная и запланированная нижняя половина будет выполнена ядром позже. Она будет выполнена в контексте ядра при разрешенных прерываниях, что в итоге увеличивает производительность системы с точки зрения пользователя (время отклика), так как появляется возможность реагировать на высокоскоростные прерывания.
Названия top-half и bottom-half – это дословные названия старой схемы, которая в современных версиях Линукс отсутствует. Все новые схемы реализации обработчиков нижней половины построены на ее выполнении отдельным потоком ядра. Для реализации обработчиков нижних половин существует несколько механизмов в Линукс:
Начиная с ядра 2.3 стали доступны softirq. Набор softirq функций состоит из 32-ух статически определенных конструктивов нижней половины. Код этих функций находится в файле ./kernel/softirq.c
Уже в ядре 2.3, но обычно рассматривается ядро 2.6, реализованы тасклеты (tasklets). ./include/linux/interrupt.h. Как говорят, тасклеты базируются на softirq функциях, но у них есть важные отличия.
В ядре 2.5 были введены очереди работ (work queues в ./include/linux/workqueue.h). Очереди работ выполняют действия, которые были отложены из контекста прерывания в контексте процесса ядра.
Softirq.
Описываются структурой
struct softirq_action { // находится в linux/interrup.h
void (*action)(struct softirq_atcion *);
}
Фактически определены в виде массива из 32 экземпляров данной структуры. При этом максимальное количество softirq не может быть изменено, а добавление нового обработчика softirq требует перекомпиляции ядра. При этом отложенные прерывания softirq с меньшим номером выполняются раньше прерываний с большими номерами, но обработчик одного softirq не вытесняет другой (то есть, обработчик выполняется с начала до конца). Единственное событие, которое может вытеснить softirq – это аппаратное прерывание. При этом на другом процессоре в архитектуре SMP может выполняться другой обработчик отложенного прерывания, причем это может быть тот же обработчик. В результате, очевидно, возможно возникновение проблем с взаимоисключением (что это?). Функция softirq должна быть реентерабельной (не зависим от данных, без переменных). А если в функции есть критический участок (обращение к разделяемым ресурсам), то он должен быть защищен. (Функция должна быть реентерабльной, потому что softirq может одновременно выполняться на разных процессорах, то есть разные процессы заинтересованы в выполнении softirq. Получается, что на каждом процессоре выполняется запущенный поток, чтобы выполнить код softirq, при этом softirq может находиться в разных точках.) Книга Лав.
Прототип обработчика отложенного прерывания:
void softirq_handler(struct softirq_action *);
Запускается функция action, которой в качестве параметра передается единственный указатель на структуру softirq_action.
Запуск отложенных прерываний. Перед тем, как зарегистрированное отложенное прерывание будет запущено, оно должно быть поставлено в очередь на выполнение. Этот процесс называется генерацией отложенного прерывание (rise). Как правило, так называемая маркировка отложенных прерываний для их запуска выполняется из топ-халф. Проверка ожидающих выполнения обработчиков отложенных прерываний и их запуск осуществляется в следующих случаях:
При возврате из обработчика аппаратного прерывания.
В контексте потока ядра ksoftirqd (реализован в виде демона). Таких демонов в системе будет столько, сколько процессоров.
В любом коде ядра, в котором явно проверяются и запускаются ожидающие обработчики отложенных прерываний, как, например, это делается в сетевой подсистеме.
Независимо от метода вызова отложенного прерывания, его выполнение осуществляется в функции _do_softirq(). В книге Лав на стр. 178 перечисляются 9 отложенных прерываний.
-
HI_SOFTIRQ
0
Высокоприоритетный таскл
TIMER_SOFTIRQ
1
Таймеры
NET_TX_SOFTIRQ
2
отправка сетевых пакетов
NET_RX_SOFTIRQ
3
прием сетевых пакетов
BLOCK_SOFTIRQ
4
блочные устройства
TASKLET_SOFTIRQ
5
тасклеты с обычным приоритетом
SHED_SOFTIRQ
6
планировщик
HRTIMER_SOFTIRQ
7
высокоточные таймеры
RCV_SOFTIRQ
8
RCV-блокировка
Регистрация обработчика.
Для регистрации обработчика softriq используется функция opensoftirq(). Ей передаются три параметра: индекс отложенного прерывания (в таблице), функция-обработчик и значение поля дата.
Пример:
opensofrtirq(NET_TX_SOFTIRQ, net_tx_action, NULL).
Тасклеты.
Тасклеты реализованы на основе softirq. Для них есть собственная структура. Тасклеты представлены двумя типами отложенных прерываний: HI_SOFTRQ и TASKLET_SOFTRIQ, Единственная разница между ними заключается в том, что тасклеты типа HI выполняются всегда раньше, чем тасклеты типа TASKLET.
В системе представляются структурой. Каждый экземпляр такой структуры представляет собой уникальный тасклет. Структура определена в linux/interrupt.h.
Планирование тасклетов на выполнение.
Запланированные (scheduled) на выполнение тасклеты хранятся в двух структурах, определенных для каждого процессора. В структуре tasklet_hi_ve высокоприоритетные тасклеты, в tasklet_ve – обычные тасклеты. Тасклеты могут быть запланированы на выполнение с помощью соответствующих функций: tasklet_hi_scheduled, tasklet_scheduled.
Отложенные прерывания и тасклеты (сравнение).
Отложенные прерывания используются для запуска самых важных и критичных по времени выполнения нижних половин (bottom half). В настоящий момент только в двух подсистемах, а именно в сетевой и подсистемы блочных устройств, напрямую используются softirq (отложенные прерывания). Кроме того, на основе softirq построены таймера ядра и сами тасклеты. Тасклеты имеют более простой интерфейс и упрощенные правила блокировок Это связано с тем, что два тасклета одного типа не могут выполняться одновременно на разных процессорах, но могут выполняться параллельно тасклеты разных типов. Тасклеты создаются динамически, в отличие от софтиэрку. Тасклеты являются хорошим компромиссом между производительностью и простотой использования. Тем не менее для задач, критичных ко времени выполнения и способных обеспечить эффективные блокировки, лучше (правильнее) использовать отложенные прерывания. При этом необходимо помнить, что софтиэрку выполняется при разрешенных прерываниях и не может переходить в состояние sleep. Другое отложенное прерывание не может прерывать выполнение отложенного прерывания. Отложенное прерывание может прервать только аппаратное прерывание. Поскольку софтиэрку одного типа могут одновременно выполняться на разных процессорах, взаимоисключение должно быть реализовано корректно и эффективно.
Коротко можно определить тасклет следующим образом. Тасклет - это, по сути, отложенное прерывания, для которого обработчик не может выполняться параллельно на нескольких процессорах.
Обслуживание прерываний Windows.
Картинка из Шоу (в начале лекции).
Завершая передачу данных (операцию ввода-вывода), устройство генерирует сигнал прерывания. Это прерывание поступает на выделенную ножку контроллера прерываний. В результате процессор передает управление обработчику ловушки (trap), который находит isr (interrupt service routine) для этого устройства по таблице IDT (interrupt descriptor table). Windows 2000 и так далее обычно обрабатывают прерывания в 2 этапа.
На первом этапе вызывается isr на уровне Device IRQL (interrupt request level), в течение времени, пока происходит сохранение состояния устройства и запрет дальнейших прерываний от этого устройства. Затем (см. Линукс top-half) isr помещает DPC (differed procedure call – отложенный вызов процедуры) в очередь, то есть, фактически, активизирует планирование DPC и завершается. При последующем вызове DPC процедуры драйвер устройства заканчивает обработку прерывания (см. Линукс bottom-half). После чего драйвер вызывает диспетчер ввода-вывода (см. картинку), которая завершает ввод-вывод и удаляет isr. (лист 4 – из Соломона). – первый этап
2 этап (лист 5): Для отложенной процедуры данного прерывания IRQL понижается до уровня DPC-диспатч.
DPC-процедура начинает обработку следующего запроса из очереди устройства, после чего заканчивает обработку прерывания.
