Skip to contentSkip to conversation

Add the end-of-trace marker and the module list to WARN_ON()

PATCH In review Arjan van de Ven 3 participants 7 messages Jan 3, 2008 – Jan 4, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 2/2 Add the end-of-trace marker and the module list to WARN_ON()

Subject: Add the end-of-trace marker and the module list to WARN_ON()
From: Arjan van de Ven <[email protected]>
CC: Ingo Molnar <[email protected]>
CC: Andrew Morton <[email protected]>
CC: Olof Johansson <[email protected]>

Unlike oopses, WARN_ON() currently doesn't print the loaded modules list. This makes it harder to take action on certain bug reports. For example, recently there were a set of WARN_ON()s reported in the mac80211 stack, which were just signaling a driver bug. It takes then anther round trip to the bug reporter (if he responds at all) to find out which driver is at fault.

Another issue is that, unlike oopses, WARN_ON() doesn't currently printk the helpful "cut here" line, nor the "end of trace" marker. Now that WARN_ON() is out of line, the size increase due to this is minimal and it's worth adding.

---
 kernel/panic.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
kernel/panic.c +12 -4
Index: linux-2.6.24-rc6/kernel/panic.c
===================================================================
@@ -281,6 +281,13 @@ static int init_oops_id(void)
 }
 late_initcall(init_oops_id);
 
