diff mbox

[v8,4/8] ppc64 ftrace_with_regs configuration variables

Message ID 20160210174450.9C065692C8@newverein.lst.de (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Torsten Duwe Feb. 10, 2016, 4:25 p.m. UTC
* arch/powerpc/Makefile:
    - globally use -mprofile-kernel in case it's configured,
      available and bug-free.
  * arch/powerpc/gcc-mprofile-kernel-notrace.sh:
    - make sure -mprofile-kernel works and has none of the
      known bugs.
  * arch/powerpc/kernel/ftrace.c:
    - error out on compile with HAVE_DYNAMIC_FTRACE_WITH_REGS
      and a buggy compiler.
  * arch/powerpc/Kconfig / kernel/trace/Kconfig:
    - declare that ppc64le HAVE_MPROFILE_KERNEL and
      HAVE_DYNAMIC_FTRACE_WITH_REGS, and use it.

Signed-off-by: Torsten Duwe <duwe@suse.de>
---
 arch/powerpc/Kconfig                        |  2 ++
 arch/powerpc/Makefile                       | 17 +++++++++++++++
 arch/powerpc/gcc-mprofile-kernel-notrace.sh | 33 +++++++++++++++++++++++++++++
 arch/powerpc/kernel/ftrace.c                |  5 +++++
 kernel/trace/Kconfig                        |  5 +++++
 5 files changed, 62 insertions(+)
 create mode 100755 arch/powerpc/gcc-mprofile-kernel-notrace.sh

Comments

Balbir Singh Feb. 11, 2016, 7:48 a.m. UTC | #1
On Wed, 2016-02-10 at 17:25 +0100, Torsten Duwe wrote:

snip

> diff --git a/arch/powerpc/gcc-mprofile-kernel-notrace.sh b/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> new file mode 100755
> index 0000000..68d6482
> --- /dev/null
> +++ b/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> @@ -0,0 +1,33 @@
> +#!/bin/sh
> +# Test whether the compile option -mprofile-kernel
> +# generates profiling code ( = a call to mcount), and
> +# whether a function without any global references sets
> +# the TOC pointer properly at the beginning, and
> +# whether the "notrace" function attribute successfully
> +# suppresses the _mcount call.
> +
> +echo "int func() { return 0; }" | \
> +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> +    grep -q "mcount"
> +
> +trace_result=$?
> +
> +echo "int func() { return 0; }" | \
> +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> +    sed -n -e '/func:/,/bl _mcount/p' | grep -q TOC
> +
> +leaf_toc_result=$?
> +

leaf_toc_result failed for me with gcc 5. I'll try and grab gcc-6
and give the patches a spin

> +/bin/echo -e "#include \nnotrace int func() { return 0; }" | \
> +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> +    grep -q "mcount"
> +
> +notrace_result=$?
> +
> +if [ "$trace_result" -eq "0" -a \
> +	"$leaf_toc_result" -eq "0" -a \
> +	"$notrace_result" -eq "1" ]; then
> +	echo y
> +else
> +	echo n
> +fi
Kamalesh Babulal Feb. 11, 2016, 8:39 a.m. UTC | #2
* Balbir Singh <bsingharora@gmail.com> [2016-02-11 18:48:17]:

> On Wed, 2016-02-10 at 17:25 +0100, Torsten Duwe wrote:
> 
> snip
> 
> > diff --git a/arch/powerpc/gcc-mprofile-kernel-notrace.sh b/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> > new file mode 100755
> > index 0000000..68d6482
> > --- /dev/null
> > +++ b/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> > @@ -0,0 +1,33 @@
> > +#!/bin/sh
> > +# Test whether the compile option -mprofile-kernel
> > +# generates profiling code ( = a call to mcount), and
> > +# whether a function without any global references sets
> > +# the TOC pointer properly at the beginning, and
> > +# whether the "notrace" function attribute successfully
> > +# suppresses the _mcount call.
> > +
> > +echo "int func() { return 0; }" | \
> > +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> > +    grep -q "mcount"
> > +
> > +trace_result=$?
> > +
> > +echo "int func() { return 0; }" | \
> > +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> > +    sed -n -e '/func:/,/bl _mcount/p' | grep -q TOC
> > +
> > +leaf_toc_result=$?
> > +
> 
> leaf_toc_result failed for me with gcc 5. I'll try and grab gcc-6
> and give the patches a spin
> 

It fails for me to on ppc64le but pass over ppc64

# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/ppc64-redhat-linux/5.1.1/lto-wrapper
Target: ppc64-redhat-linux
[...]
gcc version 5.1.1 20150422 (Red Hat 5.1.1-1) (GCC)

# echo "int func() { return 0;  }" |     gcc -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null |     sed -n -e '/func:/,/bl _mcount/p'
func:
        .quad   .L.func,.TOC.@tocbase
        .previous
        .type   func, @function
.L.func:
        mflr 0
        std 0,16(1)
        bl _mcount

# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/powerpc64le-linux-gnu/5/lto-wrapper
Target: powerpc64le-linux-gnu
[...]
gcc version 5.3.1 20160205 (Ubuntu/IBM 5.3.1-8ubuntu2)

# echo "int func() { return 0;  }" |     gcc -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null |     sed -n -e '/func:/,/bl _mcount/p'
func:
        mflr 0
        std 0,16(1)
        bl _mcount


I will try it over gcc-6.

Thanks,
Kamalesh
Torsten Duwe Feb. 11, 2016, 8:42 a.m. UTC | #3
On Thu, Feb 11, 2016 at 06:48:17PM +1100, Balbir Singh wrote:
> On Wed, 2016-02-10 at 17:25 +0100, Torsten Duwe wrote:
> > +
> > +echo "int func() { return 0; }" | \
> > +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> > +    sed -n -e '/func:/,/bl _mcount/p' | grep -q TOC
> > +
> > +leaf_toc_result=$?
> > +
> 
> leaf_toc_result failed for me with gcc 5. I'll try and grab gcc-6
> and give the patches a spin

Don't bother. _All_ gccs are broken in that respect currently.
AFAIK Anton is working on this. You have to fake the test, like
static int a; return a++;

Gcc fails to set the TOC for profiled "leaf" functions, where it
thinks no global/static symbols are referenced.

	Torsten
Balbir Singh Feb. 11, 2016, 9:34 a.m. UTC | #4
On Thu, 2016-02-11 at 09:42 +0100, Torsten Duwe wrote:
> On Thu, Feb 11, 2016 at 06:48:17PM +1100, Balbir Singh wrote:
> > On Wed, 2016-02-10 at 17:25 +0100, Torsten Duwe wrote:
> > > +
> > > +echo "int func() { return 0; }" | \
> > > +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> > > +    sed -n -e '/func:/,/bl _mcount/p' | grep -q TOC
> > > +
> > > +leaf_toc_result=$?
> > > +
> > 
> > leaf_toc_result failed for me with gcc 5. I'll try and grab gcc-6
> > and give the patches a spin
> 
> Don't bother. _All_ gccs are broken in that respect currently.
> AFAIK Anton is working on this. You have to fake the test, like
> static int a; return a++;
> 
> Gcc fails to set the TOC for profiled "leaf" functions, where it
> thinks no global/static symbols are referenced.
> 


Thanks for the quick answer

BTW, do we expect static/non global functions to be called from
patched contexts? I understand that not supporting it will
complicate a patch.

Balbir Singh
Balbir Singh Feb. 11, 2016, 9:35 a.m. UTC | #5
On Thu, 2016-02-11 at 14:09 +0530, Kamalesh Babulal wrote:
> * Balbir Singh <bsingharora@gmail.com> [2016-02-11 18:48:17]:
> 
> > On Wed, 2016-02-10 at 17:25 +0100, Torsten Duwe wrote:
> > 
> > snip
> > 
> > > diff --git a/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> > > b/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> > > new file mode 100755
> > > index 0000000..68d6482
> > > --- /dev/null
> > > +++ b/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> > > @@ -0,0 +1,33 @@
> > > +#!/bin/sh
> > > +# Test whether the compile option -mprofile-kernel
> > > +# generates profiling code ( = a call to mcount), and
> > > +# whether a function without any global references sets
> > > +# the TOC pointer properly at the beginning, and
> > > +# whether the "notrace" function attribute successfully
> > > +# suppresses the _mcount call.
> > > +
> > > +echo "int func() { return 0; }" | \
> > > +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> > > +    grep -q "mcount"
> > > +
> > > +trace_result=$?
> > > +
> > > +echo "int func() { return 0; }" | \
> > > +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> > > +    sed -n -e '/func:/,/bl _mcount/p' | grep -q TOC
> > > +
> > > +leaf_toc_result=$?
> > > +
> > 
> > leaf_toc_result failed for me with gcc 5. I'll try and grab gcc-6
> > and give the patches a spin
> > 
> 
> It fails for me to on ppc64le but pass over ppc64
> 

This series is for ppc64le only, so we can safely ignore ppc64 for now

Regards,
Balbir Singh.
Murali Sampath Feb. 11, 2016, 1 p.m. UTC | #6
Original Message
From: Balbir Singh
Sent: Thursday, February 11, 2016 4:37 AM
To: Kamalesh Babulal
Cc: Petr Mladek; Jessica Yu; linux-kernel@vger.kernel.org; Steven Rostedt; Torsten Duwe; Jiri Kosina; live-patching@vger.kernel.org; Miroslav Benes; linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH v8 4/8] ppc64 ftrace_with_regs configuration variables


