Запрещение и разрешение прерываний

Запрещение и разрешение прерываний

Для локального запрещения прерываний на текущем процессоре (и только на текущем процессоре) и последующего разрешения можно использовать следующий код.

local_irq_disable();

/* прерывания запрещены ... */

local_irq_enable();

Эти функции обычно реализуются в виде одной инструкции на языке ассемблера (что, конечно, зависит от аппаратной платформы). Для платформы x86 функция local_irq_disable() — это просто машинная инструкция cli, а функция local_irq_enable() — просто инструкция sti. Для хакеров, не знакомых с платформой x86, sti и cli — это ассемблерные вызовы, которые соответственно позволяют установить (set) или очистить (clear) флаг разрешения прерываний (allow interrupt flag). Другими словами, они разрешают или запрещают доставку прерываний на вызвавшем их процессоре.

Функция local_irq_disable() является опасной в случае, когда перед ее вызовом прерывания уже были запрещены. При этом соответствующий ей вызов функции local_irq_enable() разрешит прерывания независимо от того, были они запрещены первоначально (до вызова local_irq_disable()) или нет. Для того чтобы избежать такой ситуации, необходим механизм, который позволяет восстанавливать состояние системы обработки прерывании в первоначальное значение. Это требование имеет общий характер, потому что некоторый участок кода ядра в одном случае может выполняться при разрешенных прерываниях, а в другом случае— при запрещенных, в зависимости от последовательности вызовов функций. Например, пусть показанный фрагмент кода является частью функции. Эта функция вызывается двумя другими функциями, и в первом случае перед вызовом прерывания запрещаются, а во втором — нет. Так как при увеличении объема кода ядра становится сложно отслеживать все возможные варианты вызова функции, значительно безопаснее сохранять состояние системы прерываний перед тем, как запрещать прерывания. Вместо разрешения прерываний просто восстанавливается первоначальное состояние системы обработки прерываний следующим образом.

unsigned long flags;

local_irq_save(flags);

/* прерывания запрещены . . */

local_irq_restore(flags);

/* состояние системы прерываний восстановлено

   в первоначальное значение ... */

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

Все описанные функции могут вызываться как из обработчика прерываний, так и из контекста процесса.

Больше нет глобального вызова cli()

Ранее ядро предоставляло функцию, с помощью которой можно было запретить прерывания на всех процессорах системы. Более того, если какой-либо процессор вызывал эту функцию, то он должен был ждать, пока прерывания не будут разрешены. Эта функция называлась cli(), а соответствующая ей разрешающая функция — sti(); очень "x86-центрично" (хотя и было доступно для всех аппаратных платформ). Эти интерфейсы были изъяты во время разработки ядер серии 2.5, и, следовательно, все операции по синхронизации обработки прерываний должны использовать комбинацию функций по управлению локальными прерываниями и функций работы со спин-блокировками (обсуждаются в главе 9, "Средства синхронизации в ядре"). Это означает, что код, который ранее должен был всего лишь глобально запретить прерывания для того, чтобы получить монопольный доступ к совместно используемым данным, теперь должен выполнить несколько больше работы.

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

Изъятие глобальной функции cli() имеет несколько преимуществ. Во-первых, это подталкивает разработчиков драйверов к использованию настоящих блокировок. Специальные блокировки на уровне мелких структурных единиц работают быстрее, чем глобальные блокировки, к которым относится и функция cli(). Во-вторых, это упрощает значительную часть кода и позволяет удалить большой объем кода. В результате система обработки прерываний стала проще и понятнее.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

10.1.3 Программы обработки прерываний

Из книги Архитектура операционной системы UNIX автора Бах Морис Дж

10.1.3 Программы обработки прерываний Как уже говорилось выше (раздел 6.4.1), возникновение прерывания побуждает ядро запускать программу обработки прерываний, в основе алгоритма которой лежит соотношение между устройством, вызвавшим прерывание, и смещением в таблице


Практическое запрещение кэширования

Из книги Разгони свой сайт автора Мациевский Николай

