Skip to contentSkip to conversation

dump_stack: allow specifying printk log level

PATCH In review [email protected] 4 participants 11 messages Nov 5, 2015 – Dec 2, 2015

Subsystems (7)
lore
Share & tools
lore
#0 lore raw

cover dump_stack: allow specifying printk log level

This patchset lays the foundation work to allow using dump_stack() with a specified printk log level. Currently each architecture uses a different log level in show_stack() and it's not possible to control it without calling directly architecture specific functions.

The motivation behind this work is to limit the amount of kernel messages printed in the console when a process is killed by the OOM killer. In some scenarios (lots of containers running different customers' workloads) OOMs are way more common and don't require the console to be flooded by stack traces when the OOM killer probably did the right choice. During a recent discussion it was determined that a knob to control when dump_stack() is called is a bad idea and instead we should tune the log level in dump_stack() which prompted this work.

This patchset introduces two new functions:
dump_stack_lvl(char *log_lvl)
show_stack_lvl(struct task_struct *task, unsigned long *sp, char *log_lvl)

and both can be reimplemented by each architecture but only the second is expected. The idea is to initially implement show_stack_lvl() in all architectures then simply have show_stack() to require log_lvl as parameter. While that happens, dump_stack() uses can be changed to dump_stack_lvl() and once everything is in place, dump_stack() will require the log_level as well.

I have a draft patch for every architecture but for this patchset I'm only including x86 to get some feedback while I try to get a cross compiler working for each one of them (which is being harder than I thought).

Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Greg Thelen <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc David Rientjes <[email protected]>
Signature · 7 lines
Aristeu

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#1 lore raw

PATCH 1/5 dump_stack: pass log level to dump_stack_print_info()

This is in preparation for dump_stack_lvl() which will allow the log level to be passed.

Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Greg Thelen <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc David Rientjes <[email protected]>
---
 lib/dump_stack.c |   16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)
lib/dump_stack.c +11 -5
@@ -9,9 +9,9 @@
 #include <linux/smp.h>
 #include <linux/atomic.h>
 
-static void __dump_stack(void)
+static void __dump_stack(char *log_lvl)
 {
-	dump_stack_print_info(KERN_DEFAULT);
+	dump_stack_print_info(log_lvl);
 	show_stack(NULL, NULL);
 }
 
@@ -23,7 +23,7 @@ static void __dump_stack(void)
 #ifdef CONFIG_SMP
 static atomic_t dump_lock = ATOMIC_INIT(-1);
 
-asmlinkage __visible void dump_stack(void)
+static void _dump_stack(char *log_lvl)
 {
 	int was_locked;
 	int old;
@@ -47,17 +47,23 @@ was_locked = 0;
 		goto retry;
 	}
 
-	__dump_stack();
+	__dump_stack(log_lvl);
 
 	if (!was_locked)
 		atomic_set(&dump_lock, -1);
 
 	preempt_enable();
 }
+
+asmlinkage __visible void dump_stack(void)
+{
+	_dump_stack(KERN_DEFAULT);
+}
+
 #else
 asmlinkage __visible void dump_stack(void)
 {
-	__dump_stack();
+	__dump_stack(KERN_DEFAULT);
 }
 #endif
 EXPORT_SYMBOL(dump_stack);

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#2 lore raw

PATCH 2/5 dump_stack: introduce dump_stack_lvl

In reply to [email protected]

dump_stack_lvl() allows passing the log level down to the architecture specific code.

Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Greg Thelen <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc David Rientjes <[email protected]>
---
 include/linux/printk.h |    1 +
 lib/dump_stack.c       |   11 +++++++++++
 2 files changed, 12 insertions(+)
lib/dump_stack.c +11 -0
@@ -55,6 +55,11 @@ was_locked = 0;
 	preempt_enable();
 }
 
