Skip to content

Commit

Permalink
Merge tag 'printk-for-5.8' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/printk/linux

Pull printk updates from Petr Mladek:

 - Benjamin Herrenschmidt solved a problem with non-matched console
   aliases by first checking consoles defined on the command line. It is
   a more conservative approach than the previous attempts.

 - Benjamin also made sure that the console accessible via /dev/console
   always has CON_CONSDEV flag.

 - Andy Shevchenko added the %ptT modifier for printing struct time64_t.
   It extends the existing %ptR handling for struct rtc_time.

 - Bruno Meneguele fixed /dev/kmsg error value returned by unsupported
   SEEK_CUR.

 - Tetsuo Handa removed unused pr_cont_once().

... and a few small fixes.

* tag 'printk-for-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux:
  printk: Remove pr_cont_once()
  printk: handle blank console arguments passed in.
  kernel/printk: add kmsg SEEK_CUR handling
  printk: Fix a typo in comment "interator"->"iterator"
  usb: pulse8-cec: Switch to use %ptT
  ARM: bcm2835: Switch to use %ptT
  lib/vsprintf: Print time64_t in human readable format
  lib/vsprintf: update comment about simple_strto<foo>() functions
  printk: Correctly set CON_CONSDEV even when preferred console was not registered
  printk: Fix preferred console selection with multiple matches
  printk: Move console matching logic into a separate function
  printk: Convert a use of sprintf to snprintf in console_unlock
  • Loading branch information
Linus Torvalds committed Jun 1, 2020
2 parents 4d67829 + 8b390ab commit ca1f5df
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 85 deletions.
5 changes: 5 additions & 0 deletions Documentation/ABI/testing/dev-kmsg
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ Description: The /dev/kmsg character device node provides userspace access
seek after the last record available at the time
the last SYSLOG_ACTION_CLEAR was issued.

Due to the record nature of this interface with a "read all"
behavior and the specific positions each seek operation sets,
SEEK_CUR is not supported, returning -ESPIPE (invalid seek) to
errno whenever requested.

The output format consists of a prefix carrying the syslog
prefix including priority and facility, the 64 bit message
sequence number and the monotonic timestamp in microseconds,
Expand Down
22 changes: 12 additions & 10 deletions Documentation/core-api/printk-formats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -482,21 +482,23 @@ Examples (OF)::
%pfwf /ocp@68000000/i2c@48072000/camera@10/port/endpoint - Full name
%pfwP endpoint - Node name

Time and date (struct rtc_time)
-------------------------------
Time and date
-------------

::

%ptR YYYY-mm-ddTHH:MM:SS
%ptRd YYYY-mm-dd
%ptRt HH:MM:SS
%ptR[dt][r]
%pt[RT] YYYY-mm-ddTHH:MM:SS
%pt[RT]d YYYY-mm-dd
%pt[RT]t HH:MM:SS
%pt[RT][dt][r]

For printing date and time as represented by struct rtc_time structure in
human readable format.
For printing date and time as represented by
R struct rtc_time structure
T time64_t type
in human readable format.

By default year will be incremented by 1900 and month by 1. Use %ptRr (raw)
to suppress this behaviour.
By default year will be incremented by 1900 and month by 1.
Use %pt[RT]r (raw) to suppress this behaviour.

Passed by reference.

Expand Down
12 changes: 3 additions & 9 deletions drivers/firmware/raspberrypi.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,16 +182,10 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
RPI_FIRMWARE_GET_FIRMWARE_REVISION,
&packet, sizeof(packet));

if (ret == 0) {
struct tm tm;

time64_to_tm(packet, 0, &tm);
if (ret)
return;

dev_info(fw->cl.dev,
"Attached to firmware from %04ld-%02d-%02d %02d:%02d\n",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min);
}
dev_info(fw->cl.dev, "Attached to firmware from %ptT\n", &packet);
}

static void
Expand Down
6 changes: 1 addition & 5 deletions drivers/media/usb/pulse8-cec/pulse8-cec.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,6 @@ static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio,
u8 *data = pulse8->data + 1;
u8 cmd[2];
int err;
struct tm tm;
time64_t date;

