Re: [PATCH 2/2] ftrace: support for PowerPC

Previous thread: [PATCH 1/2] ftrace ppc: add irqs_disabled_flags to ppc by Steven Rostedt on Wednesday, May 14, 2008 - 8:49 pm. (2 messages)

Next thread: Re: NET_SCHED cbq dropping too many packets on a bonding interface by Kingsley Foreman on Wednesday, May 14, 2008 - 11:16 pm. (2 messages)
From: Steven Rostedt
Date: Wednesday, May 14, 2008 - 8:49 pm

This patch adds full support for ftrace for PowerPC (both 64 and 32 bit).
This includes dynamic tracing and function filtering.

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
---
 arch/powerpc/Kconfig                     |    5 
 arch/powerpc/kernel/Makefile             |   14 ++
 arch/powerpc/kernel/entry_32.S           |  130 ++++++++++++++++++++++++
 arch/powerpc/kernel/entry_64.S           |   62 +++++++++++
 arch/powerpc/kernel/ftrace.c             |  165 +++++++++++++++++++++++++++++++
 arch/powerpc/kernel/io.c                 |    3 
 arch/powerpc/kernel/irq.c                |    6 -
 arch/powerpc/kernel/setup_32.c           |   11 +-
 arch/powerpc/kernel/setup_64.c           |    5 
 arch/powerpc/platforms/powermac/Makefile |    5 
 kernel/trace/trace_selftest.c            |   11 +-
 11 files changed, 406 insertions(+), 11 deletions(-)

Index: linux-sched-devel.git/arch/powerpc/kernel/io.c
===================================================================
--- linux-sched-devel.git.orig/arch/powerpc/kernel/io.c	2008-05-14 19:30:53.000000000 -0700
+++ linux-sched-devel.git/arch/powerpc/kernel/io.c	2008-05-14 19:31:48.000000000 -0700
@@ -120,7 +120,8 @@ EXPORT_SYMBOL(_outsl_ns);
 
 #define IO_CHECK_ALIGN(v,a) ((((unsigned long)(v)) & ((a) - 1)) == 0)
 
-void _memset_io(volatile void __iomem *addr, int c, unsigned long n)
+notrace void
+_memset_io(volatile void __iomem *addr, int c, unsigned long n)
 {
 	void *p = (void __force *)addr;
 	u32 lc = c;
Index: linux-sched-devel.git/arch/powerpc/kernel/Makefile
===================================================================
--- linux-sched-devel.git.orig/arch/powerpc/kernel/Makefile	2008-05-14 19:30:53.000000000 -0700
+++ linux-sched-devel.git/arch/powerpc/kernel/Makefile	2008-05-14 19:31:56.000000000 -0700
@@ -12,6 +12,18 @@ CFLAGS_prom_init.o      += -fPIC
 CFLAGS_btext.o		+= -fPIC
 endif
 
+ifdef CONFIG_FTRACE
+# Do not trace early boot code
+CFLAGS_REMOVE_cputable.o = -pg
+CFLAGS_REMOVE_prom_init.o = ...
From: David Miller
Date: Wednesday, May 14, 2008 - 10:28 pm

From: Steven Rostedt <rostedt@goodmis.org>

Yikes, that's really expensive.

Can't you do a tail call and let the function you end
up calling do all the callee-saved register pops onto
the stack?

That's what I did on sparc.
--

From: Steven Rostedt
Date: Thursday, May 15, 2008 - 6:38 am

Well, at least with dynamic ftrace, it's only expensive when tracing is

Not sure PPC has such a thing. I'm only a hobby PPC hacker (did it full
time in another life). If there is such a way, I'll be happy to Ack any

So that was your secret! ;-)

-- Steve

--

From: Scott Wood
Date: Thursday, May 15, 2008 - 9:48 am

The PPC32 ABI seems to (unfortunately) suggest that, with mcount, all
registers are callee-saved (except for the modifiable-during-function-linkage
registers like r0, r11, and r12) -- so mcount has to save the registers that
the callee won't (because they're normally volatile).

-Scott
--

From: Ingo Molnar
Date: Friday, May 16, 2008 - 5:06 am

applied, thanks. Nice stuff! :)

	Ingo
--

From: Michael Ellerman
Date: Tuesday, May 20, 2008 - 7:04 am

Hi Steven,

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

I don't grok what you're doing with CALL_BACK, you add it in places and
subtract in others - and it looks like you could do neither, but I haven't


And that.


0x03fffffe should be 0x03fffffc, if you set bit 1 you'll end with a "bla" i=
nstruction,
ie. branch absolute and link. That shouldn't happen as long as ip and addr =
are
properly aligned, but still.

In fact I think you should just use create_function_call() or create_branch=
() from

We already have a #define for .long, it's called PPC_LONG (asm/asm-compat.h=
)


=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

Can you please put the extern in a header, and the EXPORT_SYMBOL in arch/po=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

Ditto.


cheers