+asmlinkage __visible void dump_stack_lvl(char *log_lvl)
+{
+	_dump_stack(log_lvl);
+}
+
 asmlinkage __visible void dump_stack(void)
 {
 	_dump_stack(KERN_DEFAULT);
@@ -65,5 +70,11 @@ asmlinkage __visible void dump_stack(voi
 {
 	__dump_stack(KERN_DEFAULT);
 }
+
+asmlinkage __visible void dump_stack_lvl(char *log_lvl)
+{
+	__dump_stack(log_lvl);
+}
 #endif
 EXPORT_SYMBOL(dump_stack);
+EXPORT_SYMBOL(dump_stack_lvl);
include/linux/printk.h +1 -0
@@ -231,6 +231,7 @@ static inline void show_regs_print_info(
 #endif
 
 extern asmlinkage void dump_stack(void) __cold;
+extern asmlinkage void dump_stack_lvl(char *log_lvl);
 
 #ifndef pr_fmt
 #define pr_fmt(fmt) fmt

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#3 lore raw

PATCH 3/5 dump_stack: introduce generic show_stack_lvl()

In reply to [email protected]

show_stack_lvl() works like show_stack() but allows also passing the log level. The default implementation that should be overrided by architecture specific code simply will call the existing show_stack().

Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Greg Thelen <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc David Rientjes <[email protected]>
---
 include/linux/sched.h |    2 ++
 lib/dump_stack.c      |    8 +++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)
lib/dump_stack.c +7 -1
@@ -9,10 +9,16 @@
 #include <linux/smp.h>
 #include <linux/atomic.h>
 
+void __weak show_stack_lvl(struct task_struct *task, unsigned long *sp,
+			       char *log_lvl)
+{
+	return show_stack(task, sp);
+}
+
 static void __dump_stack(char *log_lvl)
 {
 	dump_stack_print_info(log_lvl);
-	show_stack(NULL, NULL);
+	show_stack_lvl(NULL, NULL, log_lvl);
 }
 
 /**
include/linux/sched.h +2 -0
@@ -368,6 +368,8 @@ extern void show_regs(struct pt_regs *);
  * trace (or NULL if the entire call-chain of the task should be shown).
  */
 extern void show_stack(struct task_struct *task, unsigned long *sp);
+extern void show_stack_lvl(struct task_struct *task, unsigned long *sp,
+			   char *log_lvl);
 
 extern void cpu_init (void);
 extern void trap_init(void);

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#4 lore raw

PATCH 4/5 x86: dumpstack - implement show_stack_lvl()

In reply to [email protected]

show_stack_lvl() allows passing the log level and is used by dump_stack_lvl().

Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Greg Thelen <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc David Rientjes <[email protected]>
---
 arch/x86/kernel/dumpstack.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
arch/x86/kernel/dumpstack.c +7 -2
@@ -180,7 +180,7 @@ void show_trace(struct task_struct *task
 	show_trace_log_lvl(task, regs, stack, bp, "");
 }
 
-void show_stack(struct task_struct *task, unsigned long *sp)
+void show_stack_lvl(struct task_struct *task, unsigned long *sp, char *log_lvl)
 {
 	unsigned long bp = 0;
 	unsigned long stack;
@@ -194,7 +194,12 @@ unsigned long bp = 0;
 		bp = stack_frame(current, NULL);
 	}
 
-	show_stack_log_lvl(task, NULL, sp, bp, "");
+	show_stack_log_lvl(task, NULL, sp, bp, log_lvl);
+}
+
+void show_stack(struct task_struct *task, unsigned long *sp)
+{
+	show_stack_lvl(task, sp, KERN_DEFAULT);
 }
 
 static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

Acked-by on v1 4/5
#5 lore raw

Re: [PATCH 4/5] x86: dumpstack - implement show_stack_lvl()

Quoted 30 lines · * [email protected] <[email protected]> wrote:

show_stack_lvl() allows passing the log level and is used by dump_stack_lvl().

Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Greg Thelen <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc David Rientjes <[email protected]>
---
 arch/x86/kernel/dumpstack.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
arch/x86/kernel/dumpstack.c +1 -1
@@ -180,7 +180,7 @@ void show_trace(struct task_struct *task
 	show_trace_log_lvl(task, regs, stack, bp, "");
 }
 
-void show_stack(struct task_struct *task, unsigned long *sp)
+void show_stack_lvl(struct task_struct *task, unsigned long *sp, char *log_lvl)
 {
 	unsigned long bp = 0;
 	unsigned long stack;
@@ -194,7 +194,12 @@ unsigned long bp = 0;
 		bp = stack_frame(current, NULL);
 	}
 

arch/x86/kernel/dumpstack.c unsigned long bp = 0; · line 205

Quoted 10 lines
arch/x86/kernel/dumpstack.c +6 -1
-	show_stack_log_lvl(task, NULL, sp, bp, "");
+	show_stack_log_lvl(task, NULL, sp, bp, log_lvl);
+}
+
+void show_stack(struct task_struct *task, unsigned long *sp)
+{
+	show_stack_lvl(task, sp, KERN_DEFAULT);
 }
 
 static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;

Thanks,

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#6 lore raw

PATCH 5/5 mm: use KERN_DEBUG for dump_stack() during an OOM

In reply to [email protected]

dump_stack() isn't always useful and in some scenarios OOMs can be quite common and there's no need to flood the console with dump_stack()'s output.

Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Greg Thelen <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc David Rientjes <[email protected]>
---
 mm/oom_kill.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
