Printk внутри обработчика прерываний, действительно ли это так плохо?
все знают, что обработчик прерывания должен быть коротким, насколько это возможно. и добавление таких функций, как printk
для отладки внутри обработчика прерываний, - это то, чего не следует делать.
На самом деле, я пробовал это раньше, когда я отлаживал ядро linux для устройства с прерыванием, приводившего в действие устройство char, которое я написал, и это разрушило время работы драйвера.
У меня есть вопрос, почему это происходит?
Функция printk
буферизуется! это означает, насколько я понимаю, что данные вставляются в очередь и обрабатываются позже, скорее всего, после завершения обработчика прерываний.
Так почему же он не работает?
Ответы
Ответ 1
Функция printk
не просто вставляет в очередь/буфер - при условии, что уровень журнала достаточно высок, вывод из printk
будет немедленно отправлен на консоль, как часть вызова printk
, Это особенно медленно, если консоль, скажем, на последовательном порту. Но в любом случае printk
действительно создает довольно существенные издержки и может повлиять на время.
Если у вас есть временное критическое место, где вы хотите получить отладочный вывод, вы можете посмотреть на использование функции trace_printk
в современных ядрах. На самом деле это просто вводит ввод в буфер ringbuffer, и вы можете прочитать его позже. Взгляните на эту статью для получения полной информации.
Ответ 2
Да, это очень плохо, так как printf
скорее всего не реентерабелен. Что может случиться, так это то, что основная программа вызывает printf, прерывание приходит во время выполнения printf
, а затем обработчик IRQ вызывает printf
снова: могут произойти очень плохие вещи (например, тупик, поврежденные внутренние буферы и т.д.)