All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] printk: Add printk_deferred_{enter, exit}
@ 2020-09-27 16:11 Chengming Zhou
  2020-09-27 16:11 ` [PATCH 2/2] sched: mark PRINTK_DEFERRED_CONTEXT_MASK in __schedule() Chengming Zhou
  0 siblings, 1 reply; 20+ messages in thread
From: Chengming Zhou @ 2020-09-27 16:11 UTC (permalink / raw)
  To: linux-kernel, pmladek, sergey.senozhatsky, rostedt, mingo,
	peterz, juri.lelli, vincent.guittot, dietmar.eggemann, bsegall,
	mgorman
  Cc: zhouchengming, songmuchun

We use printk_deferred in scheduler code when rq lock held because calling
printk can cause deadlock. It's a nice solution but a little hard to use
when we want to mark the printk_deferred danger areas.
Currently, the use of WARN_ON or WARN_ON_ONCE in scheduler with rq lock
held can cause deadlock when warn condition met. If we can mark the
printk_deferred area when rq lock held using pintk_deferred_{enter, exit},
all console output in that area will be deferred.

Signed-off-by: Chengming Zhou <zhouchengming@bytedance.com>
Signed-off-by: MuChun Song <songmuchun@bytedance.com>
---
 include/linux/printk.h      |  8 ++++++++
 kernel/printk/internal.h    |  3 ++-
 kernel/printk/printk_safe.c | 18 ++++++++++++++++++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 34c1a7be3e01..96ab252f529a 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -147,6 +147,14 @@ static inline __printf(1, 2) __cold
 void early_printk(const char *s, ...) { }
 #endif
 
+#ifdef CONFIG_PRINTK
+extern void printk_deferred_enter(void);
+extern void printk_deferred_exit(void);
+#else
+static inline void printk_deferred_enter(void) { }
+static inline void printk_deferred_exit(void) { }
+#endif
+
 #ifdef CONFIG_PRINTK_NMI
 extern void printk_nmi_enter(void);
 extern void printk_nmi_exit(void);
diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h
index 660f9a6bf73a..b2ede46b7460 100644
--- a/kernel/printk/internal.h
+++ b/kernel/printk/internal.h
@@ -6,7 +6,8 @@
 
 #ifdef CONFIG_PRINTK
 
-#define PRINTK_SAFE_CONTEXT_MASK	0x007ffffff
+#define PRINTK_SAFE_CONTEXT_MASK	0x003ffffff
+#define PRINTK_DEFERRED_CONTEXT_MASK	0x004000000
 #define PRINTK_NMI_DIRECT_CONTEXT_MASK	0x008000000
 #define PRINTK_NMI_CONTEXT_MASK		0xff0000000
 
diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c
index 50aeae770434..f77c6880f59f 100644
--- a/kernel/printk/printk_safe.c
+++ b/kernel/printk/printk_safe.c
@@ -335,6 +335,16 @@ static __printf(1, 0) int vprintk_nmi(const char *fmt, va_list args)
 
 #endif /* CONFIG_PRINTK_NMI */
 
+void printk_deferred_enter(void)
+{
+	__this_cpu_or(printk_context, PRINTK_DEFERRED_CONTEXT_MASK);
+}
+
+void printk_deferred_exit(void)
+{
+	__this_cpu_and(printk_context, ~PRINTK_DEFERRED_CONTEXT_MASK);
+}
+
 /*
  * Lock-less printk(), to avoid deadlocks should the printk() recurse
  * into itself. It uses a per-CPU buffer to store the message, just like
@@ -385,6 +395,14 @@ __printf(1, 0) int vprintk_func(const char *fmt, va_list args)
 	if (this_cpu_read(printk_context) & PRINTK_NMI_CONTEXT_MASK)
 		return vprintk_nmi(fmt, args);
 
+	if (this_cpu_read(printk_context) & PRINTK_DEFERRED_CONTEXT_MASK) {
+		int len;
+
+		len = vprintk_emit(0, LOGLEVEL_SCHED, NULL, 0, fmt, args);
+		defer_console_output();
+		return len;
+	}
+
 	/* Use extra buffer to prevent a recursion deadlock in safe mode. */
 	if (this_cpu_read(printk_context) & PRINTK_SAFE_CONTEXT_MASK)
 		return vprintk_safe(fmt, args);
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2020-09-30  7:50 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-27 16:11 [PATCH 1/2] printk: Add printk_deferred_{enter, exit} Chengming Zhou
2020-09-27 16:11 ` [PATCH 2/2] sched: mark PRINTK_DEFERRED_CONTEXT_MASK in __schedule() Chengming Zhou
2020-09-28  7:32   ` Peter Zijlstra
2020-09-28  7:52     ` Joe Perches
2020-09-28  8:00       ` Peter Zijlstra
2020-09-28  8:06         ` Peter Zijlstra
2020-09-28  8:54     ` [External] " Chengming Zhou
2020-09-28  9:01       ` Peter Zijlstra
2020-09-28 10:04         ` Chengming Zhou
2020-09-28 10:04           ` Chengming Zhou
2020-09-28 10:25           ` Peter Zijlstra
2020-09-28 10:25             ` Peter Zijlstra
2020-09-28 23:50             ` Sergey Senozhatsky
2020-09-28 23:50               ` Sergey Senozhatsky
2020-09-29 14:27             ` Petr Mladek
2020-09-29 14:27               ` Petr Mladek
2020-09-29 15:09               ` Peter Zijlstra
2020-09-29 15:09                 ` Peter Zijlstra
2020-09-30  0:48                 ` Sergey Senozhatsky
2020-09-30  0:48                   ` Sergey Senozhatsky

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.