docs: pr_*() kerneldocs and basic printk docs
Add kerneldocs comments to the pr_*() macros in printk.h. Add a new rst node in the core-api manual describing the basic usage of printk and the related macro aliases. Signed-off-by: Ricardo Cañuelo <ricardo.canuelo@collabora.com> Link: https://lore.kernel.org/r/20200403093617.18003-1-ricardo.canuelo@collabora.com Signed-off-by: Jonathan Corbet <corbet@lwn.net>
This commit is contained in:
parent
4951d27b09
commit
90c165f0de
|
@ -18,6 +18,7 @@ it.
|
||||||
|
|
||||||
kernel-api
|
kernel-api
|
||||||
workqueue
|
workqueue
|
||||||
|
printk-basics
|
||||||
printk-formats
|
printk-formats
|
||||||
symbol-namespaces
|
symbol-namespaces
|
||||||
|
|
||||||
|
|
115
Documentation/core-api/printk-basics.rst
Normal file
115
Documentation/core-api/printk-basics.rst
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
===========================
|
||||||
|
Message logging with printk
|
||||||
|
===========================
|
||||||
|
|
||||||
|
printk() is one of the most widely known functions in the Linux kernel. It's the
|
||||||
|
standard tool we have for printing messages and usually the most basic way of
|
||||||
|
tracing and debugging. If you're familiar with printf(3) you can tell printk()
|
||||||
|
is based on it, although it has some functional differences:
|
||||||
|
|
||||||
|
- printk() messages can specify a log level.
|
||||||
|
|
||||||
|
- the format string, while largely compatible with C99, doesn't follow the
|
||||||
|
exact same specification. It has some extensions and a few limitations
|
||||||
|
(no ``%n`` or floating point conversion specifiers). See :ref:`How to get
|
||||||
|
printk format specifiers right <printk-specifiers>`.
|
||||||
|
|
||||||
|
All printk() messages are printed to the kernel log buffer, which is a ring
|
||||||
|
buffer exported to userspace through /dev/kmsg. The usual way to read it is
|
||||||
|
using ``dmesg``.
|
||||||
|
|
||||||
|
printk() is typically used like this::
|
||||||
|
|
||||||
|
printk(KERN_INFO "Message: %s\n", arg);
|
||||||
|
|
||||||
|
where ``KERN_INFO`` is the log level (note that it's concatenated to the format
|
||||||
|
string, the log level is not a separate argument). The available log levels are:
|
||||||
|
|
||||||
|
+----------------+--------+-----------------------------------------------+
|
||||||
|
| Name | String | Alias function |
|
||||||
|
+================+========+===============================================+
|
||||||
|
| KERN_EMERG | "0" | pr_emerg() |
|
||||||
|
+----------------+--------+-----------------------------------------------+
|
||||||
|
| KERN_ALERT | "1" | pr_alert() |
|
||||||
|
+----------------+--------+-----------------------------------------------+
|
||||||
|
| KERN_CRIT | "2" | pr_crit() |
|
||||||
|
+----------------+--------+-----------------------------------------------+
|
||||||
|
| KERN_ERR | "3" | pr_err() |
|
||||||
|
+----------------+--------+-----------------------------------------------+
|
||||||
|
| KERN_WARNING | "4" | pr_warn() |
|
||||||
|
+----------------+--------+-----------------------------------------------+
|
||||||
|
| KERN_NOTICE | "5" | pr_notice() |
|
||||||
|
+----------------+--------+-----------------------------------------------+
|
||||||
|
| KERN_INFO | "6" | pr_info() |
|
||||||
|
+----------------+--------+-----------------------------------------------+
|
||||||
|
| KERN_DEBUG | "7" | pr_debug() and pr_devel() if DEBUG is defined |
|
||||||
|
+----------------+--------+-----------------------------------------------+
|
||||||
|
| KERN_DEFAULT | "" | |
|
||||||
|
+----------------+--------+-----------------------------------------------+
|
||||||
|
| KERN_CONT | "c" | pr_cont() |
|
||||||
|
+----------------+--------+-----------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
The log level specifies the importance of a message. The kernel decides whether
|
||||||
|
to show the message immediately (printing it to the current console) depending
|
||||||
|
on its log level and the current *console_loglevel* (a kernel variable). If the
|
||||||
|
message priority is higher (lower log level value) than the *console_loglevel*
|
||||||
|
the message will be printed to the console.
|
||||||
|
|
||||||
|
If the log level is omitted, the message is printed with ``KERN_DEFAULT``
|
||||||
|
level.
|
||||||
|
|
||||||
|
You can check the current *console_loglevel* with::
|
||||||
|
|
||||||
|
$ cat /proc/sys/kernel/printk
|
||||||
|
4 4 1 7
|
||||||
|
|
||||||
|
The result shows the *current*, *default*, *minimum* and *boot-time-default* log
|
||||||
|
levels.
|
||||||
|
|
||||||
|
To change the current console_loglevel simply write the the desired level to
|
||||||
|
``/proc/sys/kernel/printk``. For example, to print all messages to the console::
|
||||||
|
|
||||||
|
# echo 8 > /proc/sys/kernel/printk
|
||||||
|
|
||||||
|
Another way, using ``dmesg``::
|
||||||
|
|
||||||
|
# dmesg -n 5
|
||||||
|
|
||||||
|
sets the console_loglevel to print KERN_WARNING (4) or more severe messages to
|
||||||
|
console. See ``dmesg(1)`` for more information.
|
||||||
|
|
||||||
|
As an alternative to printk() you can use the ``pr_*()`` aliases for
|
||||||
|
logging. This family of macros embed the log level in the macro names. For
|
||||||
|
example::
|
||||||
|
|
||||||
|
pr_info("Info message no. %d\n", msg_num);
|
||||||
|
|
||||||
|
prints a ``KERN_INFO`` message.
|
||||||
|
|
||||||
|
Besides being more concise than the equivalent printk() calls, they can use a
|
||||||
|
common definition for the format string through the pr_fmt() macro. For
|
||||||
|
instance, defining this at the top of a source file (before any ``#include``
|
||||||
|
directive)::
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__
|
||||||
|
|
||||||
|
would prefix every pr_*() message in that file with the module and function name
|
||||||
|
that originated the message.
|
||||||
|
|
||||||
|
For debugging purposes there are also two conditionally-compiled macros:
|
||||||
|
pr_debug() and pr_devel(), which are compiled-out unless ``DEBUG`` (or
|
||||||
|
also ``CONFIG_DYNAMIC_DEBUG`` in the case of pr_debug()) is defined.
|
||||||
|
|
||||||
|
|
||||||
|
Function reference
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. kernel-doc:: kernel/printk/printk.c
|
||||||
|
:functions: printk
|
||||||
|
|
||||||
|
.. kernel-doc:: include/linux/printk.h
|
||||||
|
:functions: pr_emerg pr_alert pr_crit pr_err pr_warn pr_notice pr_info
|
||||||
|
pr_fmt pr_debug pr_devel pr_cont
|
|
@ -2,6 +2,8 @@
|
||||||
How to get printk format specifiers right
|
How to get printk format specifiers right
|
||||||
=========================================
|
=========================================
|
||||||
|
|
||||||
|
.. _printk-specifiers:
|
||||||
|
|
||||||
:Author: Randy Dunlap <rdunlap@infradead.org>
|
:Author: Randy Dunlap <rdunlap@infradead.org>
|
||||||
:Author: Andrew Murray <amurray@mpc-data.co.uk>
|
:Author: Andrew Murray <amurray@mpc-data.co.uk>
|
||||||
|
|
||||||
|
|
|
@ -279,39 +279,116 @@ static inline void printk_safe_flush_on_panic(void)
|
||||||
|
|
||||||
extern int kptr_restrict;
|
extern int kptr_restrict;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pr_fmt - used by the pr_*() macros to generate the printk format string
|
||||||
|
* @fmt: format string passed from a pr_*() macro
|
||||||
|
*
|
||||||
|
* This macro can be used to generate a unified format string for pr_*()
|
||||||
|
* macros. A common use is to prefix all pr_*() messages in a file with a common
|
||||||
|
* string. For example, defining this at the top of a source file:
|
||||||
|
*
|
||||||
|
* #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
*
|
||||||
|
* would prefix all pr_info, pr_emerg... messages in the file with the module
|
||||||
|
* name.
|
||||||
|
*/
|
||||||
#ifndef pr_fmt
|
#ifndef pr_fmt
|
||||||
#define pr_fmt(fmt) fmt
|
#define pr_fmt(fmt) fmt
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* These can be used to print at the various log levels.
|
* pr_emerg - Print an emergency-level message
|
||||||
* All of these will print unconditionally, although note that pr_debug()
|
* @fmt: format string
|
||||||
* and other debug macros are compiled out unless either DEBUG is defined
|
* @...: arguments for the format string
|
||||||
* or CONFIG_DYNAMIC_DEBUG is set.
|
*
|
||||||
|
* This macro expands to a printk with KERN_EMERG loglevel. It uses pr_fmt() to
|
||||||
|
* generate the format string.
|
||||||
*/
|
*/
|
||||||
#define pr_emerg(fmt, ...) \
|
#define pr_emerg(fmt, ...) \
|
||||||
printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
|
printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
/**
|
||||||
|
* pr_alert - Print an alert-level message
|
||||||
|
* @fmt: format string
|
||||||
|
* @...: arguments for the format string
|
||||||
|
*
|
||||||
|
* This macro expands to a printk with KERN_ALERT loglevel. It uses pr_fmt() to
|
||||||
|
* generate the format string.
|
||||||
|
*/
|
||||||
#define pr_alert(fmt, ...) \
|
#define pr_alert(fmt, ...) \
|
||||||
printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
|
printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
/**
|
||||||
|
* pr_crit - Print a critical-level message
|
||||||
|
* @fmt: format string
|
||||||
|
* @...: arguments for the format string
|
||||||
|
*
|
||||||
|
* This macro expands to a printk with KERN_CRIT loglevel. It uses pr_fmt() to
|
||||||
|
* generate the format string.
|
||||||
|
*/
|
||||||
#define pr_crit(fmt, ...) \
|
#define pr_crit(fmt, ...) \
|
||||||
printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
|
printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
/**
|
||||||
|
* pr_err - Print an error-level message
|
||||||
|
* @fmt: format string
|
||||||
|
* @...: arguments for the format string
|
||||||
|
*
|
||||||
|
* This macro expands to a printk with KERN_ERR loglevel. It uses pr_fmt() to
|
||||||
|
* generate the format string.
|
||||||
|
*/
|
||||||
#define pr_err(fmt, ...) \
|
#define pr_err(fmt, ...) \
|
||||||
printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
|
printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
/**
|
||||||
|
* pr_warn - Print a warning-level message
|
||||||
|
* @fmt: format string
|
||||||
|
* @...: arguments for the format string
|
||||||
|
*
|
||||||
|
* This macro expands to a printk with KERN_WARNING loglevel. It uses pr_fmt()
|
||||||
|
* to generate the format string.
|
||||||
|
*/
|
||||||
#define pr_warn(fmt, ...) \
|
#define pr_warn(fmt, ...) \
|
||||||
printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
|
printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
/**
|
||||||
|
* pr_notice - Print a notice-level message
|
||||||
|
* @fmt: format string
|
||||||
|
* @...: arguments for the format string
|
||||||
|
*
|
||||||
|
* This macro expands to a printk with KERN_NOTICE loglevel. It uses pr_fmt() to
|
||||||
|
* generate the format string.
|
||||||
|
*/
|
||||||
#define pr_notice(fmt, ...) \
|
#define pr_notice(fmt, ...) \
|
||||||
printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
|
printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
/**
|
||||||
|
* pr_info - Print an info-level message
|
||||||
|
* @fmt: format string
|
||||||
|
* @...: arguments for the format string
|
||||||
|
*
|
||||||
|
* This macro expands to a printk with KERN_INFO loglevel. It uses pr_fmt() to
|
||||||
|
* generate the format string.
|
||||||
|
*/
|
||||||
#define pr_info(fmt, ...) \
|
#define pr_info(fmt, ...) \
|
||||||
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
|
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
|
||||||
/*
|
|
||||||
* Like KERN_CONT, pr_cont() should only be used when continuing
|
/**
|
||||||
* a line with no newline ('\n') enclosed. Otherwise it defaults
|
* pr_cont - Continues a previous log message in the same line.
|
||||||
* back to KERN_DEFAULT.
|
* @fmt: format string
|
||||||
|
* @...: arguments for the format string
|
||||||
|
*
|
||||||
|
* This macro expands to a printk with KERN_CONT loglevel. It should only be
|
||||||
|
* used when continuing a log message with no newline ('\n') enclosed. Otherwise
|
||||||
|
* it defaults back to KERN_DEFAULT loglevel.
|
||||||
*/
|
*/
|
||||||
#define pr_cont(fmt, ...) \
|
#define pr_cont(fmt, ...) \
|
||||||
printk(KERN_CONT fmt, ##__VA_ARGS__)
|
printk(KERN_CONT fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
/* pr_devel() should produce zero code unless DEBUG is defined */
|
/**
|
||||||
|
* pr_devel - Print a debug-level message conditionally
|
||||||
|
* @fmt: format string
|
||||||
|
* @...: arguments for the format string
|
||||||
|
*
|
||||||
|
* This macro expands to a printk with KERN_DEBUG loglevel if DEBUG is
|
||||||
|
* defined. Otherwise it does nothing.
|
||||||
|
*
|
||||||
|
* It uses pr_fmt() to generate the format string.
|
||||||
|
*/
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define pr_devel(fmt, ...) \
|
#define pr_devel(fmt, ...) \
|
||||||
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
|
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
@ -325,7 +402,18 @@ extern int kptr_restrict;
|
||||||
#if defined(CONFIG_DYNAMIC_DEBUG)
|
#if defined(CONFIG_DYNAMIC_DEBUG)
|
||||||
#include <linux/dynamic_debug.h>
|
#include <linux/dynamic_debug.h>
|
||||||
|
|
||||||
/* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */
|
/**
|
||||||
|
* pr_debug - Print a debug-level message conditionally
|
||||||
|
* @fmt: format string
|
||||||
|
* @...: arguments for the format string
|
||||||
|
*
|
||||||
|
* This macro expands to dynamic_pr_debug() if CONFIG_DYNAMIC_DEBUG is
|
||||||
|
* set. Otherwise, if DEBUG is defined, it's equivalent to a printk with
|
||||||
|
* KERN_DEBUG loglevel. If DEBUG is not defined it does nothing.
|
||||||
|
*
|
||||||
|
* It uses pr_fmt() to generate the format string (dynamic_pr_debug() uses
|
||||||
|
* pr_fmt() internally).
|
||||||
|
*/
|
||||||
#define pr_debug(fmt, ...) \
|
#define pr_debug(fmt, ...) \
|
||||||
dynamic_pr_debug(fmt, ##__VA_ARGS__)
|
dynamic_pr_debug(fmt, ##__VA_ARGS__)
|
||||||
#elif defined(DEBUG)
|
#elif defined(DEBUG)
|
||||||
|
|
Loading…
Reference in a new issue