Printk внутри обработчика прерываний, действительно ли это так плохо?

все знают, что обработчик прерывания должен быть коротким, насколько это возможно. и добавление таких функций, как printk для отладки внутри обработчика прерываний, - это то, чего не следует делать. На самом деле, я пробовал это раньше, когда я отлаживал ядро ​​linux для устройства с прерыванием, приводившего в действие устройство char, которое я написал, и это разрушило время работы драйвера.

У меня есть вопрос, почему это происходит? Функция printk буферизуется! это означает, насколько я понимаю, что данные вставляются в очередь и обрабатываются позже, скорее всего, после завершения обработчика прерываний.

Так почему же он не работает?

Ответ 1

Функция printk не просто вставляет в очередь/буфер - при условии, что уровень журнала достаточно высок, вывод из printk будет немедленно отправлен на консоль, как часть вызова printk, Это особенно медленно, если консоль, скажем, на последовательном порту. Но в любом случае printk действительно создает довольно существенные издержки и может повлиять на время.

Если у вас есть временное критическое место, где вы хотите получить отладочный вывод, вы можете посмотреть на использование функции trace_printk в современных ядрах. На самом деле это просто вводит ввод в буфер ringbuffer, и вы можете прочитать его позже. Взгляните на эту статью для получения полной информации.

Ответ 2

Да, это очень плохо, так как printf скорее всего не реентерабелен. Что может случиться, так это то, что основная программа вызывает printf, прерывание приходит во время выполнения printf, а затем обработчик IRQ вызывает printf снова: могут произойти очень плохие вещи (например, тупик, поврежденные внутренние буферы и т.д.)