162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci============
462306a36Sopenharmony_ciPrintk Index
562306a36Sopenharmony_ci============
662306a36Sopenharmony_ci
762306a36Sopenharmony_ciThere are many ways how to monitor the state of the system. One important
862306a36Sopenharmony_cisource of information is the system log. It provides a lot of information,
962306a36Sopenharmony_ciincluding more or less important warnings and error messages.
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciThere are monitoring tools that filter and take action based on messages
1262306a36Sopenharmony_cilogged.
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ciThe kernel messages are evolving together with the code. As a result,
1562306a36Sopenharmony_ciparticular kernel messages are not KABI and never will be!
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ciIt is a huge challenge for maintaining the system log monitors. It requires
1862306a36Sopenharmony_ciknowing what messages were updated in a particular kernel version and why.
1962306a36Sopenharmony_ciFinding these changes in the sources would require non-trivial parsers.
2062306a36Sopenharmony_ciAlso it would require matching the sources with the binary kernel which
2162306a36Sopenharmony_ciis not always trivial. Various changes might be backported. Various kernel
2262306a36Sopenharmony_civersions might be used on different monitored systems.
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciThis is where the printk index feature might become useful. It provides
2562306a36Sopenharmony_cia dump of printk formats used all over the source code used for the kernel
2662306a36Sopenharmony_ciand modules on the running system. It is accessible at runtime via debugfs.
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ciThe printk index helps to find changes in the message formats. Also it helps
2962306a36Sopenharmony_cito track the strings back to the kernel sources and the related commit.
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ciUser Interface
3362306a36Sopenharmony_ci==============
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ciThe index of printk formats are split in into separate files. The files are
3662306a36Sopenharmony_cinamed according to the binaries where the printk formats are built-in. There
3762306a36Sopenharmony_ciis always "vmlinux" and optionally also modules, for example::
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci   /sys/kernel/debug/printk/index/vmlinux
4062306a36Sopenharmony_ci   /sys/kernel/debug/printk/index/ext4
4162306a36Sopenharmony_ci   /sys/kernel/debug/printk/index/scsi_mod
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ciNote that only loaded modules are shown. Also printk formats from a module
4462306a36Sopenharmony_cimight appear in "vmlinux" when the module is built-in.
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ciThe content is inspired by the dynamic debug interface and looks like::
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci   $> head -1 /sys/kernel/debug/printk/index/vmlinux; shuf -n 5 vmlinux
4962306a36Sopenharmony_ci   # <level[,flags]> filename:line function "format"
5062306a36Sopenharmony_ci   <5> block/blk-settings.c:661 disk_stack_limits "%s: Warning: Device %s is misaligned\n"
5162306a36Sopenharmony_ci   <4> kernel/trace/trace.c:8296 trace_create_file "Could not create tracefs '%s' entry\n"
5262306a36Sopenharmony_ci   <6> arch/x86/kernel/hpet.c:144 _hpet_print_config "hpet: %s(%d):\n"
5362306a36Sopenharmony_ci   <6> init/do_mounts.c:605 prepare_namespace "Waiting for root device %s...\n"
5462306a36Sopenharmony_ci   <6> drivers/acpi/osl.c:1410 acpi_no_auto_serialize_setup "ACPI: auto-serialization disabled\n"
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci, where the meaning is:
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci   - :level: log level value: 0-7 for particular severity, -1 as default,
5962306a36Sopenharmony_ci	'c' as continuous line without an explicit log level
6062306a36Sopenharmony_ci   - :flags: optional flags: currently only 'c' for KERN_CONT
6162306a36Sopenharmony_ci   - :filename\:line: source filename and line number of the related
6262306a36Sopenharmony_ci	printk() call. Note that there are many wrappers, for example,
6362306a36Sopenharmony_ci	pr_warn(), pr_warn_once(), dev_warn().
6462306a36Sopenharmony_ci   - :function: function name where the printk() call is used.
6562306a36Sopenharmony_ci   - :format: format string
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ciThe extra information makes it a bit harder to find differences
6862306a36Sopenharmony_cibetween various kernels. Especially the line number might change
6962306a36Sopenharmony_civery often. On the other hand, it helps a lot to confirm that
7062306a36Sopenharmony_ciit is the same string or find the commit that is responsible
7162306a36Sopenharmony_cifor eventual changes.
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ciprintk() Is Not a Stable KABI
7562306a36Sopenharmony_ci=============================
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ciSeveral developers are afraid that exporting all these implementation
7862306a36Sopenharmony_cidetails into the user space will transform particular printk() calls
7962306a36Sopenharmony_ciinto KABI.
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ciBut it is exactly the opposite. printk() calls must _not_ be KABI.
8262306a36Sopenharmony_ciAnd the printk index helps user space tools to deal with this.
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ciSubsystem specific printk wrappers
8662306a36Sopenharmony_ci==================================
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ciThe printk index is generated using extra metadata that are stored in
8962306a36Sopenharmony_cia dedicated .elf section ".printk_index". It is achieved using macro
9062306a36Sopenharmony_ciwrappers doing __printk_index_emit() together with the real printk()
9162306a36Sopenharmony_cicall. The same technique is used also for the metadata used by
9262306a36Sopenharmony_cithe dynamic debug feature.
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ciThe metadata are stored for a particular message only when it is printed
9562306a36Sopenharmony_ciusing these special wrappers. It is implemented for the commonly
9662306a36Sopenharmony_ciused printk() calls, including, for example, pr_warn(), or pr_once().
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ciAdditional changes are necessary for various subsystem specific wrappers
9962306a36Sopenharmony_cithat call the original printk() via a common helper function. These needs
10062306a36Sopenharmony_citheir own wrappers adding __printk_index_emit().
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ciOnly few subsystem specific wrappers have been updated so far,
10362306a36Sopenharmony_cifor example, dev_printk(). As a result, the printk formats from
10462306a36Sopenharmony_cisome subsystes can be missing in the printk index.
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ciSubsystem specific prefix
10862306a36Sopenharmony_ci=========================
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ciThe macro pr_fmt() macro allows to define a prefix that is printed
11162306a36Sopenharmony_cibefore the string generated by the related printk() calls.
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ciSubsystem specific wrappers usually add even more complicated
11462306a36Sopenharmony_ciprefixes.
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ciThese prefixes can be stored into the printk index metadata
11762306a36Sopenharmony_ciby an optional parameter of __printk_index_emit(). The debugfs
11862306a36Sopenharmony_ciinterface might then show the printk formats including these prefixes.
11962306a36Sopenharmony_ciFor example, drivers/acpi/osl.c contains::
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci  #define pr_fmt(fmt) "ACPI: OSL: " fmt
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci  static int __init acpi_no_auto_serialize_setup(char *str)
12462306a36Sopenharmony_ci  {
12562306a36Sopenharmony_ci	acpi_gbl_auto_serialize_methods = FALSE;
12662306a36Sopenharmony_ci	pr_info("Auto-serialization disabled\n");
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	return 1;
12962306a36Sopenharmony_ci  }
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ciThis results in the following printk index entry::
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci  <6> drivers/acpi/osl.c:1410 acpi_no_auto_serialize_setup "ACPI: auto-serialization disabled\n"
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ciIt helps matching messages from the real log with printk index.
13662306a36Sopenharmony_ciThen the source file name, line number, and function name can
13762306a36Sopenharmony_cibe used to match the string with the source code.
138