Вопрос по linux-device-driver, linux-kernel – Может ли обработчик прерываний быть прерван тем же обработчиком прерываний?

6

Отключает ли процессор все прерывания на локальном процессоре перед вызовом обработчика прерываний? Или он отключает только ту конкретную линию прерывания, которая обслуживается?

Какой процессор? Какая архитектура? eepp
архитектура x86. Harman

Ваш Ответ

5   ответов
0

на удивление хорошо написанную «Intel» Intel & # xAE; Руководство по разработке программного обеспечения для архитектуры 64 и IA-32, том 1, страницы 6-10:

If an interrupt or exception handler is called through an interrupt gate, the processor clears the interrupt enable (IF) flag in the EFLAGS register to prevent subsequent interrupts from interfering with the execution of the handler. When a handler is called through a trap gate, the state of the IF flag is not changed.

Так что просто для ясности - да, фактически процессор "отключает" все прерывания перед вызовом обработчика прерываний. При правильном описании процессор просто запускает флаг, который заставляет его игнорировать все запросы прерывания. За исключением, вероятно, немаскируемых прерываний и / или собственных программных исключений (пожалуйста, кто-то исправит меня в этом,not verified).

3

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

Обратите внимание, что, хотя это означает, что ваш обработчик прерываний не будет состязаться с самим собой на одном и том же процессоре, он может и будет состязаться с тем, что он работает на других процессорах в системе SMP / SMT.

Не строгое поведение HW - вопрос был задан в контексте ядра Linux. Поведение LAPIC программируемо, но именно так его программирует Linux - все прерывания имеют одинаковый приоритет, поэтому одно блокирует другое, но Linux в программном обеспечении повторно разрешает прерывания очень быстро даже до запуска обработчика прерываний.
Не могли бы вы предоставить источник заявления "x86 отключает все локальные прерывания ... перед переходом к вектору прерываний"? В моем распоряжении документация по 3-томной архитектуре Intel и документация 8259A, также от Intel. Я не могу найти ничего, что подсказывало бы мне, что прерывания автоматически отключаются перед переходом к вектору прерываний, то есть в точке входа в ISR (процедура обработки прерывания / процедура обработки прерывания)
Впоследствии я обнаружил ссылку на «default» Поведение x86 HW, о котором идет речь, в Intel 64 и IA-32 Arch. Руководство разработчика программного обеспечения, стр. 6-10 Том 1: «Если обработчик прерываний или исключений вызывается через шлюз прерываний, процессор очищает флаг разрешения прерываний (IF) в регистре EFLAGS, чтобы предотвратить прерывание последующих прерываний при выполнении обработчика.» Спасибо за разъяснения по поводу Linux.
0

чтобы ISR был атомарным, и никто не должен быть в состоянии превзойти ISR.

Поэтому ISR отключает локальные прерывания (то есть прерывание на текущем процессоре), и как только ISR вызывает функцию ret_from_intr () (т.е. мы завершили ISR), прерывания снова включаются на текущем процессоре.

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

В системе SMP нам также необходимо включить надлежащий механизм синхронизации (спин-блокировка) в ISR.

Не могли бы вы более подробно изложить свой ответ, добавив немного больше описания предлагаемого вами решения?
2

При получении прерывания аппаратное обеспечение выполняет следующие действия:
 1. Сохраните все регистры в заранее определенном месте.
 2. Установите указатель команд (программный счетчик АКА) на адрес обработчика прерываний.
 3. Установите для регистра, управляющего прерываниями, значение, которое отключает все (или большинство) прерываний. Это предотвращает прерывание другого прерывания.

Исключением является NMI (немаскируемое прерывание), которое нельзя отключить.

Из Linux Kernel DevelopmentInterrupt handlers in Linux need not be reentrant. When a given interrupt handler is executing, the corresponding interrupt line is masked out on all processors, preventing another interrupt on the same line from being received. Normally all other interrupts are enabled, so other interrupts are serviced, but the current line is always disabled. Consequently, the same interrupt handler is never invoked concurrently to service a nested interrupt. This greatly simplifies writing your interrupt handler.  Таким образом, маскируется только текущая строка прерывания. Harman
@ Harman, это означает, что только текущая линия прерывания гарантированно будет маскироваться. Я почти уверен, что реальная реализация на x86 - замаскировать их всех.
1

Я также хотел бы добавить то, что, по моему мнению, может иметь отношение к делу.

Во многих реальных драйверах / коде ядра «нижняя половина» (bh) довольно часто используются обработчики - тасклеты, softirqs. Они выполняются в контексте прерывания иcan работать параллельно со своими обработчиками верхней половины (th) на SMP (esp softirq).

Конечно, недавно произошел переход (в основном код, перенесенный из проекта PREEMPT_RT) в направлении основной линии, что по существу избавляет от «bh». механизм - все обработчики прерываний будут работать с отключенными всеми прерываниями. Мало того, что обработчики (могут быть) преобразованы в потоки ядра - это так называемые «потоки» обработчики прерываний.

На сегодняшний день выбор остается за разработчиком - вы можете использовать «традиционный». стиль th / bh или стиль с резьбой.

Ссылка и детали:

http://lwn.net/Articles/380931/

http://lwn.net/Articles/302043/

Похожие вопросы