On Thu, 2016-02-11 at 14:09 +0530, Kamalesh Babulal wrote:
> * Balbir Singh <bsingharora@gmail.com> [2016-02-11 18:48:17]:
>
> > On Wed, 2016-02-10 at 17:25 +0100, Torsten Duwe wrote:
> >
> > snip
> >
> > > diff --git a/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> > > b/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> > > new file mode 100755
> > > index 0000000..68d6482
> > > --- /dev/null
> > > +++ b/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> > > @@ -0,0 +1,33 @@
> > > +#!/bin/sh
> > > +# Test whether the compile option -mprofile-kernel
> > > +# generates profiling code ( = a call to mcount), and
> > > +# whether a function without any global references sets
> > > +# the TOC pointer properly at the beginning, and
> > > +# whether the "notrace" function attribute successfully
> > > +# suppresses the _mcount call.
> > > +
> > > +echo "int func() { return 0; }" | \
> > > +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> > > +    grep -q "mcount"
> > > +
> > > +trace_result=$?
> > > +
> > > +echo "int func() { return 0; }" | \
> > > +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> > > +    sed -n -e '/func:/,/bl _mcount/p' | grep -q TOC
> > > +
> > > +leaf_toc_result=$?
> > > +
> >
> > leaf_toc_result failed for me with gcc 5. I'll try and grab gcc-6
> > and give the patches a spin
> >
>
> It fails for me to on ppc64le but pass over ppc64
>