--=20
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
From: Benjamin Herrenschmidt
Date: Tuesday, May 20, 2008 - 7:17 am

Not running at the linked address... might be causing trouble.

Ben.


--

From: Steven Rostedt
Date: Tuesday, May 20, 2008 - 7:51 am

I figured it was something like that, so I didn't look too deep into it,
and decided that it was best just not to trace it.

-- Steve

--

From: Steven Rostedt
Date: Tuesday, May 20, 2008 - 7:32 am

Hi Michael,

I really appreciate this. It's been a few years since I did any real PPC

The -pg flag makes calls to the mcount code. I didn't look too deeply, but
at least in my first prototypes the early boot up code would crash when
calling mcount. I found that simply keeping them from calling mcount made
things OK. Perhaps I'm just hiding the problem, but the tracing wont


I tried hard to make most of the complex logic stay in generic code.

What dynamic ftrace does is at start up the code is simply a nop. Then
after initialization of ftrace, it calls kstop-machine that will call into
the arch code to convert the nop to a call to a "record_ip" function.
That record_ip function will start recording the return address of the
mcount function (__builtin_return_address(0)).

Then later, once a second the ftraced wakes up and checks if any new
functions have been recorded. If they have been, then it calls
kstop_machine againg and for each recorded function, it passes in the
address that was recorded.

The arch is responsible for knowning how to translate the
__builtin_return_address(0) into the address of the location of the call,
to be able to modify that code.

On boot up, all functions call "mcount". The ftraced daemon will convert
those calls to nop, and when tracing is enabled, then they will be
converted to point directly to the tracing function.






Actually, I think Ingo added this into the generic code. I'll see what's

Ditto too ;-)


Thanks a lot for you feedback!

-- Steve

--

From: Steven Rostedt
Date: Thursday, May 22, 2008 - 11:31 am

This patch cleans up the ftrace code in PowerPC based on the comments from
Michael Ellerman.

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
---
 -0700                           |binary
 arch/powerpc/kernel/entry_32.S  |   11 ++---------
 arch/powerpc/kernel/ftrace.c    |    8 +++++++-
 arch/powerpc/kernel/ppc_ksyms.c |    5 +++++
 arch/powerpc/kernel/setup_32.c  |    5 -----
 arch/powerpc/kernel/setup_64.c  |    5 -----
 include/asm-powerpc/ftrace.h    |    6 ++++++
 6 files changed, 20 insertions(+), 20 deletions(-)

Index: linux-tip.git/arch/powerpc/kernel/entry_32.S
===================================================================
--- linux-tip.git.orig/arch/powerpc/kernel/entry_32.S	2008-05-22 09:17:51.000000000 -0700
+++ linux-tip.git/arch/powerpc/kernel/entry_32.S	2008-05-22 09:18:21.000000000 -0700
@@ -1129,18 +1129,11 @@ _GLOBAL(_mcount)
 	stw	r5, 8(r1)

 	LOAD_REG_ADDR(r5, ftrace_trace_function)
-#if 0
-	mtctr	r3
-	mr	r1, r5
-	bctrl
-#endif
 	lwz	r5,0(r5)
-#if 1
+
 	mtctr	r5
 	bctrl
-#else
-	bl	ftrace_stub
-#endif
+
 	nop

 	lwz	r6, 8(r1)
Index: linux-tip.git/arch/powerpc/kernel/ftrace.c
===================================================================
--- linux-tip.git.orig/arch/powerpc/kernel/ftrace.c	2008-05-22 09:19:12.000000000 -0700
+++ linux-tip.git/arch/powerpc/kernel/ftrace.c	2008-05-22 09:29:45.000000000 -0700
@@ -51,10 +51,16 @@ notrace unsigned char *ftrace_call_repla
 {
 	static unsigned int op;

+	/*
+	 * It would be nice to just use create_function_call, but that will
+	 * update the code itself. Here we need to just return the
+	 * instruction that is going to be modified, without modifying the
+	 * code.
+	 */
 	addr = GET_ADDR(addr);

 	/* Set to "bl addr" */
-	op = 0x48000001 | (ftrace_calc_offset(ip, addr) & 0x03fffffe);
+	op = 0x48000001 | (ftrace_calc_offset(ip, addr) & 0x03fffffc);

 	/*
 	 * No locking needed, this must be called via kstop_machine
Index: ...
From: Thomas Gleixner
Date: Tuesday, May 27, 2008 - 8:36 am

Applied, thanks

	 tglx
--

From: Michael Ellerman
Date: Sunday, June 1, 2008 - 7:15 pm

Hi Steven,

Thanks for that.

I posted some patches last week, also in my git tree[1], that should
allow you to use create_branch() in your code (and also facilitate some
other things I wanted to do). I also added a #define for NOP also.

If/when my patches go into powerpc-next I'll do a patch against
linux-next for ftrace to use them.

cheers

[1]: http://git.kernel.org/?p=3Dlinux/kernel/git/mpe/linux-2.6.git;a=3Dsumm=
ary

--=20
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person