printk: Avoid false positive lockdep report for legacy printing
BugLink: https://bugs.launchpad.net/bugs/2060704 Legacy console printing from printk() caller context may invoke the console driver from atomic context. This leads to a lockdep splat because the console driver will acquire a sleeping lock and the caller may already hold a spinning lock. This is noticed by lockdep on !PREEMPT_RT configurations because it will lead to a problem on PREEMPT_RT. However, on PREEMPT_RT the printing path from atomic context is always avoided and the console driver is always invoked from a dedicated thread. Thus the lockdep splat on !PREEMPT_RT is a false positive. For !PREEMPT_RT override the lock-context before invoking the console driver to avoid the false positive. Do not override the lock-context for PREEMPT_RT in order to allow lockdep to catch any real locking context issues related to the write callback usage. Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Kevin Becker <kevin.becker@canonical.com>
This commit is contained in:
committed by
Kevin Becker
parent
cdd67ae59b
commit
26331faec8
+30
-1
@@ -2990,6 +2990,33 @@ out:
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Legacy console printing from printk() caller context does not respect
|
||||
* raw_spinlock/spinlock nesting. For !PREEMPT_RT the lockdep warning is a
|
||||
* false positive. For PREEMPT_RT the false positive condition does not
|
||||
* occur.
|
||||
*
|
||||
* This map is used to establish LD_WAIT_SLEEP context for the console write
|
||||
* callbacks when legacy printing to avoid false positive lockdep complaints,
|
||||
* thus allowing lockdep to continue to function for real issues.
|
||||
*/
|
||||
#ifdef CONFIG_PREEMPT_RT
|
||||
static inline void printk_legacy_lock_map_acquire_try(void) { }
|
||||
static inline void printk_legacy_lock_map_release(void) { }
|
||||
#else
|
||||
static DEFINE_WAIT_OVERRIDE_MAP(printk_legacy_map, LD_WAIT_SLEEP);
|
||||
|
||||
static inline void printk_legacy_lock_map_acquire_try(void)
|
||||
{
|
||||
lock_map_acquire_try(&printk_legacy_map);
|
||||
}
|
||||
|
||||
static inline void printk_legacy_lock_map_release(void)
|
||||
{
|
||||
lock_map_release(&printk_legacy_map);
|
||||
}
|
||||
#endif /* CONFIG_PREEMPT_RT */
|
||||
|
||||
/*
|
||||
* Used as the printk buffers for non-panic, serialized console printing.
|
||||
* This is for legacy (!CON_NBCON) as well as all boot (CON_BOOT) consoles.
|
||||
@@ -3045,7 +3072,7 @@ static bool console_emit_next_record(struct console *con, bool *handover, int co
|
||||
/*
|
||||
* With forced threading this function is either in a thread
|
||||
* or panic context. So there is no need for concern about
|
||||
* printk reentrance or handovers.
|
||||
* printk reentrance, handovers, or lockdep complaints.
|
||||
*/
|
||||
|
||||
con->write(con, outbuf, pmsg.outbuf_len);
|
||||
@@ -3067,7 +3094,9 @@ static bool console_emit_next_record(struct console *con, bool *handover, int co
|
||||
/* Do not trace print latency. */
|
||||
stop_critical_timings();
|
||||
|
||||
printk_legacy_lock_map_acquire_try();
|
||||
con->write(con, outbuf, pmsg.outbuf_len);
|
||||
printk_legacy_lock_map_release();
|
||||
|
||||
start_critical_timings();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user