Что такое прерывания linux

Обработчики прерываний

Везде, кроме последней главы, все, что мы пока делали в ядре, сводилось к запросам и ответам разным процессам или работали со специальными файлом, посылали ioctl или выдавали системный вызов. Но работа ядра не должна сводится только к обработке запросы. Другая задача, которая является очень важной, сводится к работе с аппаратными средствами, связанными с машиной.

Имеются два типа взаимодействия между CPU и остальной частью аппаратных средств компьютера. Первый тип, когда CPU дает команды аппаратным средствам, другой, когда аппаратные средства должны сообщить что-то CPU. Второй, названный прерываниями, является намного более тяжелым в работе, потому что с ним нужно иметь дело когда удобно аппаратным средствам, а не CPU. Аппаратные устройства обычно имеют очень маленькое количество ОЗУ, и если Вы не читаете их информацию сразу, она теряется.

Под Linux аппаратные прерывания названы IRQ (сокращение от Interrupt Requests) 11.1 . Имеется два типа IRQ: короткий и длинный. Короткий IRQ тот, который займет очень короткий период времени, в течение которого остальная часть машины будет блокирована, и никакие другие прерывания не будут обработаны. Длинный IRQ тот, который может занять более длительное время, в течение которого другие прерывания могут происходить (но не прерывания из того жесамого устройства). Если возможно, лучше объявить, что программа обработки прерывания будет длинной.

Когда CPU получает прерывание, он останавливает любые процессы (если это не более важное прерывание, тогда обработка пришедшего прерывания будет иметь место только когда более важное будет выполнено), сохраняет параметры в стеке и вызывает программу обработки прерывания (обработчик прерывания). Это означает, что некоторые вещи не позволяются в программе обработки прерывания непосредственно, потому что система находится в неизвестном состоянии. Решение для этой проблемы: программа обработки прерывания, должна разобраться что должно быть выполнено немедленно (обычно чтение чего-то из аппаратных средств или посылка чего-либо аппаратным средствам), затем запланировать обработку новой информации в более позднее время (это названо «нижней половиной») и вернуть управление. Ядро гарантирует вызов нижней половины как можно скорее. Когда оно это сделает, все позволенное в модулях будет доступно нашему обработчику.

Способ выполнять это состоит в том, чтобы вызвать request_irq для получения нашей программы обработки прерывания, вызванную, когда релевантное IRQ получено (их имеется 16 на платформах Intel). Эта функция получает IRQ номер, имя функции, флажки, имя для /proc/interrupts и параметр для для вызова обработчика прерываний. Флажки могут включать SA_SHIRQ , чтобы указать, что вы желаете совместно использовать IRQ с другими программами обработки прерывания (обычно, потому что ряд аппаратных устройств сидит на том же самом IRQ) и SA_INTERRUPT , чтобы указать, что это быстрое прерывание. Эта функция сработает только если еще нет драйвера на этом IRQ, или если вы оба желаете совместно использовать данный IRQ.

Затем, из программы обработки прерывания, мы связываемся с аппаратными средствами и затем используем queue_task_irq с tq_immediate и mark_bh(BH_IMMEDIATE) , чтобы запланировать нижнюю половину. Причина по которой мы не можем использовать стандартный вызов queue_task в версии 2.0 в том, что прерывание могло бы случиться в середине какого-то процесса. queue_task 11.2 . mark_bh нужен потому что более ранние версии Linux имели массив только из 32 нижних частей, и теперь одни из них (а именно BH_IMMEDIATE ) используется для связанного списка нижних частей драйверов.

Источник

Исходники

Другое

Глава 11. Обработка прерываний

11.1. Обработка прерываний

Везде, кроме предыдущей главы, все наши действия в ядре сводилось к ответам на разные запросы от процессов, к работе со специальными файлом, посылке команд ioctl или запуску системных вызовов. Однако работа ядра не может сводится только к обработке запросов. Еще одна немаловажная задача — это работа с аппаратурой компьютера.

