Skip to content

Commit 4ca6c02

Browse files
committed
Merge tag 'printk-for-6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux
Pull printk updates from Petr Mladek: - Prevent possible deadlocks, caused by the lock serializing per-CPU backtraces, by entering the deferred printk context - Enforce the right casting in LOG_BUF_LEN_MAX definition * tag 'printk-for-6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux: printk: Defer legacy printing when holding printk_cpu_sync printk: Remove redundant deferred check in vprintk() printk: Fix signed integer overflow when defining LOG_BUF_LEN_MAX
2 parents 62de6e1 + 4859bcd commit 4ca6c02

File tree

3 files changed

+18
-11
lines changed

3 files changed

+18
-11
lines changed

kernel/printk/internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,3 +338,9 @@ bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
338338
void console_prepend_dropped(struct printk_message *pmsg, unsigned long dropped);
339339
void console_prepend_replay(struct printk_message *pmsg);
340340
#endif
341+
342+
#ifdef CONFIG_SMP
343+
bool is_printk_cpu_sync_owner(void);
344+
#else
345+
static inline bool is_printk_cpu_sync_owner(void) { return false; }
346+
#endif

kernel/printk/printk.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ static struct latched_seq clear_seq = {
523523
/* record buffer */
524524
#define LOG_ALIGN __alignof__(unsigned long)
525525
#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
526-
#define LOG_BUF_LEN_MAX (u32)(1 << 31)
526+
#define LOG_BUF_LEN_MAX ((u32)1 << 31)
527527
static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
528528
static char *log_buf = __log_buf;
529529
static u32 log_buf_len = __LOG_BUF_LEN;
@@ -4922,6 +4922,11 @@ void console_try_replay_all(void)
49224922
static atomic_t printk_cpu_sync_owner = ATOMIC_INIT(-1);
49234923
static atomic_t printk_cpu_sync_nested = ATOMIC_INIT(0);
49244924

4925+
bool is_printk_cpu_sync_owner(void)
4926+
{
4927+
return (atomic_read(&printk_cpu_sync_owner) == raw_smp_processor_id());
4928+
}
4929+
49254930
/**
49264931
* __printk_cpu_sync_wait() - Busy wait until the printk cpu-reentrant
49274932
* spinning lock is not owned by any CPU.

kernel/printk/printk_safe.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,15 @@ bool is_printk_legacy_deferred(void)
6161
/*
6262
* The per-CPU variable @printk_context can be read safely in any
6363
* context. CPU migration is always disabled when set.
64+
*
65+
* A context holding the printk_cpu_sync must not spin waiting for
66+
* another CPU. For legacy printing, it could be the console_lock
67+
* or the port lock.
6468
*/
6569
return (force_legacy_kthread() ||
6670
this_cpu_read(printk_context) ||
67-
in_nmi());
71+
in_nmi() ||
72+
is_printk_cpu_sync_owner());
6873
}
6974

7075
asmlinkage int vprintk(const char *fmt, va_list args)
@@ -74,15 +79,6 @@ asmlinkage int vprintk(const char *fmt, va_list args)
7479
if (unlikely(kdb_trap_printk && kdb_printf_cpu < 0))
7580
return vkdb_printf(KDB_MSGSRC_PRINTK, fmt, args);
7681
#endif
77-
78-
/*
79-
* Use the main logbuf even in NMI. But avoid calling console
80-
* drivers that might have their own locks.
81-
*/
82-
if (is_printk_legacy_deferred())
83-
return vprintk_deferred(fmt, args);
84-
85-
/* No obstacles. */
8682
return vprintk_default(fmt, args);
8783
}
8884
EXPORT_SYMBOL(vprintk);

0 commit comments

Comments
 (0)