mm/oom_kill.c +1 -1
@@ -384,7 +384,7 @@ pr_warning("%s invoked oom-killer: gfp_m
 		current->signal->oom_score_adj);
 	cpuset_print_task_mems_allowed(current);
 	task_unlock(current);
-	dump_stack();
+	dump_stack_lvl(KERN_DEBUG);
 	if (memcg)
 		mem_cgroup_print_oom_info(memcg, p);
 	else

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

Acked-by on v1 5/5
#7 lore raw

Re: [PATCH 5/5] mm: use KERN_DEBUG for dump_stack() during an OOM

[Hmm, this got stuck in my outgoing queue for some reason - sending again]

Quoted 2 lines · On Thu 05-11-15 17:30:19, [email protected] wrote:

dump_stack() isn't always useful and in some scenarios OOMs can be quite common and there's no need to flood the console with dump_stack()'s output.

I think we want to revisit loglevel of other parts of the oom report as well but this is a good start.

Quoted 8 lines
Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Greg Thelen <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc David Rientjes <[email protected]>
Quoted 16 lines
---
 mm/oom_kill.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
mm/oom_kill.c +1 -1
@@ -384,7 +384,7 @@ pr_warning("%s invoked oom-killer: gfp_m
 		current->signal->oom_score_adj);
 	cpuset_print_task_mems_allowed(current);
 	task_unlock(current);
-	dump_stack();
+	dump_stack_lvl(KERN_DEBUG);
 	if (memcg)
 		mem_cgroup_print_oom_info(memcg, p);
 	else
Signature · 8 lines
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#8 lore raw
In reply to [email protected]
Quoted 18 lines · On Thu 05-11-15 17:30:14, [email protected] wrote:

This patchset lays the foundation work to allow using dump_stack() with a specified printk log level. Currently each architecture uses a different log level in show_stack() and it's not possible to control it without calling directly architecture specific functions.

The motivation behind this work is to limit the amount of kernel messages printed in the console when a process is killed by the OOM killer. In some scenarios (lots of containers running different customers' workloads) OOMs are way more common and don't require the console to be flooded by stack traces when the OOM killer probably did the right choice. During a recent discussion it was determined that a knob to control when dump_stack() is called is a bad idea and instead we should tune the log level in dump_stack() which prompted this work.

This patchset introduces two new functions:
dump_stack_lvl(char *log_lvl)
show_stack_lvl(struct task_struct *task, unsigned long *sp, char *log_lvl)

Quoted 5 lines

and both can be reimplemented by each architecture but only the second is expected. The idea is to initially implement show_stack_lvl() in all architectures then simply have show_stack() to require log_lvl as parameter. While that happens, dump_stack() uses can be changed to dump_stack_lvl() and once everything is in place, dump_stack() will require the log_level as well.

This looks good to me FWIW.

Quoted 15 lines

I have a draft patch for every architecture but for this patchset I'm only including x86 to get some feedback while I try to get a cross compiler working for each one of them (which is being harder than I thought).

Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Greg Thelen <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc David Rientjes <[email protected]>
Signature · 1 line
Aristeu
Signature · 8 lines
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
maintainer
#9 lore raw
Quoted 11 lines · On Mon, 9 Nov 2015 17:21:25 +0100 Michal Hocko <[email protected]> wrote:
Quoted 9 lines

This patchset introduces two new functions:
dump_stack_lvl(char *log_lvl)
show_stack_lvl(struct task_struct *task, unsigned long *sp, char *log_lvl)

and both can be reimplemented by each architecture but only the second is expected. The idea is to initially implement show_stack_lvl() in all architectures then simply have show_stack() to require log_lvl as parameter. While that happens, dump_stack() uses can be changed to dump_stack_lvl() and once everything is in place, dump_stack() will require the log_level as well.

This looks good to me FWIW.

Seems reasonable to me as well and yes, there will be extra fill-in work to do.

The "lvl" thing stands out - kernel code doesn't do this arbitrary vowelicide to make identifiers shorter. s/lvl/level/g?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#10 lore raw
Quoted 2 lines · Andrew Morton

Seems reasonable to me as well and yes, there will be extra fill-in work to do.

I have some of the archs already converted, will wait until this initial patchset is in to submit.

Quoted 2 lines

The "lvl" thing stands out - kernel code doesn't do this arbitrary vowelicide to make identifiers shorter. s/lvl/level/g?

There are show_regs_log_lvl(), show_trace_log_lvl(), show_stack_log_lvl() (avr32, x86) and I just wanted to keep the naming consistent. If you're strong about this I can change it and resubmit.

Signature · 7 lines
Aristeu

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>