Skip to content

Commit a229327

Browse files
committed
Merge tag 'printk-for-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux
Pull printk updates from Petr Mladek: - Remove some twists in the console registration code. It does not change the existing behavior except for one corner case. The proper default console (with tty binding) will be registered again even when it has been removed in the meantime. It is actually a bug fix. Anyway, this modified behavior requires some manual interaction. - Optimize gdb extension for huge ring buffers. - Do not use atomic operations for a local bitmap variable. - Update git links in MAINTAINERS. * tag 'printk-for-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux: MAINTAIERS/printk: Add link to printk git MAINTAINERS/vsprintf: Update link to printk git tree scripts/gdb: lx-dmesg: read records individually printk/console: Clean up boot console handling in register_console() printk/console: Remove need_default_console variable printk/console: Remove unnecessary need_default_console manipulation printk/console: Rename has_preferred_console to need_default_console printk/console: Split out code that enables default console vsprintf: Use non-atomic bitmap API when applicable
2 parents e9e64f8 + d12013c commit a229327

File tree

4 files changed

+80
-66
lines changed

4 files changed

+80
-66
lines changed

MAINTAINERS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15396,6 +15396,7 @@ M: Sergey Senozhatsky <[email protected]>
1539615396
R: Steven Rostedt <[email protected]>
1539715397
R: John Ogness <[email protected]>
1539815398
S: Maintained
15399+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux.git
1539915400
F: include/linux/printk.h
1540015401
F: kernel/printk/
1540115402

@@ -20525,7 +20526,7 @@ M: Sergey Senozhatsky <[email protected]>
2052520526
R: Andy Shevchenko <[email protected]>
2052620527
R: Rasmus Villemoes <[email protected]>
2052720528
S: Maintained
20528-
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk.git
20529+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux.git
2052920530
F: Documentation/core-api/printk-formats.rst
2053020531
F: lib/test_printf.c
2053120532
F: lib/test_scanf.c

kernel/printk/printk.c

Lines changed: 58 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ static struct console *exclusive_console;
280280
static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
281281

282282
static int preferred_console = -1;
283-
static bool has_preferred_console;
284283
int console_set_on_cmdline;
285284
EXPORT_SYMBOL(console_set_on_cmdline);
286285

@@ -2861,7 +2860,8 @@ early_param("keep_bootcon", keep_bootcon_setup);
28612860
* Care need to be taken with consoles that are statically
28622861
* enabled such as netconsole
28632862
*/
2864-
static int try_enable_new_console(struct console *newcon, bool user_specified)
2863+
static int try_enable_preferred_console(struct console *newcon,
2864+
bool user_specified)
28652865
{
28662866
struct console_cmdline *c;
28672867
int i, err;
@@ -2891,10 +2891,8 @@ static int try_enable_new_console(struct console *newcon, bool user_specified)
28912891
return err;
28922892
}
28932893
newcon->flags |= CON_ENABLED;
2894-
if (i == preferred_console) {
2894+
if (i == preferred_console)
28952895
newcon->flags |= CON_CONSDEV;
2896-
has_preferred_console = true;
2897-
}
28982896
return 0;
28992897
}
29002898

@@ -2909,6 +2907,21 @@ static int try_enable_new_console(struct console *newcon, bool user_specified)
29092907
return -ENOENT;
29102908
}
29112909

2910+
/* Try to enable the console unconditionally */
2911+
static void try_enable_default_console(struct console *newcon)
2912+
{
2913+
if (newcon->index < 0)
2914+
newcon->index = 0;
2915+
2916+
if (newcon->setup && newcon->setup(newcon, NULL) != 0)
2917+
return;
2918+
2919+
newcon->flags |= CON_ENABLED;
2920+
2921+
if (newcon->device)
2922+
newcon->flags |= CON_CONSDEV;
2923+
}
2924+
29122925
/*
29132926
* The console driver calls this routine during kernel initialization
29142927
* to register the console printing procedure with printk() and to
@@ -2930,59 +2943,56 @@ static int try_enable_new_console(struct console *newcon, bool user_specified)
29302943
*/
29312944
void register_console(struct console *newcon)
29322945
{
2933-
struct console *bcon = NULL;
2946+
struct console *con;
2947+
bool bootcon_enabled = false;
2948+
bool realcon_enabled = false;
29342949
int err;
29352950

2936-
for_each_console(bcon) {
2937-
if (WARN(bcon == newcon, "console '%s%d' already registered\n",
2938-
bcon->name, bcon->index))
2951+
for_each_console(con) {
2952+
if (WARN(con == newcon, "console '%s%d' already registered\n",
2953+
con->name, con->index))
29392954
return;
29402955
}
29412956

2942-
/*
2943-
* before we register a new CON_BOOT console, make sure we don't
2944-
* already have a valid console
2945-
*/
2946-
if (newcon->flags & CON_BOOT) {
2947-
for_each_console(bcon) {
2948-
if (!(bcon->flags & CON_BOOT)) {
2949-
pr_info("Too late to register bootconsole %s%d\n",
2950-
newcon->name, newcon->index);
2951-
return;
2952-
}
2953-
}
2957+
for_each_console(con) {
2958+
if (con->flags & CON_BOOT)
2959+
bootcon_enabled = true;
2960+
else
2961+
realcon_enabled = true;
29542962
}
29552963

2956-
if (console_drivers && console_drivers->flags & CON_BOOT)
2957-
bcon = console_drivers;
2958-
2959-
if (!has_preferred_console || bcon || !console_drivers)
2960-
has_preferred_console = preferred_console >= 0;
2964+
/* Do not register boot consoles when there already is a real one. */
2965+
if (newcon->flags & CON_BOOT && realcon_enabled) {
2966+
pr_info("Too late to register bootconsole %s%d\n",
2967+
newcon->name, newcon->index);
2968+
return;
2969+
}
29612970

29622971
/*
2963-
* See if we want to use this console driver. If we
2964-
* didn't select a console we take the first one
2965-
* that registers here.
2972+
* See if we want to enable this console driver by default.
2973+
*
2974+
* Nope when a console is preferred by the command line, device
2975+
* tree, or SPCR.
2976+
*
2977+
* The first real console with tty binding (driver) wins. More
2978+
* consoles might get enabled before the right one is found.
2979+
*
2980+
* Note that a console with tty binding will have CON_CONSDEV
2981+
* flag set and will be first in the list.
29662982
*/
2967-
if (!has_preferred_console) {
2968-
if (newcon->index < 0)
2969-
newcon->index = 0;
2970-
if (newcon->setup == NULL ||
2971-
newcon->setup(newcon, NULL) == 0) {
2972-
newcon->flags |= CON_ENABLED;
2973-
if (newcon->device) {
2974-
newcon->flags |= CON_CONSDEV;
2975-
has_preferred_console = true;
2976-
}
2983+
if (preferred_console < 0) {
2984+
if (!console_drivers || !console_drivers->device ||
2985+
console_drivers->flags & CON_BOOT) {
2986+
try_enable_default_console(newcon);
29772987
}
29782988
}
29792989

29802990
/* See if this console matches one we selected on the command line */
2981-
err = try_enable_new_console(newcon, true);
2991+
err = try_enable_preferred_console(newcon, true);
29822992

29832993
/* If not, try to match against the platform default(s) */
29842994
if (err == -ENOENT)
2985-
err = try_enable_new_console(newcon, false);
2995+
err = try_enable_preferred_console(newcon, false);
29862996

29872997
/* printk() messages are not printed to the Braille console. */
29882998
if (err || newcon->flags & CON_BRL)
@@ -2994,8 +3004,10 @@ void register_console(struct console *newcon)
29943004
* the real console are the same physical device, it's annoying to
29953005
* see the beginning boot messages twice
29963006
*/
2997-
if (bcon && ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV))
3007+
if (bootcon_enabled &&
3008+
((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV)) {
29983009
newcon->flags &= ~CON_PRINTBUFFER;
3010+
}
29993011

30003012
/*
30013013
* Put this console in the list - keep the
@@ -3051,15 +3063,15 @@ void register_console(struct console *newcon)
30513063
pr_info("%sconsole [%s%d] enabled\n",
30523064
(newcon->flags & CON_BOOT) ? "boot" : "" ,
30533065
newcon->name, newcon->index);
3054-
if (bcon &&
3066+
if (bootcon_enabled &&
30553067
((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) &&
30563068
!keep_bootcon) {
30573069
/* We need to iterate through all boot consoles, to make
30583070
* sure we print everything out, before we unregister them.
30593071
*/
3060-
for_each_console(bcon)
3061-
if (bcon->flags & CON_BOOT)
3062-
unregister_console(bcon);
3072+
for_each_console(con)
3073+
if (con->flags & CON_BOOT)
3074+
unregister_console(con);
30633075
}
30643076
}
30653077
EXPORT_SYMBOL(register_console);

lib/vsprintf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3564,7 +3564,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
35643564
++fmt;
35653565

35663566
for ( ; *fmt && *fmt != ']'; ++fmt, ++len)
3567-
set_bit((u8)*fmt, set);
3567+
__set_bit((u8)*fmt, set);
35683568

35693569
/* no ']' or no character set found */
35703570
if (!*fmt || !len)
@@ -3574,7 +3574,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
35743574
if (negate) {
35753575
bitmap_complement(set, set, 256);
35763576
/* exclude null '\0' byte */
3577-
clear_bit(0, set);
3577+
__clear_bit(0, set);
35783578
}
35793579

35803580
/* match must be non-empty */

scripts/gdb/linux/dmesg.py

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,32 +44,29 @@ def invoke(self, arg, from_tty):
4444
sz = prb_desc_ring_type.get_type().sizeof
4545
desc_ring = utils.read_memoryview(inf, addr, sz).tobytes()
4646

47-
# read in descriptor array
47+
# read in descriptor count, size, and address
4848
off = prb_desc_ring_type.get_type()['count_bits'].bitpos // 8
4949
desc_ring_count = 1 << utils.read_u32(desc_ring, off)
5050
desc_sz = prb_desc_type.get_type().sizeof
5151
off = prb_desc_ring_type.get_type()['descs'].bitpos // 8
52-
addr = utils.read_ulong(desc_ring, off)
53-
descs = utils.read_memoryview(inf, addr, desc_sz * desc_ring_count).tobytes()
52+
desc_addr = utils.read_ulong(desc_ring, off)
5453

55-
# read in info array
54+
# read in info size and address
5655
info_sz = printk_info_type.get_type().sizeof
5756
off = prb_desc_ring_type.get_type()['infos'].bitpos // 8
58-
addr = utils.read_ulong(desc_ring, off)
59-
infos = utils.read_memoryview(inf, addr, info_sz * desc_ring_count).tobytes()
57+
info_addr = utils.read_ulong(desc_ring, off)
6058

6159
# read in text data ring structure
6260
off = printk_ringbuffer_type.get_type()['text_data_ring'].bitpos // 8
6361
addr = prb_addr + off
6462
sz = prb_data_ring_type.get_type().sizeof
6563
text_data_ring = utils.read_memoryview(inf, addr, sz).tobytes()
6664

67-
# read in text data
65+
# read in text data size and address
6866
off = prb_data_ring_type.get_type()['size_bits'].bitpos // 8
6967
text_data_sz = 1 << utils.read_u32(text_data_ring, off)
7068
off = prb_data_ring_type.get_type()['data'].bitpos // 8
71-
addr = utils.read_ulong(text_data_ring, off)
72-
text_data = utils.read_memoryview(inf, addr, text_data_sz).tobytes()
69+
text_data_addr = utils.read_ulong(text_data_ring, off)
7370

7471
counter_off = atomic_long_type.get_type()['counter'].bitpos // 8
7572

@@ -102,17 +99,20 @@ def invoke(self, arg, from_tty):
10299
desc_off = desc_sz * ind
103100
info_off = info_sz * ind
104101

102+
desc = utils.read_memoryview(inf, desc_addr + desc_off, desc_sz).tobytes()
103+
105104
# skip non-committed record
106-
state = 3 & (utils.read_u64(descs, desc_off + sv_off +
107-
counter_off) >> desc_flags_shift)
105+
state = 3 & (utils.read_u64(desc, sv_off + counter_off) >> desc_flags_shift)
108106
if state != desc_committed and state != desc_finalized:
109107
if did == head_id:
110108
break
111109
did = (did + 1) & desc_id_mask
112110
continue
113111

114-
begin = utils.read_ulong(descs, desc_off + begin_off) % text_data_sz
115-
end = utils.read_ulong(descs, desc_off + next_off) % text_data_sz
112+
begin = utils.read_ulong(desc, begin_off) % text_data_sz
113+
end = utils.read_ulong(desc, next_off) % text_data_sz
114+
115+
info = utils.read_memoryview(inf, info_addr + info_off, info_sz).tobytes()
116116

117117
# handle data-less record
118118
if begin & 1 == 1:
@@ -125,16 +125,17 @@ def invoke(self, arg, from_tty):
125125
# skip over descriptor id
126126
text_start = begin + utils.get_long_type().sizeof
127127

128-
text_len = utils.read_u16(infos, info_off + len_off)
128+
text_len = utils.read_u16(info, len_off)
129129

130130
# handle truncated message
131131
if end - text_start < text_len:
132132
text_len = end - text_start
133133

134-
text = text_data[text_start:text_start + text_len].decode(
135-
encoding='utf8', errors='replace')
134+
text_data = utils.read_memoryview(inf, text_data_addr + text_start,
135+
text_len).tobytes()
136+
text = text_data[0:text_len].decode(encoding='utf8', errors='replace')
136137

137-
time_stamp = utils.read_u64(infos, info_off + ts_off)
138+
time_stamp = utils.read_u64(info, ts_off)
138139

139140
for line in text.splitlines():
140141
msg = u"[{time:12.6f}] {line}\n".format(

0 commit comments

Comments
 (0)