Commit d8763154 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'printk-for-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux

Pull printk updates from Petr Mladek:

 - Refactor printk code for formatting messages that are shown on
   consoles. This is a preparatory step for introducing atomic consoles
   which could not share the global buffers

 - Prevent memory leak when removing printk index in debugfs

 - Dump also the newest printk message by the sample gdbmacro

 - Fix a compiler warning

* tag 'printk-for-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux:
  printf: fix errname.c list
  kernel/printk/index.c: fix memory leak with using debugfs_lookup()
  printk: Use scnprintf() to print the message about the dropped messages on a console
  printk: adjust string limit macros
  printk: use printk_buffers for devkmsg
  printk: introduce console_prepend_dropped() for dropped messages
  printk: introduce printk_get_next_message() and printk_message
  printk: introduce struct printk_buffers
  console: Document struct console
  console: Use BIT() macros for @flags values
  printk: move size limit macros into internal.h
  docs: gdbmacros: print newest record
parents cd43b506 392143c9
...@@ -312,10 +312,10 @@ define dmesg ...@@ -312,10 +312,10 @@ define dmesg
set var $prev_flags = $info->flags set var $prev_flags = $info->flags
end end
set var $id = ($id + 1) & $id_mask
if ($id == $end_id) if ($id == $end_id)
loop_break loop_break
end end
set var $id = ($id + 1) & $id_mask
end end
end end
document dmesg document dmesg
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#define _LINUX_CONSOLE_H_ 1 #define _LINUX_CONSOLE_H_ 1
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/bits.h>
#include <linux/rculist.h> #include <linux/rculist.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -125,37 +126,82 @@ static inline int con_debug_leave(void) ...@@ -125,37 +126,82 @@ static inline int con_debug_leave(void)
/* /*
* The interface for a console, or any other device that wants to capture * The interface for a console, or any other device that wants to capture
* console messages (printer driver?) * console messages (printer driver?)
*
* If a console driver is marked CON_BOOT then it will be auto-unregistered
* when the first real console is registered. This is for early-printk drivers.
*/ */
#define CON_PRINTBUFFER (1) /**
#define CON_CONSDEV (2) /* Preferred console, /dev/console */ * cons_flags - General console flags
#define CON_ENABLED (4) * @CON_PRINTBUFFER: Used by newly registered consoles to avoid duplicate
#define CON_BOOT (8) * output of messages that were already shown by boot
#define CON_ANYTIME (16) /* Safe to call when cpu is offline */ * consoles or read by userspace via syslog() syscall.
#define CON_BRL (32) /* Used for a braille device */ * @CON_CONSDEV: Indicates that the console driver is backing
#define CON_EXTENDED (64) /* Use the extended output format a la /dev/kmsg */ * /dev/console.
* @CON_ENABLED: Indicates if a console is allowed to print records. If
* false, the console also will not advance to later
* records.
* @CON_BOOT: Marks the console driver as early console driver which
* is used during boot before the real driver becomes
* available. It will be automatically unregistered
* when the real console driver is registered unless
* "keep_bootcon" parameter is used.
* @CON_ANYTIME: A misnomed historical flag which tells the core code
* that the legacy @console::write callback can be invoked
* on a CPU which is marked OFFLINE. That is misleading as
* it suggests that there is no contextual limit for
* invoking the callback. The original motivation was
* readiness of the per-CPU areas.
* @CON_BRL: Indicates a braille device which is exempt from
* receiving the printk spam for obvious reasons.
* @CON_EXTENDED: The console supports the extended output format of
* /dev/kmesg which requires a larger output buffer.
*/
enum cons_flags {
CON_PRINTBUFFER = BIT(0),
CON_CONSDEV = BIT(1),
CON_ENABLED = BIT(2),
CON_BOOT = BIT(3),
CON_ANYTIME = BIT(4),
CON_BRL = BIT(5),
CON_EXTENDED = BIT(6),
};
/**
* struct console - The console descriptor structure
* @name: The name of the console driver
* @write: Write callback to output messages (Optional)
* @read: Read callback for console input (Optional)
* @device: The underlying TTY device driver (Optional)
* @unblank: Callback to unblank the console (Optional)
* @setup: Callback for initializing the console (Optional)
* @exit: Callback for teardown of the console (Optional)
* @match: Callback for matching a console (Optional)
* @flags: Console flags. See enum cons_flags
* @index: Console index, e.g. port number
* @cflag: TTY control mode flags
* @ispeed: TTY input speed
* @ospeed: TTY output speed
* @seq: Sequence number of the next ringbuffer record to print
* @dropped: Number of unreported dropped ringbuffer records
* @data: Driver private data
* @node: hlist node for the console list
*/
struct console { struct console {
char name[16]; char name[16];
void (*write)(struct console *, const char *, unsigned); void (*write)(struct console *co, const char *s, unsigned int count);
int (*read)(struct console *, char *, unsigned); int (*read)(struct console *co, char *s, unsigned int count);
struct tty_driver *(*device)(struct console *, int *); struct tty_driver *(*device)(struct console *co, int *index);
void (*unblank)(void); void (*unblank)(void);
int (*setup)(struct console *, char *); int (*setup)(struct console *co, char *options);
int (*exit)(struct console *); int (*exit)(struct console *co);
int (*match)(struct console *, char *name, int idx, char *options); int (*match)(struct console *co, char *name, int idx, char *options);
short flags; short flags;
short index; short index;
int cflag; int cflag;
uint ispeed; uint ispeed;
uint ospeed; uint ospeed;
u64 seq; u64 seq;
unsigned long dropped; unsigned long dropped;
void *data; void *data;
struct hlist_node node; struct hlist_node node;
}; };
#ifdef CONFIG_LOCKDEP #ifdef CONFIG_LOCKDEP
......
...@@ -44,8 +44,6 @@ static inline const char *printk_skip_headers(const char *buffer) ...@@ -44,8 +44,6 @@ static inline const char *printk_skip_headers(const char *buffer)
return buffer; return buffer;
} }
#define CONSOLE_EXT_LOG_MAX 8192
/* printk's without a loglevel use this.. */ /* printk's without a loglevel use this.. */
#define MESSAGE_LOGLEVEL_DEFAULT CONFIG_MESSAGE_LOGLEVEL_DEFAULT #define MESSAGE_LOGLEVEL_DEFAULT CONFIG_MESSAGE_LOGLEVEL_DEFAULT
......
...@@ -145,7 +145,7 @@ static void pi_create_file(struct module *mod) ...@@ -145,7 +145,7 @@ static void pi_create_file(struct module *mod)
#ifdef CONFIG_MODULES #ifdef CONFIG_MODULES
static void pi_remove_file(struct module *mod) static void pi_remove_file(struct module *mod)
{ {
debugfs_remove(debugfs_lookup(pi_get_module_name(mod), dfs_index)); debugfs_lookup_and_remove(pi_get_module_name(mod), dfs_index);
} }
static int pi_module_notify(struct notifier_block *nb, unsigned long op, static int pi_module_notify(struct notifier_block *nb, unsigned long op,
......
...@@ -14,6 +14,21 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, ...@@ -14,6 +14,21 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,
#ifdef CONFIG_PRINTK #ifdef CONFIG_PRINTK
#ifdef CONFIG_PRINTK_CALLER
#define PRINTK_PREFIX_MAX 48
#else
#define PRINTK_PREFIX_MAX 32
#endif
/*
* the maximum size of a formatted record (i.e. with prefix added
* per line and dropped messages or in extended message format)
*/
#define PRINTK_MESSAGE_MAX 2048
/* the maximum size allowed to be reserved for a record */
#define PRINTKRB_RECORD_MAX 1024
/* Flags for a single printk record. */ /* Flags for a single printk record. */
enum printk_info_flags { enum printk_info_flags {
LOG_NEWLINE = 2, /* text ended with a newline */ LOG_NEWLINE = 2, /* text ended with a newline */
...@@ -48,6 +63,10 @@ u16 printk_parse_prefix(const char *text, int *level, ...@@ -48,6 +63,10 @@ u16 printk_parse_prefix(const char *text, int *level,
enum printk_info_flags *flags); enum printk_info_flags *flags);
#else #else
#define PRINTK_PREFIX_MAX 0
#define PRINTK_MESSAGE_MAX 0
#define PRINTKRB_RECORD_MAX 0
/* /*
* In !PRINTK builds we still export console_sem * In !PRINTK builds we still export console_sem
* semaphore and some of console functions (console_unlock()/etc.), so * semaphore and some of console functions (console_unlock()/etc.), so
...@@ -58,3 +77,29 @@ u16 printk_parse_prefix(const char *text, int *level, ...@@ -58,3 +77,29 @@ u16 printk_parse_prefix(const char *text, int *level,
static inline bool printk_percpu_data_ready(void) { return false; } static inline bool printk_percpu_data_ready(void) { return false; }
#endif /* CONFIG_PRINTK */ #endif /* CONFIG_PRINTK */
/**
* struct printk_buffers - Buffers to read/format/output printk messages.
* @outbuf: After formatting, contains text to output.
* @scratchbuf: Used as temporary ringbuffer reading and string-print space.
*/
struct printk_buffers {
char outbuf[PRINTK_MESSAGE_MAX];
char scratchbuf[PRINTKRB_RECORD_MAX];
};
/**
* struct printk_message - Container for a prepared printk message.
* @pbufs: printk buffers used to prepare the message.
* @outbuf_len: The length of prepared text in @pbufs->outbuf to output. This
* does not count the terminator. A value of 0 means there is
* nothing to output and this record should be skipped.
* @seq: The sequence number of the record used for @pbufs->outbuf.
* @dropped: The number of dropped records from reading @seq.
*/
struct printk_message {
struct printk_buffers *pbufs;
unsigned int outbuf_len;
u64 seq;
unsigned long dropped;
};
This diff is collapsed.
...@@ -21,6 +21,7 @@ static const char *names_0[] = { ...@@ -21,6 +21,7 @@ static const char *names_0[] = {
E(EADDRNOTAVAIL), E(EADDRNOTAVAIL),
E(EADV), E(EADV),
E(EAFNOSUPPORT), E(EAFNOSUPPORT),
E(EAGAIN), /* EWOULDBLOCK */
E(EALREADY), E(EALREADY),
E(EBADE), E(EBADE),
E(EBADF), E(EBADF),
...@@ -31,15 +32,17 @@ static const char *names_0[] = { ...@@ -31,15 +32,17 @@ static const char *names_0[] = {
E(EBADSLT), E(EBADSLT),
E(EBFONT), E(EBFONT),
E(EBUSY), E(EBUSY),
#ifdef ECANCELLED E(ECANCELED), /* ECANCELLED */
E(ECANCELLED),
#endif
E(ECHILD), E(ECHILD),
E(ECHRNG), E(ECHRNG),
E(ECOMM), E(ECOMM),
E(ECONNABORTED), E(ECONNABORTED),
E(ECONNREFUSED), /* EREFUSED */
E(ECONNRESET), E(ECONNRESET),
E(EDEADLK), /* EDEADLOCK */
#if EDEADLK != EDEADLOCK /* mips, sparc, powerpc */
E(EDEADLOCK), E(EDEADLOCK),
#endif
E(EDESTADDRREQ), E(EDESTADDRREQ),
E(EDOM), E(EDOM),
E(EDOTDOT), E(EDOTDOT),
...@@ -166,14 +169,17 @@ static const char *names_0[] = { ...@@ -166,14 +169,17 @@ static const char *names_0[] = {
E(EUSERS), E(EUSERS),
E(EXDEV), E(EXDEV),
E(EXFULL), E(EXFULL),
E(ECANCELED), /* ECANCELLED */
E(EAGAIN), /* EWOULDBLOCK */
E(ECONNREFUSED), /* EREFUSED */
E(EDEADLK), /* EDEADLOCK */
}; };
#undef E #undef E
#ifdef EREFUSED /* parisc */
static_assert(EREFUSED == ECONNREFUSED);
#endif
#ifdef ECANCELLED /* parisc */
static_assert(ECANCELLED == ECANCELED);
#endif
static_assert(EAGAIN == EWOULDBLOCK); /* everywhere */
#define E(err) [err - 512 + BUILD_BUG_ON_ZERO(err < 512 || err > 550)] = "-" #err #define E(err) [err - 512 + BUILD_BUG_ON_ZERO(err < 512 || err > 550)] = "-" #err
static const char *names_512[] = { static const char *names_512[] = {
E(ERESTARTSYS), E(ERESTARTSYS),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment