Так как прерывание может возникнуть в любой момент времени, то, соответственно, и обработчик прерывания может быть вызван в любой момент времени. Крайне важно, чтобы обработчик прерывания выполнялся очень быстро и возобновлял управление прерванного кода по возможности быстро. Поэтому, хотя для аппаратного обеспечения и важно, чтобы прерывание обслуживалось немедленно, для остальной системы важно, чтобы обработчик прерывания выполнялся в течение максимально короткого промежутка времени. Минимально возможная работа, которую должен сделать обработчик прерывания, — это отправить подтверждение устройству, что прерывание получено. Однако обычно обработчики прерываний должны выполнить большее количество работы. Например, рассмотрим обработчик прерывания сетевого устройства. Вместе с отправкой подтверждения аппаратному обеспечению, обработчик прерывания должен скопировать сетевые пакеты из аппаратного устройства в память системы, обработать их, отправить соответствующему стеку протоколов или соответствующей программе. Очевидно, что для этого требуется много работы.
Ясно, что два указанных требования о том, что обработчик прерывания должен выполняться быстро и, в дополнение к этому, выполнять много работы, являются противоречивыми. В связи с конфликтными требованиями, обработчик прерываний разбивается на две части, или половины. Обработчик прерывания является
Операционная система предоставляет различные механизмы для реализации обработки нижних половин, которые обсуждаются в главе 7, "Обработка нижних половин и отложенные действия".
Рассмотрим пример разделения обработчика прерывания на верхнюю и нижнюю половины на основе старой доброй сетевой платы. Когда сетевой интерфейсный адаптер получает входящие из сети пакеты, он должен уведомить ядро о том, что доступны новые данные. Это необходимо сделать немедленно, чтобы получить оптимальную пропускную способность и время задержки при передаче информации по сети. Поэтому немедленно генерируется прерывание:
Обработчик прерывания выполняется, аппаратному обеспечению направляется подтверждение, пакеты копируются в основную память, и после этого сетевой адаптер готов к получению новых пакетов. Эта задача является важной, критичной ко времени выполнения и специфической для каждого типа аппаратного обеспечения. Остальная часть обработки сетевых пакетов выполняется позже — нижней половиной обработчика прерывания. В этой главе мы рассмотрим обработку верхних половин, а в следующей — нижних.
Ответственность за обработчики прерываний лежит на драйверах устройств, которые управляют определенным типом аппаратного обеспечения. С каждым устройством связан драйвер, и если устройство использует прерывания (а большинство использует), то драйвер должен выполнить регистрацию обработчика прерывания.
Драйвер может зарегистрировать обработчик прерывания для обработки заданной линии с помощью следующей функции.
/* request_irq: выделить заданную линию прерывания */
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void*, struct pt_regs*),
unsigned long irqflags, const char* devname, void *dev_id);
Первый параметр, irq
, указывает назначаемый номер прерывания. Для некоторых устройств, таких как, например, обычные устройства персонального компьютера, таймер и клавиатура, это значение, как правило, жестко закреплено. Для большинства других устройств это значение определяется путем проверки (probing) или другим динамическим способом.
Второй параметр, handler
, — это указатель на функцию обработчика прерывания, которая обслуживает данное прерывание. Эта функция вызывается, когда в операционную систему приходит прерывание. Следует обратить внимание на специфический прототип функции-обработчика. Она принимает три параметра и возвращает значение типа irqreturn_t
. Ниже в этой главе мы более подробно обсудим эту функцию.
Третий параметр, irqflags
, может быть равным нулю или содержать битовую маску с одним или несколькими следующими флагами.