Существует два типа взаимодействий между CPU и остальной аппаратной частью компьютера. Первый — передача команд аппаратным средствам, второй — прием ответов от аппаратуры. Второй тип взаимодействия — прерывания, является наиболее тяжелым в обработке, потому что прерывания возникают тогда, когда это удобно устройству, а не CPU. Аппаратные устройства обычно имеют весьма ограниченный объем ОЗУ, и если не считать поставляемую ими информацию немедленно, то она может потеряться.

Читайте также:  Windows media player как отключить субтитры

В Linux аппаратные прерывания называются IRQ (сокращенно от Interrupt ReQuests — Запросы на Прерывание). [14] Имеется два типа IRQ: «короткие» и «длинные». «Короткие» IRQ занимают очень короткий период времени, в течение которого работа операционной системы будет заблокирована, а так же будет невозможна обработка других прерываний. «Длинные» IRQ могут занять довольно продолжительное время, в течение которого могут обрабатываться и другие прерывания (но не прерывания из того же самого устройства). Поэтому, иногда бывает благоразумным разбить выполнение работы на исполняемую внутри обработчика прерываний (т.е. подтверждение прерывания, изменение состояния и пр.) и работу, которая может быть отложена на некоторое время (например постобработка данных, активизация процессов, ожидающих эти данные и т.п.). Если это возможно, лучше объявлять обработчики прерывания «длинными».

Когда CPU получает прерывание, он останавливает любые процессы (если это не более приоритетное прерывание, тогда обработка пришедшего прерывания произойдет только тогда, когда более приоритетное будет завершено), сохраняет некоторые параметры в стеке и вызывает обработчик прерывания. Это означает, что не все действия допустимы внутри обработчика прерывания, потому что система находится в неизвестном состоянии. Решение проблемы: обработчик прерывания определяет — что должно быть сделано немедленно (обычно что-то прочитать из устройства или что-то послать ему), а затем запланировать обработку поступившей информации на более позднее время (это называется «bottom halves» — «нижние половины») и вернуть управление. Ядро гарантирует вызов «нижней половины» так быстро, насколько это возможно. Когда это произойдет, то наш обработчик — «нижняя половина», уже не будет стеснен какими-то рамками и ему будет доступно все то, что доступно обычным модулям ядра.

Устанавливается обработчик прерывания вызовом request_irq. Ей передаются номер IRQ, имя функции-обработчика, флаги, имя для /proc/interrupts и дополнительный параметр для обработчика прерываний. Флаги могут включать SA_SHIRQ, чтобы указать, что прерывание может обслуживаться несколькими обработчиками (обычно, по той простой причине, что на одном IRQ может «сидеть» несколько устройств) и SA_INTERRUPT, чтобы указать, что это «короткое» прерывание. Эта функция установит обработчик только в том случае, если на заданном IRQ еще нет обработчика прерывания, или если существующий обработчик зарегистрировал совместную обработку прерывания флагом SA_SHIRQ.

Во время обработки прерывания, из функции-обработчика прерывания, мы можем получить данные от устройства и затем, с помощью queue_task_irq, tq_immediate и mark_bh(BH_IMMEDIATE), запланировать «нижнюю половину». В ранних версиях Linux имелся массив только из 32 «нижних половин», теперь же, одна из них (а именно BH_IMMEDIATE) используется для обслуживания целого списка «нижних половин» драйверов. Вызов mark_bh(BH_IMMEDIATE) как раз и вставляет «нижнюю половину» драйвера в этот список, планируя таким образом ее исполнение.

11.2. Клавиатура на архитектуре Intel

Материал, рассматриваемый в оставшейся части этой главы, может быть применим исключительно к архитектуре Intel. На других платформах код примера работать не будет.

