From: Anton Blanchard <hidden> Date: 2014-09-17 07:07:06
We added -mno-sched-epilog in commit 7563dc645853 (powerpc:
Work around gcc's -fno-omit-frame-pointer bug).
We shouldn't apply -fno-omit-frame-pointer on powerpc any more (it's
protected by CONFIG_FRAME_POINTER and CONFIG_SCHED_OMIT_FRAME_POINTER).
It's also an undocumented gcc option, so lets remove it.
Signed-off-by: Anton Blanchard <redacted>
---
arch/powerpc/Makefile | 5 -----
arch/powerpc/kernel/Makefile | 12 ++++++------
arch/powerpc/platforms/powermac/Makefile | 2 +-
3 files changed, 7 insertions(+), 12 deletions(-)
@@ -198,11 +198,6 @@ ifeq ($(CONFIG_6xx),y)KBUILD_CFLAGS+=-mcpu=powerpcendif-# Work around a gcc code-gen bug with -fno-omit-frame-pointer.-ifeq ($(CONFIG_FUNCTION_TRACER),y)-KBUILD_CFLAGS+=-mno-sched-epilog-endif-cpu-as-$(CONFIG_4xx)+=-Wa,-m405cpu-as-$(CONFIG_ALTIVEC)+=-Wa,-maltiveccpu-as-$(CONFIG_E200)+=-Wa,-me200
@@ -17,14 +17,14 @@ endififdef CONFIG_FUNCTION_TRACER# Do not trace early boot code-CFLAGS_REMOVE_cputable.o=-pg-mno-sched-epilog-CFLAGS_REMOVE_prom_init.o=-pg-mno-sched-epilog-CFLAGS_REMOVE_btext.o=-pg-mno-sched-epilog-CFLAGS_REMOVE_prom.o=-pg-mno-sched-epilog+CFLAGS_REMOVE_cputable.o=-pg+CFLAGS_REMOVE_prom_init.o=-pg+CFLAGS_REMOVE_btext.o=-pg+CFLAGS_REMOVE_prom.o=-pg# do not trace tracer code-CFLAGS_REMOVE_ftrace.o=-pg-mno-sched-epilog+CFLAGS_REMOVE_ftrace.o=-pg# timers used by tracing-CFLAGS_REMOVE_time.o=-pg-mno-sched-epilog+CFLAGS_REMOVE_time.o=-pgendifobj-y:=cputable.optrace.osyscalls.o\
@@ -2,7 +2,7 @@ CFLAGS_bootx_init.o += -fPICifdef CONFIG_FUNCTION_TRACER# Do not trace early boot code-CFLAGS_REMOVE_bootx_init.o=-pg-mno-sched-epilog+CFLAGS_REMOVE_bootx_init.o=-pgendifobj-y+=pic.osetup.otime.ofeature.opci.o\
From: Anton Blanchard <hidden> Date: 2014-09-17 07:07:07
mod_return_to_handler is the same as return_to_handler, except
it handles the change of the TOC (r2). Add this into
return_to_handler and remove mod_return_to_handler.
Signed-off-by: Anton Blanchard <redacted>
---
arch/powerpc/kernel/entry_64.S | 24 +-----------------------
arch/powerpc/kernel/ftrace.c | 14 ++------------
arch/powerpc/kernel/process.c | 9 +--------
3 files changed, 4 insertions(+), 43 deletions(-)
@@ -510,10 +510,6 @@ int ftrace_disable_ftrace_graph_caller(void)}#endif /* CONFIG_DYNAMIC_FTRACE */-#ifdef CONFIG_PPC64-externvoidmod_return_to_handler(void);-#endif-/**Hookthereturnaddressandpushitinthestackofreturnaddrs*incurrentthreadinfo.
@@ -523,7 +519,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)unsignedlongold;intfaulted;structftrace_graph_enttrace;-unsignedlongreturn_hooker=(unsignedlong)&return_to_handler;+unsignedlongreturn_hooker;if(unlikely(ftrace_graph_is_dead()))return;
@@ -531,13 +527,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)if(unlikely(atomic_read(¤t->tracing_graph_pause)))return;-#ifdef CONFIG_PPC64-/* non core kernel code needs to save and restore the TOC */-if(REGION_ID(self_addr)!=KERNEL_REGION_ID)-return_hooker=(unsignedlong)&mod_return_to_handler;-#endif--return_hooker=ppc_function_entry((void*)return_hooker);+return_hooker=ppc_function_entry(return_to_handler);/**Protectagainstfault,evenifitshouldn't
From: Anton Blanchard <hidden> Date: 2014-09-17 07:07:09
Instead of passing in the stack address of the link register
to be modified, just pass in the old value and return the
new value and rely on ftrace_graph_caller to do the
modification.
This removes the exception handling around the stack update -
it isn't needed and we weren't consistent about it. Later on
we would do an unprotected modification:
if (!ftrace_graph_entry(&trace)) {
*parent = old;
Signed-off-by: Anton Blanchard <redacted>
---
arch/powerpc/kernel/entry_32.S | 10 +++++--
arch/powerpc/kernel/entry_64.S | 11 ++++++--
arch/powerpc/kernel/ftrace.c | 59 ++++++++++--------------------------------
3 files changed, 30 insertions(+), 50 deletions(-)
@@ -512,67 +512,34 @@ int ftrace_disable_ftrace_graph_caller(void)/**Hookthereturnaddressandpushitinthestackofreturnaddrs-*incurrentthreadinfo.+*incurrentthreadinfo.Returntheaddresswewanttodivertto.*/-voidprepare_ftrace_return(unsignedlong*parent,unsignedlongself_addr)+unsignedlongprepare_ftrace_return(unsignedlongparent,unsignedlongip){-unsignedlongold;-intfaulted;structftrace_graph_enttrace;unsignedlongreturn_hooker;if(unlikely(ftrace_graph_is_dead()))-return;+gotoout;if(unlikely(atomic_read(¤t->tracing_graph_pause)))-return;+gotoout;return_hooker=ppc_function_entry(return_to_handler);-/*-*Protectagainstfault,evenifitshouldn't-*happen.Thistoolistoomuchintrusiveto-*ignoresuchaprotection.-*/-asmvolatile(-"1: "PPC_LL"%[old], 0(%[parent])\n"-"2: "PPC_STL"%[return_hooker], 0(%[parent])\n"-" li %[faulted], 0\n"-"3:\n"--".section .fixup, \"ax\"\n"-"4: li %[faulted], 1\n"-" b 3b\n"-".previous\n"--".section __ex_table,\"a\"\n"-PPC_LONG_ALIGN"\n"-PPC_LONG"1b,4b\n"-PPC_LONG"2b,4b\n"-".previous"--:[old]"=&r"(old),[faulted]"=r"(faulted)-:[parent]"r"(parent),[return_hooker]"r"(return_hooker)-:"memory"-);--if(unlikely(faulted)){-ftrace_graph_stop();-WARN_ON(1);-return;-}--trace.func=self_addr;+trace.func=ip;trace.depth=current->curr_ret_stack+1;/* Only trace if the calling function expects to */-if(!ftrace_graph_entry(&trace)){-*parent=old;-return;-}+if(!ftrace_graph_entry(&trace))+gotoout;++if(ftrace_push_return_trace(parent,ip,&trace.depth,0)==-EBUSY)+gotoout;-if(ftrace_push_return_trace(old,self_addr,&trace.depth,0)==-EBUSY)-*parent=old;+parent=return_hooker;+out:+returnparent;}#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
From: Steven Rostedt <rostedt@goodmis.org> Date: 2014-09-23 23:18:50
I'm running my ftrace tests on my PAsemi box with your patches and
things are not going so well.
Just this patch alone causes my first stress test to lock up, and
things don't go so well after that.
INFO: rcu_sched detected stalls on CPUs/tasks: {} (detected by 1, t=5253 jiffies, g=3603, c=3602, q=15)
INFO: Stall ended before state dump start
INFO: rcu_sched detected stalls on CPUs/tasks: {} (detected by 1, t=21008 jiffies, g=3603, c=3602, q=15)
INFO: Stall ended before state dump start
That's repeated and the system is basically useless.
-- Steve
On Wed, 17 Sep 2014 17:07:02 +1000
Anton Blanchard [off-list ref] wrote:
quoted hunk
We added -mno-sched-epilog in commit 7563dc645853 (powerpc:
Work around gcc's -fno-omit-frame-pointer bug).
We shouldn't apply -fno-omit-frame-pointer on powerpc any more (it's
protected by CONFIG_FRAME_POINTER and CONFIG_SCHED_OMIT_FRAME_POINTER).
It's also an undocumented gcc option, so lets remove it.
Signed-off-by: Anton Blanchard <redacted>
---
arch/powerpc/Makefile | 5 -----
arch/powerpc/kernel/Makefile | 12 ++++++------
arch/powerpc/platforms/powermac/Makefile | 2 +-
3 files changed, 7 insertions(+), 12 deletions(-)
@@ -198,11 +198,6 @@ ifeq ($(CONFIG_6xx),y)KBUILD_CFLAGS+=-mcpu=powerpcendif-# Work around a gcc code-gen bug with -fno-omit-frame-pointer.-ifeq ($(CONFIG_FUNCTION_TRACER),y)-KBUILD_CFLAGS+=-mno-sched-epilog-endif-cpu-as-$(CONFIG_4xx)+=-Wa,-m405cpu-as-$(CONFIG_ALTIVEC)+=-Wa,-maltiveccpu-as-$(CONFIG_E200)+=-Wa,-me200
@@ -17,14 +17,14 @@ endififdef CONFIG_FUNCTION_TRACER# Do not trace early boot code-CFLAGS_REMOVE_cputable.o=-pg-mno-sched-epilog-CFLAGS_REMOVE_prom_init.o=-pg-mno-sched-epilog-CFLAGS_REMOVE_btext.o=-pg-mno-sched-epilog-CFLAGS_REMOVE_prom.o=-pg-mno-sched-epilog+CFLAGS_REMOVE_cputable.o=-pg+CFLAGS_REMOVE_prom_init.o=-pg+CFLAGS_REMOVE_btext.o=-pg+CFLAGS_REMOVE_prom.o=-pg# do not trace tracer code-CFLAGS_REMOVE_ftrace.o=-pg-mno-sched-epilog+CFLAGS_REMOVE_ftrace.o=-pg# timers used by tracing-CFLAGS_REMOVE_time.o=-pg-mno-sched-epilog+CFLAGS_REMOVE_time.o=-pgendifobj-y:=cputable.optrace.osyscalls.o\
@@ -2,7 +2,7 @@ CFLAGS_bootx_init.o += -fPICifdef CONFIG_FUNCTION_TRACER# Do not trace early boot code-CFLAGS_REMOVE_bootx_init.o=-pg-mno-sched-epilog+CFLAGS_REMOVE_bootx_init.o=-pgendifobj-y+=pic.osetup.otime.ofeature.opci.o\
From: Steven Rostedt <rostedt@goodmis.org> Date: 2014-09-23 23:20:23
On Wed, 17 Sep 2014 17:07:03 +1000
Anton Blanchard [off-list ref] wrote:
mod_return_to_handler is the same as return_to_handler, except
it handles the change of the TOC (r2). Add this into
return_to_handler and remove mod_return_to_handler.
Adding this patch actually gave me some more output. Funny that?
electra login: INFO: rcu_sched self-detected stall on CPU { 1} (t=5250 jiffies g=3579 c=3578 q=7)
Task dump for CPU 1:
trace-cmd R running task 0 3553 3550 0x00008014
Call Trace:
[c0000000054a6ce0] [c000000000012b34] .show_stack+0x104/0x260 (unreliable)
[c0000000054a6dc0] [c0000000000c2270] .sched_show_task+0xd0/0x150
[c0000000054a6e40] [c0000000000eedb0] .rcu_dump_cpu_stacks+0xe0/0x150
[c0000000054a6ee0] [c0000000000f2a48] .rcu_check_callbacks+0x4f8/0x8d0
[c0000000054a7020] [c0000000000f8118] .update_process_times+0x48/0xa0
[c0000000054a70b0] [c00000000010cfe8] .tick_sched_timer+0x88/0xd0
[c0000000054a7150] [c0000000000f8b1c] .__run_hrtimer+0xcc/0x2c0
[c0000000054a7200] [c0000000000f9a98] .hrtimer_interrupt+0x158/0x330
[c0000000054a7310] [c00000000001a6b8] .__timer_interrupt+0xa8/0x280
[c0000000054a73c0] [c00000000001a920] .timer_interrupt+0x90/0x100
[c0000000054a7440] [c000000000002260] decrementer_common+0x160/0x180
--- interrupt: 901 at .trace_buffer_lock_reserve+0x2c/0x90
LR = .trace_function+0x54/0xe0
[c0000000054a77c0] [c0000000001449cc] .function_trace_call+0x7c/0x120
[c0000000054a7840] [c00000000012d750] .ftrace_ops_no_ops+0xf0/0x170
[c0000000054a78e0] [c000000000009d8c] ftrace_call+0x4/0x8
[c0000000054a7950] [c00000000072e128] .mutex_unlock+0x18/0x70
[c0000000054a79d0] [c000000000137534] .tracing_buffers_splice_read+0x424/0x4c0
[c0000000054a7c80] [c00000000021bfe8] .do_splice_to+0xa8/0xe0
[c0000000054a7d20] [c00000000021eae4] .SyS_splice+0x694/0x6b0
[c0000000054a7e30] [c000000000009224] syscall_exit+0x0/0x98
Note, the stress test is basically this:
perf record -o perf-test.dat -a -- trace-cmd record -e all -p function hackbench 2
It actually dies as it finishes the hackbench run and starts stopping
the tracing.
-- Steve
From: Steven Rostedt <rostedt@goodmis.org> Date: 2014-09-23 23:46:07
On Wed, 17 Sep 2014 17:07:04 +1000
Anton Blanchard [off-list ref] wrote:
Instead of passing in the stack address of the link register
to be modified, just pass in the old value and return the
new value and rely on ftrace_graph_caller to do the
modification.
This removes the exception handling around the stack update -
it isn't needed and we weren't consistent about it. Later on
we would do an unprotected modification:
if (!ftrace_graph_entry(&trace)) {
*parent = old;
First I'll say this is something I've been wanting to do with x86 for
some time. That said...
With this patch, things move much further in my tests. The stress test
passes again. But then it fails on my stack trace test. Which is
because this is what I have in the stack traces:
sleep-3557 [000] d... 100.206808: <stack trace>
=> 0
=> 0
=> 0
=> 0
=> 0
=> 0
=> 0
=> 0
Where without the patches I have something like this:
sleep-3641 [001] d... 304.023550: <stack trace>
=> .ftrace_raw_event_sched_switch
=> .__schedule
=> .schedule
=> .do_nanosleep
=> .hrtimer_nanosleep
=> .compat_SyS_nanosleep
=> syscall_exit
=> 0
This could be broken from the earlier patches, I haven't run just this
test. I probably should on them.
I've attached the test.
-- Steve
From: Anton Blanchard <hidden> Date: 2014-09-24 02:22:03
Hi Steve,
quoted
This could be broken from the earlier patches, I haven't run just
this test. I probably should on them.
I went back and tested, and it breaks under the first patch.
Thanks for testing. It looks like some toolchains have issues
other than the -fno-no-omit-frame-pointer one, and -mno-sched-epilog
works around it.
I'll drop that patch and respin.
Anton
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2014-09-24 02:24:42
On Wed, 2014-09-24 at 12:22 +1000, Anton Blanchard wrote:
Hi Steve,
quoted
quoted
This could be broken from the earlier patches, I haven't run just
this test. I probably should on them.
I went back and tested, and it breaks under the first patch.
Thanks for testing. It looks like some toolchains have issues
other than the -fno-no-omit-frame-pointer one, and -mno-sched-epilog
works around it.
I'll drop that patch and respin.
Or maybe do a toolchain check / or enable it in LE ?
Ben.
From: Anton Blanchard <hidden> Date: 2014-09-24 02:33:08
Hi Ben,
quoted
I'll drop that patch and respin.
Or maybe do a toolchain check / or enable it in LE ?
We are scratching our heads trying to remember details of the issue
right now. In retrospect we should have linked the gcc bugzilla or
gcc commit details in the kernel commit message :)
Steve: what gcc version are you building with?
Anton
From: Steven Rostedt <rostedt@goodmis.org> Date: 2014-09-24 02:44:51
On Wed, 24 Sep 2014 12:33:07 +1000
Anton Blanchard [off-list ref] wrote:
Hi Ben,
quoted
quoted
I'll drop that patch and respin.
Or maybe do a toolchain check / or enable it in LE ?
We are scratching our heads trying to remember details of the issue
right now. In retrospect we should have linked the gcc bugzilla or
gcc commit details in the kernel commit message :)
Steve: what gcc version are you building with?
On Wed, Sep 24, 2014 at 12:33:07PM +1000, Anton Blanchard wrote:
We are scratching our heads trying to remember details of the issue
right now. In retrospect we should have linked the gcc bugzilla or
gcc commit details in the kernel commit message :)
There have been many GCC bugs in this area.
30282 (for 32-bit)
44199 (for 64-bit)
52828 (for everything, and this one should finally handle things for good)
Also a bunch of duplicates, and I'm sure I've missed some more.
The original issue as far as I remember: when using a frame pointer, GCC
would sometimes schedule the epilogue to do the stack adjust before
restoring all regs from the stack. Then an interrupt comes in, those
saved regs are clobbered, kaboom. We cannot disable the frame pointer
because -pg forces it (although PowerPC does not need it). The
-mno-sched-epilog flag is a workaround: the epilogue (and prologue) will
not be reordered by instruction scheduling. Slow code is better than
blowing up fast ;-)
Segher
From: Anton Blanchard <hidden> Date: 2014-10-28 04:55:50
Hi Segher,
On Wed, Sep 24, 2014 at 12:33:07PM +1000, Anton Blanchard wrote:
quoted
We are scratching our heads trying to remember details of the issue
right now. In retrospect we should have linked the gcc bugzilla or
gcc commit details in the kernel commit message :)
There have been many GCC bugs in this area.
30282 (for 32-bit)
44199 (for 64-bit)
52828 (for everything, and this one should finally handle things for
good) Also a bunch of duplicates, and I'm sure I've missed some more.
The original issue as far as I remember: when using a frame pointer,
GCC would sometimes schedule the epilogue to do the stack adjust
before restoring all regs from the stack. Then an interrupt comes
in, those saved regs are clobbered, kaboom. We cannot disable the
frame pointer because -pg forces it (although PowerPC does not need
it). The -mno-sched-epilog flag is a workaround: the epilogue (and
prologue) will not be reordered by instruction scheduling. Slow code
is better than blowing up fast ;-)
Thanks for explaining it! It does look like the last issue wasn't
fixed until gcc 4.8. We'll drop that patch.
Anton