Commit d8763154 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -312,10 +312,10 @@ define dmesg
			set var $prev_flags = $info->flags
		end

		set var $id = ($id + 1) & $id_mask
		if ($id == $end_id)
			loop_break
		end
		set var $id = ($id + 1) & $id_mask
	end
end
document dmesg
+73 −27
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#define _LINUX_CONSOLE_H_ 1

#include <linux/atomic.h>
#include <linux/bits.h>
#include <linux/rculist.h>
#include <linux/types.h>

@@ -125,28 +126,73 @@ static inline int con_debug_leave(void)
/*
 * The interface for a console, or any other device that wants to capture
 * 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 */
#define CON_ENABLED	(4)
#define CON_BOOT	(8)
#define CON_ANYTIME	(16) /* Safe to call when cpu is offline */
#define CON_BRL		(32) /* Used for a braille device */
#define CON_EXTENDED	(64) /* Use the extended output format a la /dev/kmsg */
/**
 * cons_flags - General console flags
 * @CON_PRINTBUFFER:	Used by newly registered consoles to avoid duplicate
 *			output of messages that were already shown by boot
 *			consoles or read by userspace via syslog() syscall.
 * @CON_CONSDEV:	Indicates that the console driver is backing
 *			/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 {
	char			name[16];
	void	(*write)(struct console *, const char *, unsigned);
	int	(*read)(struct console *, char *, unsigned);
	struct tty_driver *(*device)(struct console *, int *);
	void			(*write)(struct console *co, const char *s, unsigned int count);
	int			(*read)(struct console *co, char *s, unsigned int count);
	struct tty_driver	*(*device)(struct console *co, int *index);
	void			(*unblank)(void);
	int	(*setup)(struct console *, char *);
	int	(*exit)(struct console *);
	int	(*match)(struct console *, char *name, int idx, char *options);
	int			(*setup)(struct console *co, char *options);
	int			(*exit)(struct console *co);
	int			(*match)(struct console *co, char *name, int idx, char *options);
	short			flags;
	short			index;
	int			cflag;
+0 −2
Original line number Diff line number Diff line
@@ -44,8 +44,6 @@ static inline const char *printk_skip_headers(const char *buffer)
	return buffer;
}

#define CONSOLE_EXT_LOG_MAX	8192

/* printk's without a loglevel use this.. */
#define MESSAGE_LOGLEVEL_DEFAULT CONFIG_MESSAGE_LOGLEVEL_DEFAULT

+1 −1
Original line number Diff line number Diff line
@@ -145,7 +145,7 @@ static void pi_create_file(struct module *mod)
#ifdef CONFIG_MODULES
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,
+45 −0
Original line number Diff line number Diff line
@@ -14,6 +14,21 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,

#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. */
enum printk_info_flags {
	LOG_NEWLINE	= 2,	/* text ended with a newline */
@@ -48,6 +63,10 @@ u16 printk_parse_prefix(const char *text, int *level,
			enum printk_info_flags *flags);
#else

#define PRINTK_PREFIX_MAX	0
#define PRINTK_MESSAGE_MAX	0
#define PRINTKRB_RECORD_MAX	0

/*
 * In !PRINTK builds we still export console_sem
 * semaphore and some of console functions (console_unlock()/etc.), so
@@ -58,3 +77,29 @@ u16 printk_parse_prefix(const char *text, int *level,

static inline bool printk_percpu_data_ready(void) { return false; }
#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;
};
Loading