Было очень трудно выбрать тип драйвера, который можно было бы использовать в качестве примера в этой главе. С одной стороны пример должен быть достаточно полезным, он должен работать на любом компьютере и быть достаточно выразительным. С другой стороны, в ядро уже включено огромное количество драйверов практически для всех общеизвестных и широкораспространенных устройств. Эти драйверы не смогли бы совместно работать с тем, что я собирался написать. Наконец я принял решение представить в качестве примера — обработчик прерываний от клавиатуры, но для демонстрации работоспособности кода сначала придется отключить стандартный обработчик прерываний от клавиатуры, а так как этот символ объявлен как static (в файле drivers/char/keyboard.c), то нет никакого способа восстановить обработчик. Поэтому, прежде чем вы дадите команду insmod, перейдите в другую консоль и дайте команду sleep 120; reboot, если ваша файловая система представляет для вас хоть какую-нибудь ценность.

Этот пример захватывает обработку IRQ 1 — прерывание от клавиатуры на архитектуре Intel. При получении прерывания обработчик читает состояние клавиатуры (inb(0x64)) и скан-код нажатой клавиши. Затем, как только ядро сочтет возможным, оно вызывает got_char (она играет роль «нижней половины»), которая выводит, через printk, код клавиши (младшие семь бит скан-кода) и признак «нажата/отпущена» (8-й бит скан-кода — 0 или 1 соответственно).

Источник

Большие потоки трафика и управление прерываниями в Linux

В этой заметке я опишу методы увеличения производительности линуксового маршрутизатора. Для меня эта тема стала актуальна, когда проходящий сетевой трафик через один линуксовый маршрутизатор стал достаточно высоким (>150 Мбит/с, > 50 Kpps). Маршрутизатор помимо роутинга еще занимается шейпированием и выступает в качестве файрволла.

Читайте также:  Лучший распаковщик архивов для windows 10

Для высоких нагрузок стоит использовать сетевые карты Intel, на базе чипсетов 82575/82576 (Gigabit), 82598/82599 (10 Gigabit), или им подобные. Их прелесть в том, что они создают восемь очередей обработки прерываний на один интерфейс – четыре на rx и четыре на tx (возможно технологии RPS/RFS, появившиеся в ядре 2.6.35 сделают то же самое и для обычных сетевых карт). Также эти чипы неплохо ускоряют обработку трафика на аппаратном уровне.
Для начала посмотрите содержимое /proc/interrupts , в этом файле можно увидеть что вызывает прерывания и какие ядра занимаются их обработкой.

В данном примере используются сетевые карты Intel 82576. Здесь видно, что сетевые прерывания распределены по ядрам равномерно. Однако, по умолчанию так не будет. Нужно раскидать прерывания по процессорам. Чтобы это сделать нужно выполнить команду echo N > /proc/irq/X/smp_affinity , где N это маска процессора (определяет какому процессору достанется прерывание), а X — номер прерывания, виден в первом столбце вывода /proc/interrupts. Чтобы определить маску процессора, нужно возвести 2 в степень cpu_N (номер процессора) и перевести в шестнадцатиричную систему. При помощи bc вычисляется так: echo «obase=16; $[2 ** $cpu_N]» | bc . В данном примере распределение прерываний было произведено следующим образом:

Также, если маршрутизатор имеет два интерфейса, один на вход, другой на выход (классическая схема), то rx с одного интерфейса следует группировать с tx другого интерфейса на одном ядре процессора. Например, в данном случае прерывания 46 (eth0-rx-0) и 59 (eth1-tx-0) были определены на одно ядро.
Еще одним весьма важным параметром является задержка между прерываниями. Посмотреть текущее значение можно при помощи ethtool -c ethN , параметры rx-usecs и tx-usecs. Чем больше значение, тем выше задержка, но тем меньше нагрузка на процессор. Пробуйте уменьшать это значение в часы пик вплоть до ноля.
При подготовке в эксплуатацию сервера с Intel Xeon E5520 (8 ядер, каждое с HyperThreading) я выбрал такую схему распределения прерываний:

/proc/interrupts на этом сервере без нагрузки можно посмотреть тут. Не привожу это в заметке из-за громоздкости

UPD:
Если сервер работает только маршрутизатором, то тюнинг TCP стека особого значения не имеет. Однако есть параметры sysctl, которые позволяют увеличить размер кэша ARP, что может быть актуальным. При проблеме с размером ARP-кэша в dmesg будет сообщение «Neighbour table overflow».
Например:
net.ipv4.neigh.default.gc_thresh1 = 1024
net.ipv4.neigh.default.gc_thresh2 = 2048
net.ipv4.neigh.default.gc_thresh3 = 4096

Описание параметров:
gc_thresh1 — минимальное количество записей, которые должны быть в ARP-кэше. Если количество записей меньше, чем это значение, то сборщик мусора не будет очищать ARP-кэш.
gc_thresh2 — мягкое ограничение количества записей в ARP-кэше. Если количество записей достигнет этого значения, то сборщик мусора запустится в течение 5 секунд.
gc_thresh3 — жесткое ограничение количества записей в ARP-кэше. Если количество записей достигнет этого значения, то сборщик мусора незамедлительно запустится.

Источник

Прерывания

Прерывания позволяют аппаратным устройствам взаимодействовать с процессором. Например, при наборе на клавиатуре контроллер клавиатуры (или другое устройство, которое обслуживает клавиатуру) генерирует прерывание, чтобы объявить операционной системе о том, что произошли нажатия клавиш. Прерывания — это специальные электрические сигналы, которые аппаратные устройства посылают процессору. Процессор получает прерывание и дает сигнал операционной системе о том, что ОС может обработать новые данные. Аппаратные устройства генерируют прерывания асинхронно по отношению к тактовому генератору процессора — прерывания могут возникать непредсказуемо, в любой момент времени. Следовательно, работа ядра может быть прервана в любой момент для того, чтобы обработать прерывания.

Физически прерывания производятся электрическими сигналами, которые создаются устройствами и направляются на входные контакты микросхемы контроллера прерываний. Контроллер прерываний в свою очередь отправляет сигнал процессору. Процессор выполняет детектирование сигнала и прерывает выполнение работы для того, чтобы обработать прерывание. После этого процессор извещает операционную систему о том, что произошло прерывание и операционная система может соответствующим образом это прерывание обработать.

Различные устройства связаны со своими прерываниями с помощью уникальных числовых значений, соответствующих каждому прерыванию. Отсюда следует, что прерывания, поступившие от клавиатуры, отличаются от прерываний, поступивших от жесткого диска. Это позволяет операционной системе различать прерывания и иметь информацию о том, какое аппаратное устройство произвело данное прерывание. Поэтому операционная система может обслуживать каждое прерывание с помощью своего уникального обработчика.

Идентификаторы, соответствующие прерываниям, часто называются линиями запросов на прерывание (interrupt request lines, IRQ lines). Обычно это некоторые числа. Например, для платформы PC значение IRQ, равное 0, — это прерывание таймера, a IRQ, равное 1, — прерывание клавиатуры. Однако не все номера прерываний жестко определены. Прерывания, связанные с устройствами шины PCI, например, назначаются динамически. Другие платформы, которые не поддерживают стандарт PCI, имеют аналогичные функции динамического назначения номеров прерываний. Основная идея состоит в том, что определенные прерывания связаны с определенными устройствами, и у ядра есть вся эта информация. Аппаратное обеспечение, чтобы привлечь внимание ядра, генерирует прерывание вроде «Эй! Было новое нажатие клавиши! Его необходимо обработать!».

