Является ли 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 ядра.

Другие вопросы по тегам