Практическое запрещение кэширования Запретить кэширование можно и прямо из конфигурации Apache (подробная конфигурация для оптимальной производительности приводится в восьмой главе). Для этого нам нужны следующие строки:# Проверяем, что подключен mod_headers# Тогда выставляем


Запрещение/Разрешения на запуск программ

Из книги Реестр Windows автора Климов Александр

Запрещение/Разрешения на запуск программ Запрещение запуска программWindows позволяет ограничить доступ к программам, кроме разрешенных в специальном списке.Для ограничения запускаемых программ надо открыть раздел HKCUSOFTWAREMicrosoftWindowsCurrentVersonPoliciesExplorerи создать там ключ


Запрещение использования сеансов MS-DOS и однозадачного режима MS-DOS (Windows 98)

Из книги Реестр Windows автора Климов А

Запрещение использования сеансов MS-DOS и однозадачного режима MS-DOS (Windows 98) Windows позволяет открывать окно ms-dos и выполнять старые приложения ms-dos. Эта команда доступна в подменю Программы меню Пуск. Для запрета использования сеансов ms-dos откройте (создайте) раздел


Запрещение запуска программ

Из книги Энциклопедия разработчика модулей ядра Linux автора Померанц Ори

Запрещение запуска программ Windows позволяет ограничить доступ к программам, кроме разрешенных в специальном списке.Для ограничения запускаемых программ надо открыть раздел HKEY_CURRENT_USERSOFTWAREMicrosoftWindowsCurrentVersonPoliciesExplorer и создать там ключ RestrictRun типа DWORD со значением 0х00000001. Затем


Запрещение запуска редактора реестра

Из книги Тайм-менеджмент для системных администраторов автора Лимончелли Томас

Запрещение запуска редактора реестра Вы можете запретить запуск редактор реестраДля этого в разделе HKEY_CURRENT_USERSOFTWAREMicrosoftWindowsCurrentVersonPoliciesSystem нужно добавить ключ DisableRegistryTools со значением 0х00000001 типа DWORD. Запуск редактора реестра будет запрещен, однако останется возможность


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

Из книги Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform автора Кёртен Роб

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


Перенаправление прерываний

Из книги Операционная система UNIX автора Робачевский Андрей М.

Перенаправление прерываний Начнем с попытки устранить самое неприятное из возможных прерываний: к вам обращаются с проблемой, которую должен решить кто-то другой. Может быть, поступим так:— Том, проблема с веб-сервером.— Отлично! Сообщи мне о результатах, когда


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

Из книги Разработка ядра Linux автора Лав Роберт

Написание обработчиков прерываний Давайте посмотрим, как настроить обработчики прерываний — вызовы, характеристики и кое-какие стратегии


Подключение обработчиков прерываний

Из книги автора

Подключение обработчиков прерываний Для подключения к источнику прерывания воспользуйтесь функцией InterruptAttach() или InterruptAttachEvent().#include <sys/neutrino.h>int InterruptAttachEvent(int intr, const struct sigevent *event, unsigned flags);int InterruptAttach(int intr, const struct sigevent* (*handler)(void *area, int id), const void *area, int size, unsigned flags);Параметр


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

Из книги автора

Обработчики прерываний Обработчики прерываний в QNX4 могли либо возвратить идентификатор прокси (указывая этим, что надо переключить прокси и таким образом уведомить ее владельца о прерывании), либо возвратить нуль (что означало бы, что в дальнейшем ничего делать не


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

Из книги автора

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


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

Из книги автора

Обработчики прерываний Функция, которую выполняет ядро в ответ на определенное прерывание, называется обработчиком прерывания (interrupt handler) или подпрограммой обслуживания прерывания (interrupt service routine). Каждому устройству, которое генерирует прерывания, соответствует свой


Запрещение определенной линии прерывания

Из книги автора

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


Запрещение обработки нижних половин

Из книги автора

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


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

Из книги автора

Обработчик прерываний таймера Теперь, когда мы разобрались, что такое jiffies и HZ, а также какова роль системного таймера, рассмотрим реализацию обработчика прерываний системного таймера. Обработчик прерываний таймера разбит на две части: часть, зависимую от аппаратной