Исключительные ситуации (exceptions) часто рассматриваются вместе с прерываниями. В отличие от прерываний, они возникают синхронно с тактовым генератором процессора. И действительно, их часто называют синхронными прерываниями. Исключительные ситуации генерируются процессором при выполнении машинных инструкций как реакция на ошибку программы (например, деление на нуль) или как реакция на аварийную ситуацию, которая может быть обработана ядром (например, прерывание из-за отсутствия страницы, page fault). Так как большинство аппаратных платформ обрабатывают исключительные ситуации аналогично обработке прерываний, то инфраструктуры ядра, для обоих видов обработки, также аналогичны. Большая часть материала, посвященная обработке прерываний (асинхронных, которые генерируются аппаратными устройствами), также относится и к исключительным ситуациям (синхронным, которые генерируются самим процессором).

Читайте также:  Создание групп пользователей линукс

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

Читайте также

Прерывания

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

Регистрация обработчика прерывания

Регистрация обработчика прерывания Ответственность за обработчики прерываний лежит на драйверах устройств, которые управляют определенным типом аппаратного обеспечения. С каждым устройством связан драйвер, и если устройство использует прерывания (а большинство

Освобождение обработчика прерывания

Освобождение обработчика прерывания Для освобождения линии прерывания необходимо вызвать функциюvoid free_irq(unsigned int irq, void *dev_id);Если указанная линия не является совместно используемой, то эта функция удаляет обработчик и запрещает линию прерывания. Если линия запроса на

Контекст прерывания

Контекст прерывания При выполнении обработчика прерывания или обработчика нижней половины, ядро находится в контексте прерывания. Вспомним, что контекст процесса — это режим, в котором работает ядро, выполняя работу от имени процесса, например выполнение системного

Прерывания

Прерывания В этой главе вы научитесь писать обработчики прерываний для QNX/Neutrino и узнаете, как обработчики прерываний влияют на диспетчеризацию

QNX/Neutrino и прерывания

QNX/Neutrino и прерывания В данной главе мы рассмотрим прерывания, как с ними работать в QNX/Neutrino, их воздействие на диспетчеризацию и режим реального времени, а также некоторые стратегии их использования.Первый вопрос, который приходит на ум: «А что такое прерывание?»Прерывание

Подпрограмма обработки прерывания

Подпрограмма обработки прерывания Обработчик прерывания (ISR) представляет собой фрагмент кода, ответственный за очистку источника прерывания.Это ключевой момент, особенно с учетом того, что прерывание имеет приоритет выше, чем приоритет любой программы. Это означает,

Отключение обработчика прерывания

Отключение обработчика прерывания Когда вы закончили с обработчиком прерывания, вы можете пожелать уничтожить связь между ним и вектором:int InterruptDetach(int id);Я сказал «можете», потому что обрабатывающие прерывания потоки, как правило, используются в серверах, а серверы

Обработчик прерывания

Обработчик прерывания Давайте рассмотрим собственно обработчик прерывания. В первом примере применим InterruptAttach(), а затем рассмотрим аналогичный случай, только с применением функции InterruptAttachEvent().Применение функции InterruptAttach()В продолжение примера приведем функцию intHandler()

Исключения, события и прерывания

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

1.5.1 Прерывания и особые ситуации

1.5.1 Прерывания и особые ситуации Система UNIX позволяет таким устройства, как внешние устройства ввода-вывода и системные часы, асинхронно прерывать работу центрального процессора. По получении сигнала прерывания ядро операционной системы сохраняет свой текущий

1.5.2 Уровни прерывания процессора

1.5.2 Уровни прерывания процессора Ядро иногда обязано предупреждать возникновение прерываний во время критических действий, могущих в случае прерывания запортить информацию. Например, во время обработки списка с указателями возникновение прерывания от диска для ядра

6.4.1 Прерывания и особые ситуации

6.4.1 Прерывания и особые ситуации Система отвечает за обработку всех прерываний, поступили ли они от аппаратуры (например, от таймера или от периферийных устройств), от программ (в связи с выполнением инструкций, вызывающих возникновение «программных прерываний») или

Источник

Оцените статью