This series is for ppc64le only, so we can safely ignore ppc64 for now

Regards,
Balbir Singh.
Murali Sampath Feb. 11, 2016, 1 p.m. UTC | #7
‎ t

  Original Message
From: Balbir Singh
Sent: Thursday, February 11, 2016 4:37 AM
To: Kamalesh Babulal
Cc: Petr Mladek; Jessica Yu; linux-kernel@vger.kernel.org; Steven Rostedt; Torsten Duwe; Jiri Kosina; live-patching@vger.kernel.org; Miroslav Benes; linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH v8 4/8] ppc64 ftrace_with_regs configuration variables


On Thu, 2016-02-11 at 14:09 +0530, Kamalesh Babulal wrote:
> * Balbir Singh <bsingharora@gmail.com> [2016-02-11 18:48:17]:
>
> > On Wed, 2016-02-10 at 17:25 +0100, Torsten Duwe wrote:
> >
> > snip
> >
> > > diff --git a/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> > > b/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> > > new file mode 100755
> > > index 0000000..68d6482
> > > --- /dev/null
> > > +++ b/arch/powerpc/gcc-mprofile-kernel-notrace.sh
> > > @@ -0,0 +1,33 @@
> > > +#!/bin/sh
> > > +# Test whether the compile option -mprofile-kernel
> > > +# generates profiling code ( = a call to mcount), and
> > > +# whether a function without any global references sets
> > > +# the TOC pointer properly at the beginning, and
> > > +# whether the "notrace" function attribute successfully
> > > +# suppresses the _mcount call.
> > > +
> > > +echo "int func() { return 0; }" | \
> > > +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> > > +    grep -q "mcount"
> > > +
> > > +trace_result=$?
> > > +
> > > +echo "int func() { return 0; }" | \
> > > +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> > > +    sed -n -e '/func:/,/bl _mcount/p' | grep -q TOC
> > > +
> > > +leaf_toc_result=$?
> > > +
> >
> > leaf_toc_result failed for me with gcc 5. I'll try and grab gcc-6
> > and give the patches a spin
> >
>
> It fails for me to on ppc64le but pass over ppc64
>

