Между вызовами вашего модуля printk(...)
и выводом, отображаемым на консоли, есть много слоев.
Насколько я понимаю, printk () гарантированно выводит на консоль непосредственно передследующая строка кода выполняется, вместо того, чтобы выводить ее в буфер, который в конечном итоге сбрасывается в какой-то момент.Это правильно?
Нет, это не правильно.В реализации printk()
нет «консоли», и ее не должно быть.Всегда есть буфер, много слоев буферов.Строка 1705 в printk.c отвечает на ваш вопрос.Функция printk_emit()
использует статически распределенный буфер static char textbuf[LOG_LINE_MAX];
и вызывает для него vscnprintf(textbuf, sizeof(textbuf), ...)
для анализа аргументов.Так что он использует буфер.Я не думаю, что можно написать функцию printf
без использования внутреннего буфера, по крайней мере, это сложнее.А переменная __log_buf
представляет собой статически распределенный буфер, массив символов, и он является буфером журнала ядра.
Существует ли задержка между временем отправки printkв консоль, и она отображается в dmesg, что позволит моей системе зависнуть до того, как я увижу вывод?
Да?Там всегда лаг.Я не знаю, как определить «лаг» (одну миллисекунду? Секунду? Одну наносекунду?), Но должны выполняться инструкции по сборке за printk
функцией, затем все слои, пока они не будут помещены в __ log_buf статическая переменная.Затем dmesg
, который ожидает read()
, вызывает системный вызов, я думаю, где-то внутри console_unlock .После пробуждения dmesg
наконец вызовет функцию devkmsg_read () , которая вернет буфер.Затем dmesg()
вызовет системный вызов write()
на стандартный вывод после получения данных.Затем системный вызов ядра write()
попытается что-то записать на ваш экран - поэтому данные должны проходить через драйверы консоли, драйверы дисплея и драйверы графики.Там всегда лаг.Но он должен быть минимальным.
dmesg показывает рассматриваемые отпечатки после исправления проблемной строки кода
, которая просто говорит, что dmesg
не получил выводиз журнала ядра.Вероятно, происходит что-то еще.Самое простое - dmesg
процесс не получает процессорное время, блокируется при чтении системного журнала, ваш модуль выполняется внутри с отключенным irq и т. Д.