From: Wu Zhangjin <wuzhangjin@gmail.com>
To: linux-mips@linux-mips.org, linux-kernel@vger.kernel.org
Cc: Wang Liming <liming.wang@windriver.com>,
Wu Zhangjin <wuzj@lemote.com>,
Steven Rostedt <rostedt@goodmis.org>,
Ralf Baechle <ralf@linux-mips.org>,
Thomas Gleixner <tglx@linutronix.de>,
Nicholas Mc Guire <der.herr@hofr.at>, Ingo Molnar <mingo@elte.hu>
Subject: [PATCH v3] mips function graph tracer support
Date: Sun, 14 Jun 2009 23:53:09 +0800 [thread overview]
Message-ID: <80e0889dc1b610e73809b9899ada7442ee9749dc.1244994151.git.wuzj@lemote.com> (raw)
In-Reply-To: <cover.1244994151.git.wuzj@lemote.com>
From: Wu Zhangjin <wuzj@lemote.com>
this works something like -finstrument-functions does, instead of using
void __cyg_profile_func_enter (void *this_fn,
void *call_site);
void __cyg_profile_func_exit (void *this_fn,
void *call_site);
-pg use _mcount, so some tricks are adoptive by the author of orignal function
graph tracer:
the _mcount function will call prepare_function_return to save the
parent_ip, ip and calltime in a tracing array, if success, the
address of a hooker function &return_to_handler will be substitued
to the parent_ip, so, after return from _mcount it will call the
&return_to_handler, not back to the parent_ip, but calling
ftrace_return_to_handler to remember the rettime, and return the
parent_ip to let &return_to_handler go back to the real parent.
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Wu Zhangjin <wuzj@lemote.com>
---
arch/mips/Kconfig | 1 +
arch/mips/kernel/ftrace.c | 66 ++++++++++++++++++++++++++++++++++++++++
arch/mips/kernel/mcount.S | 61 +++++++++++++++++++++++++++++++++++--
arch/mips/kernel/vmlinux.lds.S | 1 +
4 files changed, 126 insertions(+), 3 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 0857239..5ac9f45 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -9,6 +9,7 @@ config MIPS
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
+ select HAVE_FUNCTION_GRAPH_TRACER
# Horrible source of confusion. Die, die, die ...
select EMBEDDED
select RTC_LIB
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
index ad490cc..65d4d56 100644
--- a/arch/mips/kernel/ftrace.c
+++ b/arch/mips/kernel/ftrace.c
@@ -205,3 +205,69 @@ int __init ftrace_dyn_arch_init(void *data)
return 0;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+
+#define JMP 0x08000000 /* jump to target directly */
+extern void ftrace_graph_call(void);
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+ unsigned long ip = (unsigned long) (&ftrace_graph_call);
+ unsigned char old[MCOUNT_INSN_SIZE], *new;
+ int ret;
+
+ /* j ftrace_stub */
+ memcpy(old, (unsigned long *) ip, MCOUNT_INSN_SIZE);
+ new = ftrace_call_replace(JMP, (unsigned long) ftrace_graph_caller);
+
+ ret = ftrace_modify_code(ip, old, new);
+
+ return ret;
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+ unsigned long ip = (unsigned long) (&ftrace_graph_call);
+ unsigned char old[MCOUNT_INSN_SIZE], *new;
+ int ret;
+
+ /* j ftrace_graph_caller */
+ memcpy(old, (unsigned long *) ip, MCOUNT_INSN_SIZE);
+ new = ftrace_call_replace(JMP, (unsigned long) ftrace_stub);
+
+ ret = ftrace_modify_code(ip, old, new);
+
+ return ret;
+}
+
+#endif /* !CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+
+unsigned long prepare_ftrace_return(unsigned long ip,
+ unsigned long parent_ip)
+{
+ struct ftrace_graph_ent trace;
+
+ /* Nmi's are currently unsupported */
+ if (unlikely(in_nmi()) ||
+ unlikely(atomic_read(¤t->tracing_graph_pause)) ||
+ (ftrace_push_return_trace(parent_ip, ip, &trace.depth) == -EBUSY))
+ return parent_ip;
+
+ trace.func = ip;
+
+ /* Only trace if the calling function expects to */
+ if (ftrace_graph_entry(&trace))
+ return (unsigned long) &return_to_handler;
+
+ current->curr_ret_stack--;
+ return parent_ip;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S
index 723ace2..559f9bd 100644
--- a/arch/mips/kernel/mcount.S
+++ b/arch/mips/kernel/mcount.S
@@ -27,7 +27,6 @@
.macro MCOUNT_SAVE_REGS
PTR_SUBU sp, PT_SIZE
PTR_S ra, PT_R31(sp)
- PTR_S $1, PT_R1(sp)
PTR_S a0, PT_R4(sp)
PTR_S a1, PT_R5(sp)
PTR_S a2, PT_R6(sp)
@@ -42,7 +41,6 @@
.macro MCOUNT_RESTORE_REGS
PTR_L ra, PT_R31(sp)
- PTR_L $1, PT_R1(sp)
PTR_L a0, PT_R4(sp)
PTR_L a1, PT_R5(sp)
PTR_L a2, PT_R6(sp)
@@ -81,6 +79,7 @@ NESTED(ftrace_caller, PT_SIZE, ra)
nop
MCOUNT_SAVE_REGS
+ PTR_S $1, PT_R1(sp)
MCOUNT_SET_ARGS
.globl ftrace_call
@@ -88,7 +87,16 @@ ftrace_call:
jal ftrace_stub
nop
+ PTR_L $1, PT_R1(sp)
MCOUNT_RESTORE_REGS
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ .globl ftrace_graph_call
+ftrace_graph_call:
+ j ftrace_stub
+ nop
+#endif
+
.globl ftrace_stub
ftrace_stub:
RETURN_BACK
@@ -106,17 +114,27 @@ NESTED(_mcount, PT_SIZE, ra)
PTR_L t1, ftrace_trace_function /* please don't use t1 later, safe? */
bne t0, t1, static_trace
nop
-
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ PTR_L t2, ftrace_graph_return
+ bne t0, t2, ftrace_graph_caller
+ nop
+ PTR_LA t0, ftrace_graph_entry_stub
+ PTR_L t2, ftrace_graph_entry
+ bne t0, t2, ftrace_graph_caller
+ nop
+#endif
j ftrace_stub
nop
static_trace:
MCOUNT_SAVE_REGS
+ PTR_S $1, PT_R1(sp)
MCOUNT_SET_ARGS /* call *ftrace_trace_function */
jalr t1
nop
+ PTR_L $1, PT_R1(sp)
MCOUNT_RESTORE_REGS
.globl ftrace_stub
ftrace_stub:
@@ -125,5 +143,42 @@ ftrace_stub:
#endif /* ! CONFIG_DYNAMIC_FTRACE */
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+NESTED(ftrace_graph_caller, PT_SIZE, ra)
+ MCOUNT_SAVE_REGS
+ PTR_S v0, PT_R2(sp)
+
+ MCOUNT_SET_ARGS
+ jal prepare_ftrace_return
+ nop
+
+ /* overwrite the parent as &return_to_handler: v0 -> $1(at) */
+ move $1, v0
+
+ PTR_L v0, PT_R2(sp)
+ MCOUNT_RESTORE_REGS
+ RETURN_BACK
+ END(ftrace_graph_caller)
+
+ .align 2
+ .globl return_to_handler
+return_to_handler:
+ PTR_SUBU sp, PT_SIZE
+ PTR_S v0, PT_R2(sp)
+
+ jal ftrace_return_to_handler
+ nop
+
+ /* restore the real parent address: v0 -> ra */
+ move ra, v0
+
+ PTR_L v0, PT_R2(sp)
+ PTR_ADDIU sp, PT_SIZE
+
+ jr ra
+
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
.set at
.set reorder
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 58738c8..67435e5 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -36,6 +36,7 @@ SECTIONS
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
+ IRQENTRY_TEXT
*(.text.*)
*(.fixup)
*(.gnu.warning)
--
1.6.0.4
next prev parent reply other threads:[~2009-06-14 15:53 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-14 15:50 [PATCH v3] mips-specific ftrace support Wu Zhangjin
2009-06-14 15:51 ` [PATCH v3] mips static function tracer support Wu Zhangjin
2009-06-14 15:52 ` [PATCH v3] add an endian argument to scripts/recordmcount.pl Wu Zhangjin
2009-06-14 15:52 ` [PATCH v3] mips dynamic function tracer support Wu Zhangjin
2009-06-14 15:52 ` [PATCH v3] filter local function prefixed by $L Wu Zhangjin
2009-06-15 15:59 ` David Daney
2009-06-15 16:30 ` Steven Rostedt
2009-06-15 18:48 ` Wu Zhangjin
2009-06-14 15:53 ` Wu Zhangjin [this message]
2009-06-14 15:53 ` [PATCH v3] mips specific clock function to get precise timestamp Wu Zhangjin
2009-06-14 15:53 ` [PATCH v3] mips specific system call tracer Wu Zhangjin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=80e0889dc1b610e73809b9899ada7442ee9749dc.1244994151.git.wuzj@lemote.com \
--to=wuzhangjin@gmail.com \
--cc=der.herr@hofr.at \
--cc=liming.wang@windriver.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@linux-mips.org \
--cc=mingo@elte.hu \
--cc=ralf@linux-mips.org \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
--cc=wuzj@lemote.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.