printk/index: Printk index feature documentation
Document the printk index feature. The primary motivation is to explain that it is not creating KABI from particular printk() calls. Acked-by: Sergey Senozhatsky <senozhatsky@chromium.org> Reviewed-by: Chris Down <chris@chrisdown.name> Signed-off-by: Petr Mladek <pmladek@suse.com>
This commit is contained in:
parent
e11da6799f
commit
a5c7a39f50
@ -20,6 +20,7 @@ it.
|
||||
workqueue
|
||||
printk-basics
|
||||
printk-formats
|
||||
printk-index
|
||||
symbol-namespaces
|
||||
|
||||
Data structures and low-level utilities
|
||||
|
137
Documentation/core-api/printk-index.rst
Normal file
137
Documentation/core-api/printk-index.rst
Normal file
@ -0,0 +1,137 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
============
|
||||
Printk Index
|
||||
============
|
||||
|
||||
There are many ways how to monitor the state of the system. One important
|
||||
source of information is the system log. It provides a lot of information,
|
||||
including more or less important warnings and error messages.
|
||||
|
||||
There are monitoring tools that filter and take action based on messages
|
||||
logged.
|
||||
|
||||
The kernel messages are evolving together with the code. As a result,
|
||||
particular kernel messages are not KABI and never will be!
|
||||
|
||||
It is a huge challenge for maintaining the system log monitors. It requires
|
||||
knowing what messages were updated in a particular kernel version and why.
|
||||
Finding these changes in the sources would require non-trivial parsers.
|
||||
Also it would require matching the sources with the binary kernel which
|
||||
is not always trivial. Various changes might be backported. Various kernel
|
||||
versions might be used on different monitored systems.
|
||||
|
||||
This is where the printk index feature might become useful. It provides
|
||||
a dump of printk formats used all over the source code used for the kernel
|
||||
and modules on the running system. It is accessible at runtime via debugfs.
|
||||
|
||||
The printk index helps to find changes in the message formats. Also it helps
|
||||
to track the strings back to the kernel sources and the related commit.
|
||||
|
||||
|
||||
User Interface
|
||||
==============
|
||||
|
||||
The index of printk formats are split in into separate files. The files are
|
||||
named according to the binaries where the printk formats are built-in. There
|
||||
is always "vmlinux" and optionally also modules, for example::
|
||||
|
||||
/sys/kernel/debug/printk/index/vmlinux
|
||||
/sys/kernel/debug/printk/index/ext4
|
||||
/sys/kernel/debug/printk/index/scsi_mod
|
||||
|
||||
Note that only loaded modules are shown. Also printk formats from a module
|
||||
might appear in "vmlinux" when the module is built-in.
|
||||
|
||||
The content is inspired by the dynamic debug interface and looks like::
|
||||
|
||||
$> head -1 /sys/kernel/debug/printk/index/vmlinux; shuf -n 5 vmlinux
|
||||
# <level[,flags]> filename:line function "format"
|
||||
<5> block/blk-settings.c:661 disk_stack_limits "%s: Warning: Device %s is misaligned\n"
|
||||
<4> kernel/trace/trace.c:8296 trace_create_file "Could not create tracefs '%s' entry\n"
|
||||
<6> arch/x86/kernel/hpet.c:144 _hpet_print_config "hpet: %s(%d):\n"
|
||||
<6> init/do_mounts.c:605 prepare_namespace "Waiting for root device %s...\n"
|
||||
<6> drivers/acpi/osl.c:1410 acpi_no_auto_serialize_setup "ACPI: auto-serialization disabled\n"
|
||||
|
||||
, where the meaning is:
|
||||
|
||||
- :level: log level value: 0-7 for particular severity, -1 as default,
|
||||
'c' as continuous line without an explicit log level
|
||||
- :flags: optional flags: currently only 'c' for KERN_CONT
|
||||
- :filename\:line: source filename and line number of the related
|
||||
printk() call. Note that there are many wrappers, for example,
|
||||
pr_warn(), pr_warn_once(), dev_warn().
|
||||
- :function: function name where the printk() call is used.
|
||||
- :format: format string
|
||||
|
||||
The extra information makes it a bit harder to find differences
|
||||
between various kernels. Especially the line number might change
|
||||
very often. On the other hand, it helps a lot to confirm that
|
||||
it is the same string or find the commit that is responsible
|
||||
for eventual changes.
|
||||
|
||||
|
||||
printk() Is Not a Stable KABI
|
||||
=============================
|
||||
|
||||
Several developers are afraid that exporting all these implementation
|
||||
details into the user space will transform particular printk() calls
|
||||
into KABI.
|
||||
|
||||
But it is exactly the opposite. printk() calls must _not_ be KABI.
|
||||
And the printk index helps user space tools to deal with this.
|
||||
|
||||
|
||||
Subsystem specific printk wrappers
|
||||
==================================
|
||||
|
||||
The printk index is generated using extra metadata that are stored in
|
||||
a dedicated .elf section ".printk_index". It is achieved using macro
|
||||
wrappers doing __printk_index_emit() together with the real printk()
|
||||
call. The same technique is used also for the metadata used by
|
||||
the dynamic debug feature.
|
||||
|
||||
The metadata are stored for a particular message only when it is printed
|
||||
using these special wrappers. It is implemented for the commonly
|
||||
used printk() calls, including, for example, pr_warn(), or pr_once().
|
||||
|
||||
Additional changes are necessary for various subsystem specific wrappers
|
||||
that call the original printk() via a common helper function. These needs
|
||||
their own wrappers adding __printk_index_emit().
|
||||
|
||||
Only few subsystem specific wrappers have been updated so far,
|
||||
for example, dev_printk(). As a result, the printk formats from
|
||||
some subsystes can be missing in the printk index.
|
||||
|
||||
|
||||
Subsystem specific prefix
|
||||
=========================
|
||||
|
||||
The macro pr_fmt() macro allows to define a prefix that is printed
|
||||
before the string generated by the related printk() calls.
|
||||
|
||||
Subsystem specific wrappers usually add even more complicated
|
||||
prefixes.
|
||||
|
||||
These prefixes can be stored into the printk index metadata
|
||||
by an optional parameter of __printk_index_emit(). The debugfs
|
||||
interface might then show the printk formats including these prefixes.
|
||||
For example, drivers/acpi/osl.c contains::
|
||||
|
||||
#define pr_fmt(fmt) "ACPI: OSL: " fmt
|
||||
|
||||
static int __init acpi_no_auto_serialize_setup(char *str)
|
||||
{
|
||||
acpi_gbl_auto_serialize_methods = FALSE;
|
||||
pr_info("Auto-serialization disabled\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
This results in the following printk index entry::
|
||||
|
||||
<6> drivers/acpi/osl.c:1410 acpi_no_auto_serialize_setup "ACPI: auto-serialization disabled\n"
|
||||
|
||||
It helps matching messages from the real log with printk index.
|
||||
Then the source file name, line number, and function name can
|
||||
be used to match the string with the source code.
|
@ -15585,6 +15585,7 @@ F: kernel/printk/
|
||||
PRINTK INDEXING
|
||||
R: Chris Down <chris@chrisdown.name>
|
||||
S: Maintained
|
||||
F: Documentation/core-api/printk-index.rst
|
||||
F: kernel/printk/index.c
|
||||
K: printk_index
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user