This series is for ppc64le only, so we can safely ignore ppc64 for now

Regards,
Balbir Singh.
Michael Ellerman Feb. 15, 2016, 10:27 a.m. UTC | #8
Hi guys,

Sorry I haven't been keeping up to date with this thread I've been away.

On Thu, 2016-02-11 at 09:42 +0100, Torsten Duwe wrote:
> On Thu, Feb 11, 2016 at 06:48:17PM +1100, Balbir Singh wrote:
> > On Wed, 2016-02-10 at 17:25 +0100, Torsten Duwe wrote:
> > > +
> > > +echo "int func() { return 0; }" | \
> > > +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> > > +    sed -n -e '/func:/,/bl _mcount/p' | grep -q TOC
> > > +
> > > +leaf_toc_result=$?
> > 
> > leaf_toc_result failed for me with gcc 5. I'll try and grab gcc-6
> > and give the patches a spin
> 
> Don't bother. _All_ gccs are broken in that respect currently.

I'm not sure where we got our wires crossed on this one, but this is not a gcc
bug. In fact it's a feature :)

There is explicit code in gcc to check whether the TOC setup is needed and only
emit it when it's required. One case where it's *not* required is when the
function does not TOC accesses. (See rs6000_global_entry_point_needed_p()).

So I think this is just one of the "fun" details we have to deal with to
implement kernel tracing.

The first implication of this is that there is not a single offset value for
the _mcount call, it needs to be calculated per-function. In practice there
will only be two values, so we could try both, or we could just have the code
work it out dynamically by looking for the expected code sequence?

