Является ли in_irq() надежным?
Ненадежное руководство по взлому ядра Linux утверждает, что
Вы можете сказать, что находитесь в состоянии аппаратного прерывания, потому что in_irq() возвращает true.
Осторожно Помните, что это вернет ложное срабатывание, если прерывания отключены (см. Ниже).
Это действительно тот случай, когда in_irq()
может вернуть ненулевое значение не в контексте hardirq в ядрах Linux 2.6.32 или новее на x86?
В моих экспериментах с ядром 2.6.32 (Debian 6) и 3.4 (OpenSUSE 12.1), in_irq()
всегда возвращает 0 при вызове из контекста процесса, даже если он вызывался между local_irq_disable()
а также local_irq_enable()
, Результаты были такими же, когда я использовал функции спин-блокировки, которые отключают прерывания вместо local_irq*
,
Из исходного кода ядра в настоящее время я не вижу, как in_irq()
может вернуть ложный положительный результат. Может ли кто-нибудь уточнить это?
РЕДАКТИРОВАТЬ: я также попробовал оба *_irqsave()
а также *_irq()
Spinlock API, а также local_irq_save()
/ local_irq_restore()
результаты были одинаковыми, то есть in_irq()
вернул 0, когда прерывания были отключены. Отключение прерываний явно через cli
машинная инструкция на x86 также не заставляла in_irq() возвращать ненулевое значение.
1 ответ
in_irq()
это обертка, которая смотрит на некоторые биты в preempt_count
, который является int в thread_info
struct и значение 0 означает, что это не прервано, поэтому оно не находится в irq.
local_irq_disable()
само по себе не влияет на этот счет, но spin_lock_irqsave()
делает, чтобы это могло привести к ложному положительному результату. Вы говорите, что использовали функции спин-блокировки, вы использовали эту? Если это так, посмотрите, изменяется ли значение preempt_count.
РЕДАКТИРОВАТЬ: просто, чтобы охватить все базы, убедитесь, что включена функция pre-emption ядра.