[PATCH v5 0/2] Add support to replay kernel log on console via sysrq

From: Sreenath Vijayan
Date: Thu Mar 07 2024 - 07:58:48 EST


Hi,

This patch series enables one to replay the kernel log messages
in printk ring buffer on consoles via sysrq. This is useful to
view the kernel messages when terminal is unresponsive to enter
commands like dmesg and syslog services are also disabled,
especially on embedded targets. Although debug features like
kdb/kgdb already allow this, these debug configs should be
enabled which is often not the case.

In the first commit, a generic function console_replay_all()
is added that replays the kernel log messages on consoles.
To do this, code under CONSOLE_REPLAY_ALL mode in
console_flush_on_panic() is taken out to a helper function
__console_rewind_all() to set the console sequence number to
oldest record in the printk buffer. This function can be called
safely under console_lock(). console_replay_all() tries to get
console subsystem lock using console_trylock() and if successful,
calls __console_rewind_all() to reset the sequence number.
Finally it calls console_unlock() which flushes out the contents
of printk buffer to consoles. The console loglevel will determine
which all kernel log messages are displayed.

In the second commit, code is added to call console_replay_all()
from the sysrq key handler when sysrq+R is pressed. Document is
also updated describing the use case and limitations.

Limitations:
- User may have to press the key combination multiple times if
console lock is not obtained at the time of key press.
- If console lock owner is stuck, console_trylock() will fail
continuously and messages won't be displayed.

These limitations can be overcome once atomic consoles are
available. Currently, it is best effort.

Links to previous discussion:
- https://lore.kernel.org/all/ZcyWU0V6Kmq0Txqr@xxxxxxxx/T/#t
- https://lore.kernel.org/all/cover.1705331453.git.sreenath.vijayan@xxxxxxxx/T/#t
- https://lore.kernel.org/linux-serial/20231221133953.1507021-1-sreenath.vijayan@xxxxxxxx/

Changelog:
V4 -> V5:
- renamed console_rewind_all() to __console_rewind_all()
- modified comments for __console_rewind_all()
- renamed dump_printk_buffer() to console_replay_all()
- used sysrq+R instead of sysrq+D
- removed workqueue based implementation and used console_trylock()

V3 -> V4:
- refactor code in console_flush_on_panic() under CONSOLE_REPLAY_ALL mode
- add new function console_rewind_all()
- use console_rewind_all() instead of ksmg_dump*() in dump_printk_buffer()

V2 -> V3:
- split the implementation into two commits
- added function in printk.c to dump printk buffer to consoles
- added Suggested-by tag
- removed code to dump printk buffer from sysrq.c and called
new function

V1 -> V2:
- modified kernel ring buffer to printk ring buffer
- allocated buf dynamically to prevent stack frame size warnings
- used buf of size 2048 to match PRINTK_MESSAGE_MAX and added comment

-- Sreenath

Sreenath Vijayan (2):
printk: Add function to replay kernel log on consoles
tty/sysrq: Replay kernel log messages on consoles via sysrq

Documentation/admin-guide/sysrq.rst | 8 +++
drivers/tty/sysrq.c | 13 ++++-
include/linux/printk.h | 4 ++
kernel/printk/printk.c | 77 ++++++++++++++++++++---------
4 files changed, 77 insertions(+), 25 deletions(-)

--
2.25.1