Secondly it means the ftrace trampoline needs to cope with being called with r2
containing something other than the kernel TOC (ie. a module's TOC pointer).
But I think that's solvable also?

cheers
Jiri Kosina Feb. 15, 2016, 12:56 p.m. UTC | #9
On Mon, 15 Feb 2016, Michael Ellerman wrote:

> > > > +echo "int func() { return 0; }" | \
> > > > +    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
> > > > +    sed -n -e '/func:/,/bl _mcount/p' | grep -q TOC
> > > > +
> > > > +leaf_toc_result=$?
> > > 
> > > leaf_toc_result failed for me with gcc 5. I'll try and grab gcc-6
> > > and give the patches a spin
> > 
> > Don't bother. _All_ gccs are broken in that respect currently.
> 
> I'm not sure where we got our wires crossed on this one, but this is not a gcc
> bug. In fact it's a feature :)
> 
> There is explicit code in gcc to check whether the TOC setup is needed and only
> emit it when it's required. One case where it's *not* required is when the
> function does not TOC accesses. (See rs6000_global_entry_point_needed_p()).

As gcc actually implements a '-mprofile-kernel' option, it's pretty much 
aware of the fact that the inserted space will be used by the kernel for 
inserting a call (as that's the sole point of the whole thing).

Therefore it must not consider any traceable function to be leaf (even 
though it might "look" leaf from the source code); if it does, then the 
mprofile-kernel option is useless.

So I actually would dare to call it a bug.

Thanks,
Torsten Duwe Feb. 15, 2016, 2:04 p.m. UTC | #10
On Mon, Feb 15, 2016 at 09:27:15PM +1100, Michael Ellerman wrote:
> 
> There is explicit code in gcc to check whether the TOC setup is needed and only

That's undestood. The claim here is: that check is incomplete, at least.

> emit it when it's required. One case where it's *not* required is when the
> function does not TOC accesses. (See rs6000_global_entry_point_needed_p()).

n.b. I cannot find this symbol in the 4.9.3 tree, but I know what you mean.

The point here is: If you profile using "-pg", gcc perfectly recognises that
it is generating a call to "_mcount", which may be non-local, and loads the TOC.
If you use "-pg -mprofile-kernel", gcc seems to forget that, and omits the TOC
load, for a similar assembler calling sequence.

Looking at the code I can _understand_ why this is so, but my GCC knowledge
is not that deep that I could easily _fix_ this reliably.

[...]

> Secondly it means the ftrace trampoline needs to cope with being called with r2
> containing something other than the kernel TOC (ie. a module's TOC pointer).
> But I think that's solvable also?

That was the alternative I asked about; but given that the _mcount / ftrace_caller
trampoline hardly differs from a normal trampoline (so far), loading R2 would be the
general case, or an excessive special case handling would result.

I'd rather see gcc getting fixed than to have workarounds in all projects that use
it, and others agreed.

	Torsten
Michael Ellerman Feb. 16, 2016, 10:09 a.m. UTC | #11
On Mon, 2016-02-15 at 15:04 +0100, Torsten Duwe wrote:
> On Mon, Feb 15, 2016 at 09:27:15PM +1100, Michael Ellerman wrote:
> > 
> > There is explicit code in gcc to check whether the TOC setup is needed and only
> 
> That's undestood. The claim here is: that check is incomplete, at least.

OK at least we agree on what's happening.

> > emit it when it's required. One case where it's *not* required is when the
> > function does not TOC accesses. (See rs6000_global_entry_point_needed_p()).
> 
> n.b. I cannot find this symbol in the 4.9.3 tree, but I know what you mean.
> 
> The point here is: If you profile using "-pg", gcc perfectly recognises that
> it is generating a call to "_mcount", which may be non-local, and loads the TOC.
> If you use "-pg -mprofile-kernel", gcc seems to forget that, and omits the TOC
> load, for a similar assembler calling sequence.

That's by design.

mprofile-kernel is supposed to create as little overhead as possible in the
non-traced case. All of the burden is shifted to the trace function (_mcount).

The reason to do that is because modern distros always build with tracing, but
most of the time tracing will not actually be active. So we want the cost of
tracing-built-in-but-disabled to be ~zero.

> > Secondly it means the ftrace trampoline needs to cope with being called with r2
> > containing something other than the kernel TOC (ie. a module's TOC pointer).
> > But I think that's solvable also?
> 
> That was the alternative I asked about; but given that the _mcount / ftrace_caller
> trampoline hardly differs from a normal trampoline (so far), loading R2 would be the
> general case, or an excessive special case handling would result.

I'm not sure I follow what you mean there at the end.

Requiring ftrace_caller() to load the kernel TOC is not a problem IMHO.

I think I have an easier way to do it, I'll reply to the patch with that (if it
works).

cheers
Torsten Duwe Feb. 16, 2016, 10:35 a.m. UTC | #12
On Tue, Feb 16, 2016 at 09:09:16PM +1100, Michael Ellerman wrote:
> On Mon, 2016-02-15 at 15:04 +0100, Torsten Duwe wrote:
> > If you use "-pg -mprofile-kernel", gcc seems to forget that, and omits the TOC
> > load, for a similar assembler calling sequence.
> 
> That's by design.

Ah, ok.

> mprofile-kernel is supposed to create as little overhead as possible in the
> non-traced case. All of the burden is shifted to the trace function (_mcount).

... or its helpers, see below.

> The reason to do that is because modern distros always build with tracing, but
> most of the time tracing will not actually be active. So we want the cost of
> tracing-built-in-but-disabled to be ~zero.

Ok, that's a design goal.

> > That was the alternative I asked about; but given that the _mcount / ftrace_caller
> > trampoline hardly differs from a normal trampoline (so far), loading R2 would be the
> > general case, or an excessive special case handling would result.
> 
> I'm not sure I follow what you mean there at the end.

This suggests you have not yet actively debugged this problem ;-)

> Requiring ftrace_caller() to load the kernel TOC is not a problem IMHO.

The problem is, you don't get to ftrace_caller in the first place :)

> I think I have an easier way to do it, I'll reply to the patch with that (if it
> works).

I doubt so. Either it works, _or_ it is easier ;)

To save you some work: by the design of minimal overhead you try to follow,
SQUASH_TOC_SAVE_INSN from my patches isn't sufficient. You'll need to load the
_current_ TOC _on_ the trampoline, and in turn it will be different from the regular
trampolines; and that needs to be recognised, or the normal module linker logic
won't work.