pulse8->vers = 0;
Expand All @@ -682,10 +681,7 @@ static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio,
if (err)
return err;
date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
time64_to_tm(date, 0, &tm);
dev_info(pulse8->dev, "Firmware build date %04ld.%02d.%02d %02d:%02d:%02d\n",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
dev_info(pulse8->dev, "Firmware build date %ptT\n", &date);

dev_dbg(pulse8->dev, "Persistent config:\n");
cmd[0] = MSGCODE_GET_AUTO_ENABLED;
Expand Down
2 changes: 1 addition & 1 deletion include/linux/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static inline int con_debug_leave(void)
*/

#define CON_PRINTBUFFER (1)
#define CON_CONSDEV (2) /* Last on the command line */
#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 */
Expand Down
3 changes: 1 addition & 2 deletions include/linux/printk.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,7 @@ extern int kptr_restrict;
printk_once(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
#define pr_info_once(fmt, ...) \
printk_once(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
#define pr_cont_once(fmt, ...) \
printk_once(KERN_CONT pr_fmt(fmt), ##__VA_ARGS__)
/* no pr_cont_once, don't do that... */

#if defined(DEBUG)
#define pr_devel_once(fmt, ...) \
Expand Down
1 change: 1 addition & 0 deletions kernel/printk/console_cmdline.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ struct console_cmdline
{
char name[16]; /* Name of the driver */
int index; /* Minor dev. to use */
bool user_specified; /* Specified by command line vs. platform */
char *options; /* Options for the driver */
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
char *brl_options; /* Options for braille driver */
Expand Down
145 changes: 96 additions & 49 deletions kernel/printk/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ static struct console *exclusive_console;
static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];

static int preferred_console = -1;
static bool has_preferred_console;
int console_set_on_cmdline;
EXPORT_SYMBOL(console_set_on_cmdline);

Expand Down Expand Up @@ -974,6 +975,16 @@ static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence)
user->idx = log_next_idx;
user->seq = log_next_seq;
break;
case SEEK_CUR:
/*
* It isn't supported due to the record nature of this
* interface: _SET _DATA and _END point to very specific
* record positions, while _CUR would be more useful in case
* of a byte-based log. Because of that, return the default
* errno value for invalid seek operation.
*/
ret = -ESPIPE;
break;
default:
ret = -EINVAL;
}
Expand Down Expand Up @@ -2140,7 +2151,7 @@ asmlinkage __visible void early_printk(const char *fmt, ...)
#endif

static int __add_preferred_console(char *name, int idx, char *options,
char *brl_options)
char *brl_options, bool user_specified)
{
struct console_cmdline *c;
int i;
Expand All @@ -2155,6 +2166,8 @@ static int __add_preferred_console(char *name, int idx, char *options,
if (strcmp(c->name, name) == 0 && c->index == idx) {
if (!brl_options)
preferred_console = i;
if (user_specified)
c->user_specified = true;
return 0;
}
}
Expand All @@ -2164,6 +2177,7 @@ static int __add_preferred_console(char *name, int idx, char *options,
preferred_console = i;
strlcpy(c->name, name, sizeof(c->name));
c->options = options;
c->user_specified = user_specified;
braille_set_options(c, brl_options);

c->index = idx;
Expand All @@ -2190,6 +2204,9 @@ static int __init console_setup(char *str)
char *s, *options, *brl_options = NULL;
int idx;

if (str[0] == 0)
return 1;

if (_braille_console_setup(&str, &brl_options))
return 1;

Expand Down Expand Up @@ -2218,7 +2235,7 @@ static int __init console_setup(char *str)
idx = simple_strtoul(s, NULL, 10);
*s = 0;

__add_preferred_console(buf, idx, options, brl_options);
__add_preferred_console(buf, idx, options, brl_options, true);
console_set_on_cmdline = 1;
return 1;
}
Expand All @@ -2239,7 +2256,7 @@ __setup("console=", console_setup);
*/
int add_preferred_console(char *name, int idx, char *options)
{
return __add_preferred_console(name, idx, options, NULL);
return __add_preferred_console(name, idx, options, NULL, false);
}

bool console_suspend_enabled = true;
Expand Down Expand Up @@ -2438,9 +2455,9 @@ void console_unlock(void)
printk_safe_enter_irqsave(flags);
raw_spin_lock(&logbuf_lock);
if (console_seq < log_first_seq) {
len = sprintf(text,
"** %llu printk messages dropped **\n",
log_first_seq - console_seq);
len = snprintf(text, sizeof(text),
"** %llu printk messages dropped **\n",
log_first_seq - console_seq);

/* messages are gone, move to first one */
console_seq = log_first_seq;
Expand Down Expand Up @@ -2651,6 +2668,63 @@ static int __init keep_bootcon_setup(char *str)

early_param("keep_bootcon", keep_bootcon_setup);

/*
* This is called by register_console() to try to match
* the newly registered console with any of the ones selected
* by either the command line or add_preferred_console() and
* setup/enable it.
*
* Care need to be taken with consoles that are statically
* enabled such as netconsole
*/
static int try_enable_new_console(struct console *newcon, bool user_specified)
{
struct console_cmdline *c;
int i;

for (i = 0, c = console_cmdline;
i < MAX_CMDLINECONSOLES && c->name[0];
i++, c++) {
if (c->user_specified != user_specified)
continue;
if (!newcon->match ||
newcon->match(newcon, c->name, c->index, c->options) != 0) {
/* default matching */
BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
if (strcmp(c->name, newcon->name) != 0)
continue;
if (newcon->index >= 0 &&
newcon->index != c->index)
continue;
if (newcon->index < 0)
newcon->index = c->index;

if (_braille_register_console(newcon, c))
return 0;

if (newcon->setup &&
newcon->setup(newcon, c->options) != 0)
return -EIO;
}
newcon->flags |= CON_ENABLED;
if (i == preferred_console) {
newcon->flags |= CON_CONSDEV;
has_preferred_console = true;
}
return 0;
}

/*
* Some consoles, such as pstore and netconsole, can be enabled even
* without matching. Accept the pre-enabled consoles only when match()
* and setup() had a change to be called.
*/
if (newcon->flags & CON_ENABLED && c->user_specified == user_specified)
return 0;

return -ENOENT;
}

/*
* The console driver calls this routine during kernel initialization
* to register the console printing procedure with printk() and to
Expand All @@ -2672,11 +2746,9 @@ early_param("keep_bootcon", keep_bootcon_setup);
*/
void register_console(struct console *newcon)
{
int i;
unsigned long flags;
struct console *bcon = NULL;
struct console_cmdline *c;
static bool has_preferred;
int err;

for_each_console(bcon) {
if (WARN(bcon == newcon, "console '%s%d' already registered\n",
Expand All @@ -2701,63 +2773,36 @@ void register_console(struct console *newcon)
if (console_drivers && console_drivers->flags & CON_BOOT)
bcon = console_drivers;

if (!has_preferred || bcon || !console_drivers)
has_preferred = preferred_console >= 0;
if (!has_preferred_console || bcon || !console_drivers)
has_preferred_console = preferred_console >= 0;

/*
* See if we want to use this console driver. If we
* didn't select a console we take the first one
* that registers here.
*/
if (!has_preferred) {
if (!has_preferred_console) {
if (newcon->index < 0)
newcon->index = 0;
if (newcon->setup == NULL ||
newcon->setup(newcon, NULL) == 0) {
newcon->flags |= CON_ENABLED;
if (newcon->device) {
newcon->flags |= CON_CONSDEV;
has_preferred = true;
has_preferred_console = true;
}
}
}

/*
* See if this console matches one we selected on
* the command line.
*/
for (i = 0, c = console_cmdline;
i < MAX_CMDLINECONSOLES && c->name[0];
i++, c++) {
if (!newcon->match ||
newcon->match(newcon, c->name, c->index, c->options) != 0) {
/* default matching */
BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
if (strcmp(c->name, newcon->name) != 0)
continue;
if (newcon->index >= 0 &&
newcon->index != c->index)
continue;
if (newcon->index < 0)
newcon->index = c->index;
/* See if this console matches one we selected on the command line */
err = try_enable_new_console(newcon, true);

if (_braille_register_console(newcon, c))
return;

if (newcon->setup &&
newcon->setup(newcon, c->options) != 0)
break;
}

newcon->flags |= CON_ENABLED;
if (i == preferred_console) {
newcon->flags |= CON_CONSDEV;
has_preferred = true;
}
break;
}
/* If not, try to match against the platform default(s) */
if (err == -ENOENT)
err = try_enable_new_console(newcon, false);

if (!(newcon->flags & CON_ENABLED))
/* printk() messages are not printed to the Braille console. */
if (err || newcon->flags & CON_BRL)
return;

/*
Expand All @@ -2779,6 +2824,8 @@ void register_console(struct console *newcon)
console_drivers = newcon;
if (newcon->next)
newcon->next->flags &= ~CON_CONSDEV;
/* Ensure this flag is always set for the head of the list */
newcon->flags |= CON_CONSDEV;
} else {
newcon->next = console_drivers->next;
console_drivers->next = newcon;
Expand Down Expand Up @@ -3384,7 +3431,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer);

/**
* kmsg_dump_rewind_nolock - reset the interator (unlocked version)
* kmsg_dump_rewind_nolock - reset the iterator (unlocked version)
* @dumper: registered kmsg dumper
*
* Reset the dumper's iterator so that kmsg_dump_get_line() and
Expand All @@ -3402,7 +3449,7 @@ void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper)
}

/**
* kmsg_dump_rewind - reset the interator
* kmsg_dump_rewind - reset the iterator
* @dumper: registered kmsg dumper
*
* Reset the dumper's iterator so that kmsg_dump_get_line() and
Expand Down
Loading

0 comments on commit ca1f5df

Please sign in to comment.