+static void print_oops_end_marker(void)
+{
+	init_oops_id();
+	printk(KERN_WARNING "---[ end trace %016llx ]---\n",
+		(unsigned long long)oops_id);
+}
+
 /*
  * Called when the architecture exits its oops handler, after printing
  * everything.
@@ -288,9 +295,7 @@ late_initcall(init_oops_id);
 void oops_exit(void)
 {
 	do_oops_enter_exit();
-	init_oops_id();
-	printk(KERN_WARNING "---[ end trace %016llx ]---\n",
-		(unsigned long long)oops_id);
+	print_oops_end_marker();
 }
 
 
@@ -298,11 +303,14 @@ void warn_on_slowpath(const char *file,
 {
 	char function[KSYM_SYMBOL_LEN];
 	unsigned long caller = (unsigned long) __builtin_return_address(0);
-
 	sprint_symbol(function, caller);
+
+	printk(KERN_WARNING "------------[ cut here ]------------\n");
 	printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file,
 		line, function);
+	print_modules();
 	dump_stack();
+	print_oops_end_marker();
 }
 EXPORT_SYMBOL(warn_on_slowpath);
 

Subject: Add the end-of-trace marker and the module list to WARN_ON()
From: Arjan van de Ven <[email protected]>
CC: Ingo Molnar <[email protected]>
CC: Andrew Morton <[email protected]>
CC: Olof Johansson <[email protected]>

Unlike oopses, WARN_ON() currently does't print the loaded modules list. This makes it harder to take action on certain bug reports. For example, recently there were a set of WARN_ON()s reported in the mac80211 stack, which were just signalling a driver bug. It takes then anther round trip to the bug reporter (if he responds at all) to find out which driver is at fault.

Another issue is that, unlike oopses, WARN_ON() doesn't currently printk the helpful "cut here" line, nor the "end of trace" marker. Now that WARN_ON() is out of line, the size increase due to this is minimal and it's worth adding.

---
 kernel/panic.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
kernel/panic.c +12 -4
Index: linux-2.6.24-rc6/kernel/panic.c
===================================================================
@@ -281,6 +281,13 @@ static int init_oops_id(void)
 }
 late_initcall(init_oops_id);
 
+static void print_oops_end_marker(void)
+{
+	init_oops_id();
+	printk(KERN_WARNING "---[ end trace %016llx ]---\n",
+		(unsigned long long)oops_id);
+}
+
 /*
  * Called when the architecture exits its oops handler, after printing
  * everything.
@@ -288,9 +295,7 @@ late_initcall(init_oops_id);
 void oops_exit(void)
 {
 	do_oops_enter_exit();
-	init_oops_id();
-	printk(KERN_WARNING "---[ end trace %016llx ]---\n",
-		(unsigned long long)oops_id);
+	print_oops_end_marker();
 }
 
 
@@ -298,11 +303,14 @@ void warn_on_slowpath(const char *file, 
 {
 	char function[KSYM_SYMBOL_LEN];
 	unsigned long caller = (unsigned long) __builtin_return_address(0);
-
 	sprint_symbol(function, caller);
+
+	printk(KERN_WARNING "------------[ cut here ]------------\n");
 	printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file,
 		line, function);
+	print_modules();
 	dump_stack();
+	print_oops_end_marker();
 }
 EXPORT_SYMBOL(warn_on_slowpath);
 
#1 lore raw

kernel/panic.c void warn_on_slowpath(const char *file, · line 313

Quoted 6 lines · Arjan van de Ven
kernel/panic.c +3 -0
+	printk(KERN_WARNING "------------[ cut here ]------------\n");
 	printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file,
 		line, function);
+	print_modules();
 	dump_stack();
+	print_oops_end_marker();

another thing: could we also put the marker into dump_stack(), and attach the marker to the Call Trace line?

Ingo

#2 lore raw
Quoted 11 lines · Ingo Molnar

kernel/panic.c void warn_on_slowpath(const char *file, · line 313

Quoted 6 lines · Arjan van de Ven
kernel/panic.c +3 -0
+	printk(KERN_WARNING "------------[ cut here ]------------\n");
 	printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file,
 		line, function);
+	print_modules();
 	dump_stack();
+	print_oops_end_marker();

another thing: could we also put the marker into dump_stack(), and attach the marker to the Call Trace line?

I have a preliminary patch for that already but I'm not happy with it yet; I need to redo it properly. It's neither depending nor incremental to these 2 patches though..

#3 lore raw
Quoted 13 lines · Arjan van de Ven
Quoted 11 lines · Ingo Molnar

kernel/panic.c void warn_on_slowpath(const char *file, · line 313

Quoted 6 lines · Arjan van de Ven
kernel/panic.c +3 -0
+	printk(KERN_WARNING "------------[ cut here ]------------\n");
 	printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file,
 		line, function);
+	print_modules();
 	dump_stack();
+	print_oops_end_marker();

another thing: could we also put the marker into dump_stack(), and attach the marker to the Call Trace line?

Quoted 3 lines

I have a preliminary patch for that already but I'm not happy with it yet; I need to redo it properly. It's neither depending nor incremental to these 2 patches though..

yeah, it was a sidenote - it should be separate to these two patches.

Ingo

#4 lore raw
In reply to Arjan van de Ven

kernel/panic.c static int init_oops_id(void) · line 289

Quoted 12 lines · Arjan van de Ven

Another issue is that, unlike oopses, WARN_ON() doesn't currently printk the helpful "cut here" line, nor the "end of trace" marker. Now that WARN_ON() is out of line, the size increase due to this is minimal and it's worth adding.

kernel/panic.c +6 -0
+static void print_oops_end_marker(void)
+{
+	init_oops_id();
+	printk(KERN_WARNING "---[ end trace %016llx ]---\n",
+		(unsigned long long)oops_id);
+}

There is also lib/bug.c which prints the "cut here" line but not the "end of trace" line. Also it prints whatever it prints with a different printk level.
Quite a few architectures use lib/bug.c also for WARN_ONs. Maybe all the code should be in one place so it doesn't diverge all the time?

#5 lore raw
Quoted 6 lines · Heiko Carstens
Quoted 5 lines · Arjan van de Ven

Another issue is that, unlike oopses, WARN_ON() doesn't currently printk the helpful "cut here" line, nor the "end of trace" marker. Now that WARN_ON() is out of line, the size increase due to this is minimal and it's worth adding.

Quoted 9 lines

kernel/panic.c static int init_oops_id(void) · line 289

Quoted 6 lines
kernel/panic.c +6 -0
+static void print_oops_end_marker(void)
+{
+	init_oops_id();
+	printk(KERN_WARNING "---[ end trace %016llx ]---\n",
+		(unsigned long long)oops_id);
+}

There is also lib/bug.c which prints the "cut here" line but not the "end of trace" line.

it ends up printing the "end of trace" line as part of the oops_exit() call

Quoted 4 lines

Also it prints whatever it prints with a different printk level.

as it should.. WARN_ON()'s are warnings so get KERN_WARNING ;-)

Quoted 1 line

Quite a few architectures use lib/bug.c also for WARN_ONs.

is this still the case after Olof's patch?

Quoted 2 lines

Maybe all the code should be in one place so it doesn't diverge all the time?

it's actually ok as is.. the core tracing code lives in panic.c; lib/bug.c is just a few helpers for BUG().. for WARN_ON() there is a lot less to help

#6 lore raw
Quoted 16 lines · Arjan van de Ven
Quoted 6 lines · Heiko Carstens
Quoted 5 lines · Arjan van de Ven

Another issue is that, unlike oopses, WARN_ON() doesn't currently printk the helpful "cut here" line, nor the "end of trace" marker. Now that WARN_ON() is out of line, the size increase due to this is minimal and it's worth adding.

Quoted 8 lines

kernel/panic.c static int init_oops_id(void) · line 289

Quoted 6 lines
kernel/panic.c +6 -0
+static void print_oops_end_marker(void)
+{
+	init_oops_id();
+	printk(KERN_WARNING "---[ end trace %016llx ]---\n",
+		(unsigned long long)oops_id);
+}

There is also lib/bug.c which prints the "cut here" line but not the "end of trace" line.

Quoted 1 line

it ends up printing the "end of trace" line as part of the oops_exit() call

Not on architectures that implement WARN_ON() with the help of lib/bug.c and an invalid opcode. Your out of line helper function doesn't get called there.

Instead the exception handler calls report_bug() which in turn prints the warning message, then calls show_regs() and returns BUG_TRAP_TYPE_WARN.

Afterwards the instruction pointer is incremented and execution continues.

This is true for powerpc, avr32, sh, parisc and s390.

Your out of line changes don't have any effect on these architectures. Dunno.. maybe you are aware of this. Just wanted to make sure we aren't talking of totally different things.

Quoted 4 lines
Quoted 2 lines

Also it prints whatever it prints with a different printk level.

as it should.. WARN_ON()'s are warnings so get KERN_WARNING ;-)

Not on all architectures.. see above :)

Quoted 3 lines
Quoted 1 line

Quite a few architectures use lib/bug.c also for WARN_ONs.

is this still the case after Olof's patch?

Yes, of course. Also I like the WARN_ON() with exception semantics much more since it gives the ability to print the register contents etc. So you get much more debug informations.

Quoted 6 lines
Quoted 2 lines

Maybe all the code should be in one place so it doesn't diverge all the time?

it's actually ok as is.. the core tracing code lives in panic.c; lib/bug.c is just a few helpers
for BUG().. for WARN_ON() there is a lot less to help

Not really... lib/bug.c handles both if the architecture wants it. It just needs to set BUGFLAG_WARNING in the bug table entries for warnings.