OTOH my proposed GCC change only affects a very limited number of functions...

Looking forward to your patch!

	Torsten
diff mbox

Patch

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index e4824fd..e5f288c 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -94,8 +94,10 @@  config PPC
 	select OF_RESERVED_MEM
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_DYNAMIC_FTRACE
+	select HAVE_DYNAMIC_FTRACE_WITH_REGS if PPC64 && CPU_LITTLE_ENDIAN
 	select HAVE_FUNCTION_TRACER
 	select HAVE_FUNCTION_GRAPH_TRACER
+	select HAVE_MPROFILE_KERNEL if PPC64 && CPU_LITTLE_ENDIAN
 	select SYSCTL_EXCEPTION_TRACE
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select VIRT_TO_BUS if !PPC64
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 96efd82..08a3952 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -133,6 +133,23 @@  else
 CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64
 endif
 
+ifeq ($(CONFIG_PPC64),y)
+ifdef CONFIG_HAVE_MPROFILE_KERNEL
+
+ifdef CONFIG_DYNAMIC_FTRACE
+ifeq ($(shell $(CONFIG_SHELL) $(srctree)/arch/powerpc/gcc-mprofile-kernel-notrace.sh $(CC) -I$(srctree)/include -D__KERNEL__), y)
+CC_USING_MPROFILE_KERNEL := -mprofile-kernel
+endif
+endif
+
+ifdef CC_USING_MPROFILE_KERNEL
+CC_FLAGS_FTRACE	:= -pg $(CC_USING_MPROFILE_KERNEL)
+KBUILD_CPPFLAGS	+= -DCC_USING_MPROFILE_KERNEL
+endif
+
+endif
+endif
+
 CFLAGS-$(CONFIG_CELL_CPU) += $(call cc-option,-mcpu=cell)
 CFLAGS-$(CONFIG_POWER4_CPU) += $(call cc-option,-mcpu=power4)
 CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5)
diff --git a/arch/powerpc/gcc-mprofile-kernel-notrace.sh b/arch/powerpc/gcc-mprofile-kernel-notrace.sh
new file mode 100755
index 0000000..68d6482
--- /dev/null
+++ b/arch/powerpc/gcc-mprofile-kernel-notrace.sh
@@ -0,0 +1,33 @@ 
+#!/bin/sh
+# Test whether the compile option -mprofile-kernel
+# generates profiling code ( = a call to mcount), and
+# whether a function without any global references sets
+# the TOC pointer properly at the beginning, and
+# whether the "notrace" function attribute successfully
+# suppresses the _mcount call.
+
+echo "int func() { return 0; }" | \
+    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
+    grep -q "mcount"
+
+trace_result=$?
+
+echo "int func() { return 0; }" | \
+    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
+    sed -n -e '/func:/,/bl _mcount/p' | grep -q TOC
+
+leaf_toc_result=$?
+
+/bin/echo -e "#include <linux/compiler.h>\nnotrace int func() { return 0; }" | \
+    $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \
+    grep -q "mcount"
+
+notrace_result=$?
+
+if [ "$trace_result" -eq "0" -a \
+	"$leaf_toc_result" -eq "0" -a \
+	"$notrace_result" -eq "1" ]; then
+	echo y
+else
+	echo n
+fi
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index ef8b916..29b7014 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -28,6 +28,11 @@ 
 
 
 #ifdef CONFIG_DYNAMIC_FTRACE
+#if defined(CONFIG_DYNAMIC_FTRACE_WITH_REGS) && defined(CONFIG_PPC64) && \
+  !defined(CC_USING_MPROFILE_KERNEL)
+#error "DYNAMIC_FTRACE_WITH_REGS requires working -mprofile-kernel"
+#endif
+
 static unsigned int
 ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
 {
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index e45db6b..a138f6d 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -52,6 +52,11 @@  config HAVE_FENTRY
 	help
 	  Arch supports the gcc options -pg with -mfentry
 
+config HAVE_MPROFILE_KERNEL
+	bool
+	help
+	  Arch supports the gcc options -pg with -mprofile-kernel
+
 config HAVE_C_RECORDMCOUNT
 	bool
 	help