Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: Fix kernel hang under FUNCTION_GRAPH_TRACER and PREEMPT_TRACER

When update the latest mainline kernel with the following three configs,
the kernel hangs during startup:

(1) CONFIG_FUNCTION_GRAPH_TRACER=y
(2) CONFIG_PREEMPT_TRACER=y
(3) CONFIG_FTRACE_STARTUP_TEST=y

When update the latest mainline kernel with the above two configs (1)
and (2), the kernel starts normally, but it still hangs when execute
the following command:

echo "function_graph" > /sys/kernel/debug/tracing/current_tracer

Without CONFIG_PREEMPT_TRACER=y, the above two kinds of kernel hangs
disappeared, so it seems that CONFIG_PREEMPT_TRACER has some influences
with function_graph tracer at the first glance.

I use ejtag to find out the epc address is related with preempt_enable()
in the file arch/mips/lib/mips-atomic.c, because function tracing can
trace the preempt_{enable,disable} calls that are traced, replace them
with preempt_{enable,disable}_notrace to prevent function tracing from
going into an infinite loop, and then it can fix the kernel hang issue.

By the way, it seems that this commit is a complement and improvement of
commit f93a1a00f2bd ("MIPS: Fix crash that occurs when function tracing
is enabled").

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>

authored by

Tiezhu Yang and committed by
Thomas Bogendoerfer
78cf0eb9 fef532ea

+6 -6
+6 -6
arch/mips/lib/mips-atomic.c
··· 37 37 */ 38 38 notrace void arch_local_irq_disable(void) 39 39 { 40 - preempt_disable(); 40 + preempt_disable_notrace(); 41 41 42 42 __asm__ __volatile__( 43 43 " .set push \n" ··· 53 53 : /* no inputs */ 54 54 : "memory"); 55 55 56 - preempt_enable(); 56 + preempt_enable_notrace(); 57 57 } 58 58 EXPORT_SYMBOL(arch_local_irq_disable); 59 59 ··· 61 61 { 62 62 unsigned long flags; 63 63 64 - preempt_disable(); 64 + preempt_disable_notrace(); 65 65 66 66 __asm__ __volatile__( 67 67 " .set push \n" ··· 78 78 : /* no inputs */ 79 79 : "memory"); 80 80 81 - preempt_enable(); 81 + preempt_enable_notrace(); 82 82 83 83 return flags; 84 84 } ··· 88 88 { 89 89 unsigned long __tmp1; 90 90 91 - preempt_disable(); 91 + preempt_disable_notrace(); 92 92 93 93 __asm__ __volatile__( 94 94 " .set push \n" ··· 106 106 : "0" (flags) 107 107 : "memory"); 108 108 109 - preempt_enable(); 109 + preempt_enable_notrace(); 110 110 } 111 111 EXPORT_SYMBOL(arch_local_irq_restore); 112 112