Discussion:
[PATCH] mips: add arch_trigger_all_cpu_backtrace() function
Eunbong Song
2014-10-22 06:39:57 UTC
Permalink
Currently, arch_trigger_all_cpu_backtrace() is defined in only x86 and sparc which has nmi interrupt.
But in case of softlockup not a hardlockup, it could be possible to dump backtrace of all cpus. and this could be helpful for debugging.

for example, if system has 2 cpus.

CPU 0 CPU 1
acquire read_lock()

try to do write_lock()

,,,
missing read_unlock()

In this case, softlockup will occur becasuse CPU 0 does not call read_unlock().
And dump_stack() print only backtrace for "CPU 0". If CPU1's backtrace is printed it's very helpful.

This patch adds arch_trigger_all_cpu_backtrace() for mips architecture.

Maybe someone make better patch than this. I just suggest the idea.
---
arch/mips/include/asm/irq.h | 3 +++
arch/mips/kernel/process.c | 18 ++++++++++++++++++
2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
index 39f07ae..5a4e1bb 100644
--- a/arch/mips/include/asm/irq.h
+++ b/arch/mips/include/asm/irq.h
@@ -48,4 +48,7 @@ extern int cp0_compare_irq;
extern int cp0_compare_irq_shift;
extern int cp0_perfcount_irq;

+void arch_trigger_all_cpu_backtrace(bool);
+#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
+
#endif /* _ASM_IRQ_H */
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 636b074..9f51d3d 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -42,6 +42,7 @@
#include <asm/isadep.h>
#include <asm/inst.h>
#include <asm/stacktrace.h>
+#include <asm/irq_regs.h>

#ifdef CONFIG_HOTPLUG_CPU
void arch_cpu_idle_dead(void)
@@ -532,3 +533,20 @@ unsigned long arch_align_stack(unsigned long sp)

return sp & ALMASK;
}
+
+static void arch_dump_stack(void *info)
+{
+ struct pt_regs *regs;
+
+ regs = get_irq_regs();
+
+ if(regs)
+ show_regs(regs);
+
+ dump_stack();
+}
+
+void arch_trigger_all_cpu_backtrace(bool include_self)
+{
+ smp_ca
John Crispin
2014-10-22 06:47:04 UTC
Permalink
Hi Eubong,

one small question inline ...
Post by Eunbong Song
Currently, arch_trigger_all_cpu_backtrace() is defined in only x86
and sparc which has nmi interrupt. But in case of softlockup not a
hardlockup, it could be possible to dump backtrace of all cpus. and
this could be helpful for debugging.
for example, if system has 2 cpus.
CPU 0 CPU 1 acquire read_lock()
try to do write_lock()
,,, missing read_unlock()
In this case, softlockup will occur becasuse CPU 0 does not call
read_unlock(). And dump_stack() print only backtrace for "CPU 0".
If CPU1's backtrace is printed it's very helpful.
This patch adds arch_trigger_all_cpu_backtrace() for mips
architecture.
Maybe someone make better patch than this. I just suggest the
idea. --- arch/mips/include/asm/irq.h | 3 +++
arch/mips/kernel/process.c | 18 ++++++++++++++++++ 2 files
changed, 21 insertions(+), 0 deletions(-)
diff --git a/arch/mips/include/asm/irq.h
b/arch/mips/include/asm/irq.h index 39f07ae..5a4e1bb 100644 ---
cp0_compare_irq_shift; extern int cp0_perfcount_irq;
+void arch_trigger_all_cpu_backtrace(bool); +#define
arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
What is the purpose of this define ? is this maybe a leftover from
some regex/cleanups ?

John
Post by Eunbong Song
+ #endif /* _ASM_IRQ_H */ diff --git a/arch/mips/kernel/process.c
b/arch/mips/kernel/process.c index 636b074..9f51d3d 100644 ---
#include <asm/stacktrace.h> +#include <asm/irq_regs.h>
return sp & ALMASK; } + +static void arch_dump_stack(void *info)
+{ + struct pt_regs *regs; + + regs = get_irq_regs(); + + if(regs)
+ show_regs(regs); + + dump_stack(); +} + +void
arch_trigger_all_cpu_backtrace(bool include_self) +{ +
smp_call_function(arch_dump_stack, NULL, 1); +}
Eunbong Song
2014-10-22 06:54:20 UTC
Permalink
Post by John Crispin
Hi Eubong,
one small question inline ...
Post by Eunbong Song
+void arch_trigger_all_cpu_backtrace(bool); +#define
arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
What is the purpose of this define ? is this maybe a leftover from
some regex/cleanups ?
Hi John.
Actually, I just follow the same function of sparc architecture.
You can find this in arch/sparc/include/asm/irq_64.h as below

void arch_trigger_all_cpu_backtrace(bool);
#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace

I guess this is used for conditional compile.
See below.
include/linux/nmi.h
#ifdef arch_trigger_all_cpu_backtrace
static inline bool trigger_all_cpu_backtrace(void)
{
arch_trigger_all_cpu_backtrace(true);

return true;
}
static inline bool trigger_allbutself_cpu_backtrace(void)
{
arch_trigger_all_cpu_backtrace(false);
return true;
}
#else
static inline bool trigger_all_cpu_backtrace(void)
{
return false;
}
static inline bool trigger_allbutself_cpu_backtrace(void)
{
return f
John Crispin
2014-10-22 07:11:39 UTC
Permalink
Post by Eunbong Song
Post by John Crispin
Hi Eubong,
one small question inline ...
Post by Eunbong Song
+void arch_trigger_all_cpu_backtrace(bool); +#define
arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
What is the purpose of this define ? is this maybe a leftover from
some regex/cleanups ?
Hi John.
Actually, I just follow the same function of sparc architecture.
You can find this in arch/sparc/include/asm/irq_64.h as below
void arch_trigger_all_cpu_backtrace(bool);
#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
I guess this is used for conditional compile.
See below.
include/linux/nmi.h
#ifdef arch_trigger_all_cpu_backtrace
static inline bool trigger_all_cpu_backtrace(void)
{
arch_trigger_all_cpu_backtrace(true);
return true;
}
static inline bool trigger_allbutself_cpu_backtrace(void)
{
arch_trigger_all_cpu_backtrace(false);
return true;
}
#else
static inline bool trigger_all_cpu_backtrace(void)
{
return false;
}
static inline bool trigger_allbutself_cpu_backtrace(void)
{
return false;
}
#endif
Thanks.
Post by John Crispin
John
i don't see how this is required for conditional compiles. the code
define a->a which is bogus i think.

John
James Hogan
2014-10-22 22:29:36 UTC
Permalink
Hi John,
Post by John Crispin
Post by Eunbong Song
Post by John Crispin
Post by Eunbong Song
+void arch_trigger_all_cpu_backtrace(bool); +#define
arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
What is the purpose of this define ? is this maybe a leftover from
some regex/cleanups ?
Hi John.
Actually, I just follow the same function of sparc architecture.
You can find this in arch/sparc/include/asm/irq_64.h as below
void arch_trigger_all_cpu_backtrace(bool);
#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
I guess this is used for conditional compile.
See below.
include/linux/nmi.h
#ifdef arch_trigger_all_cpu_backtrace
static inline bool trigger_all_cpu_backtrace(void)
{
arch_trigger_all_cpu_backtrace(true);
return true;
}
static inline bool trigger_allbutself_cpu_backtrace(void)
{
arch_trigger_all_cpu_backtrace(false);
return true;
}
#else
static inline bool trigger_all_cpu_backtrace(void)
{
return false;
}
static inline bool trigger_allbutself_cpu_backtrace(void)
{
return false;
}
#endif
Thanks.
Post by John Crispin
John
i don't see how this is required for conditional compiles. the code
define a->a which is bogus i think.
It's a pretty common pattern in the asm headers, in order to allow
generic code to use the preprocessor to see whether it was defined or
not.

Cheers
James
Ralf Baechle
2014-10-22 16:16:38 UTC
Permalink
Post by Eunbong Song
+ if(regs)
^^^

There should be a blank between if and opening parenthesis.

Ralf
James Hogan
2014-10-22 22:22:16 UTC
Permalink
Post by Eunbong Song
This patch adds arch_trigger_all_cpu_backtrace() for mips architecture.
Don't forget your Signed-off-by
Post by Eunbong Song
+static void arch_dump_stack(void *info)
+{
+ struct pt_regs *regs;
+
+ regs = get_irq_regs();
+
+ if(regs)
+ show_regs(regs);
+
+ dump_stack();
+}
+
+void arch_trigger_all_cpu_backtrace(bool include_self)
+{
+ smp_call_function(arch_dump_stack, NULL, 1);
should this call arch_dump_stack directly too if include_self?

Cheers
James
Eunbong Song
2014-10-23 00:29:05 UTC
Permalink
Post by James Hogan
Post by Eunbong Song
This patch adds arch_trigger_all_cpu_backtrace() for mips architecture.
Don't forget your Signed-off-by
I'm sorry fot this.
Post by James Hogan
Post by Eunbong Song
+static void arch_dump_stack(void *info)
+{
+ struct pt_regs *regs;
+
+ regs = get_irq_regs();
+
+ if(regs)
+ show_regs(regs);
+
+ dump_stack();
+}
+
+void arch_trigger_all_cpu_backtrace(bool include_self)
+{
+ smp_call_function(arch_dump_stack, NULL, 1);
should this call arch_dump_stack directly too if include_self?
Currently, in case of mips there is no case include_self is true, so this is not a problem.
arch_trigger_all_cpu_backtrace can only be called from trigger_allbutself_cpu_backtrace() in kernel/watchdog.c.
But as you said, if the case will be added, we should conside

Loading...