From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Ingo Molnar <mingo@elte.hu>,
Andrew Morton <akpm@linux-foundation.org>,
Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Thomas Gleixner <tglx@linutronix.de>,
"H. Peter Anvin" <hpa@zytor.com>
Subject: [PATCH 09/19] ftrace: Add default recursion protection for function tracing
Date: Fri, 20 Jul 2012 22:19:52 -0400 [thread overview]
Message-ID: <20120721022108.934274530@goodmis.org> (raw)
In-Reply-To: 20120721021943.274162381@goodmis.org
[-- Attachment #1: Type: text/plain, Size: 7897 bytes --]
From: Steven Rostedt <srostedt@redhat.com>
As more users of the function tracer utility are being added, they do
not always add the necessary recursion protection. To protect from
function recursion due to tracing, if the callback ftrace_ops does not
specifically specify that it protects against recursion (by setting
the FTRACE_OPS_FL_RECURSION_SAFE flag), the list operation will be
called by the mcount trampoline which adds recursion protection.
If the flag is set, then the function will be called directly with no
extra protection.
Note, the list operation is called if more than one function callback
is registered, or if the arch does not support all of the function
tracer features.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
include/linux/ftrace.h | 5 +++++
kernel/trace/ftrace.c | 10 ++++++++--
kernel/trace/trace_events.c | 1 +
kernel/trace/trace_functions.c | 4 ++--
kernel/trace/trace_irqsoff.c | 2 +-
kernel/trace/trace_sched_wakeup.c | 2 +-
kernel/trace/trace_selftest.c | 7 +++++--
kernel/trace/trace_stack.c | 1 +
8 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index ab39990..65a14e4 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -85,6 +85,10 @@ typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip,
* passing regs to the handler.
* Note, if this flag is set, the SAVE_REGS flag will automatically
* get set upon registering the ftrace_ops, if the arch supports it.
+ * RECURSION_SAFE - The ftrace_ops can set this to tell the ftrace infrastructure
+ * that the call back has its own recursion protection. If it does
+ * not set this, then the ftrace infrastructure will add recursion
+ * protection for the caller.
*/
enum {
FTRACE_OPS_FL_ENABLED = 1 << 0,
@@ -93,6 +97,7 @@ enum {
FTRACE_OPS_FL_CONTROL = 1 << 3,
FTRACE_OPS_FL_SAVE_REGS = 1 << 4,
FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED = 1 << 5,
+ FTRACE_OPS_FL_RECURSION_SAFE = 1 << 6,
};
struct ftrace_ops {
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index c55f7e2..ad765b4 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -66,6 +66,7 @@
static struct ftrace_ops ftrace_list_end __read_mostly = {
.func = ftrace_stub,
+ .flags = FTRACE_OPS_FL_RECURSION_SAFE,
};
/* ftrace_enabled is a method to turn ftrace on or off */
@@ -221,12 +222,13 @@ static void update_ftrace_function(void)
/*
* If we are at the end of the list and this ops is
- * not dynamic and the arch supports passing ops, then have the
- * mcount trampoline call the function directly.
+ * recursion safe and not dynamic and the arch supports passing ops,
+ * then have the mcount trampoline call the function directly.
*/
if (ftrace_ops_list == &ftrace_list_end ||
(ftrace_ops_list->next == &ftrace_list_end &&
!(ftrace_ops_list->flags & FTRACE_OPS_FL_DYNAMIC) &&
+ (ftrace_ops_list->flags & FTRACE_OPS_FL_RECURSION_SAFE) &&
!FTRACE_FORCE_LIST_FUNC)) {
/* Set the ftrace_ops that the arch callback uses */
if (ftrace_ops_list == &global_ops)
@@ -867,6 +869,7 @@ static void unregister_ftrace_profiler(void)
#else
static struct ftrace_ops ftrace_profile_ops __read_mostly = {
.func = function_profile_call,
+ .flags = FTRACE_OPS_FL_RECURSION_SAFE,
};
static int register_ftrace_profiler(void)
@@ -1049,6 +1052,7 @@ static struct ftrace_ops global_ops = {
.func = ftrace_stub,
.notrace_hash = EMPTY_HASH,
.filter_hash = EMPTY_HASH,
+ .flags = FTRACE_OPS_FL_RECURSION_SAFE,
};
static DEFINE_MUTEX(ftrace_regex_lock);
@@ -3967,6 +3971,7 @@ void __init ftrace_init(void)
static struct ftrace_ops global_ops = {
.func = ftrace_stub,
+ .flags = FTRACE_OPS_FL_RECURSION_SAFE,
};
static int __init ftrace_nodyn_init(void)
@@ -4023,6 +4028,7 @@ ftrace_ops_control_func(unsigned long ip, unsigned long parent_ip,
static struct ftrace_ops control_ops = {
.func = ftrace_ops_control_func,
+ .flags = FTRACE_OPS_FL_RECURSION_SAFE,
};
static inline void
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 8c66968..6825d83 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -1721,6 +1721,7 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip,
static struct ftrace_ops trace_ops __initdata =
{
.func = function_test_events_call,
+ .flags = FTRACE_OPS_FL_RECURSION_SAFE,
};
static __init void event_trace_self_test_with_function(void)
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 5675ebd..fdff65d 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -153,13 +153,13 @@ function_stack_trace_call(unsigned long ip, unsigned long parent_ip,
static struct ftrace_ops trace_ops __read_mostly =
{
.func = function_trace_call,
- .flags = FTRACE_OPS_FL_GLOBAL,
+ .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE,
};
static struct ftrace_ops trace_stack_ops __read_mostly =
{
.func = function_stack_trace_call,
- .flags = FTRACE_OPS_FL_GLOBAL,
+ .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE,
};
/* Our two options */
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index c7a9ba9..d98ee82 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -154,7 +154,7 @@ irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip,
static struct ftrace_ops trace_ops __read_mostly =
{
.func = irqsoff_tracer_call,
- .flags = FTRACE_OPS_FL_GLOBAL,
+ .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE,
};
#endif /* CONFIG_FUNCTION_TRACER */
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
index 7547e36..02170c0 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -130,7 +130,7 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip,
static struct ftrace_ops trace_ops __read_mostly =
{
.func = wakeup_tracer_call,
- .flags = FTRACE_OPS_FL_GLOBAL,
+ .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE,
};
#endif /* CONFIG_FUNCTION_TRACER */
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
index add37e0..1fb6da8 100644
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -148,19 +148,22 @@ static void trace_selftest_test_dyn_func(unsigned long ip,
static struct ftrace_ops test_probe1 = {
.func = trace_selftest_test_probe1_func,
+ .flags = FTRACE_OPS_FL_RECURSION_SAFE,
};
static struct ftrace_ops test_probe2 = {
.func = trace_selftest_test_probe2_func,
+ .flags = FTRACE_OPS_FL_RECURSION_SAFE,
};
static struct ftrace_ops test_probe3 = {
.func = trace_selftest_test_probe3_func,
+ .flags = FTRACE_OPS_FL_RECURSION_SAFE,
};
static struct ftrace_ops test_global = {
- .func = trace_selftest_test_global_func,
- .flags = FTRACE_OPS_FL_GLOBAL,
+ .func = trace_selftest_test_global_func,
+ .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE,
};
static void print_counts(void)
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index 2fa5328..0c1b1657 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -137,6 +137,7 @@ stack_trace_call(unsigned long ip, unsigned long parent_ip,
static struct ftrace_ops trace_ops __read_mostly =
{
.func = stack_trace_call,
+ .flags = FTRACE_OPS_FL_RECURSION_SAFE,
};
static ssize_t
--
1.7.10.4
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
next prev parent reply other threads:[~2012-07-21 2:22 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-21 2:19 [PATCH 00/19] [GIT PULL][v3.6] ftrace: Allow kprobes to work with ftace Steven Rostedt
2012-07-21 2:19 ` [PATCH 01/19] ftrace: Pass ftrace_ops as third parameter to function trace callback Steven Rostedt
2012-07-21 2:19 ` [PATCH 02/19] ftrace: Consolidate arch dependent functions with list function Steven Rostedt
2012-07-21 2:19 ` [PATCH 03/19] ftrace: Return pt_regs to function trace callback Steven Rostedt
2012-07-21 2:19 ` [PATCH 04/19] ftrace/x86_32: Push ftrace_ops in as 3rd parameter to function tracer Steven Rostedt
2012-07-21 2:19 ` [PATCH 05/19] ftrace/x86: Add separate function to save regs Steven Rostedt
2012-07-21 2:19 ` [PATCH 06/19] ftrace/x86: Add save_regs for i386 function calls Steven Rostedt
2012-07-21 2:19 ` [PATCH 07/19] ftrace/x86_32: Simplify parameter setup for ftrace_regs_caller Steven Rostedt
2012-07-23 4:06 ` Masami Hiramatsu
2012-07-21 2:19 ` [PATCH 08/19] ftrace/x86: Remove function_trace_stop check from graph caller Steven Rostedt
2012-07-21 2:19 ` Steven Rostedt [this message]
2012-07-21 2:19 ` [PATCH 10/19] ftrace: Only compile ftrace selftest if selftests are enabled Steven Rostedt
2012-07-21 2:19 ` [PATCH 11/19] ftrace: Add selftest to test function trace recursion protection Steven Rostedt
2012-07-21 2:19 ` [PATCH 12/19] ftrace: Add selftest to test function save-regs support Steven Rostedt
2012-07-21 2:19 ` [PATCH 13/19] ftrace: add ftrace_set_filter_ip() for address based filter Steven Rostedt
2012-07-21 2:19 ` [PATCH 14/19] kprobes: Inverse taking of module_mutex with kprobe_mutex Steven Rostedt
2012-07-21 2:19 ` [PATCH 15/19] kprobes: cleanup to separate probe-able check Steven Rostedt
2012-07-21 2:19 ` [PATCH 16/19] kprobes: Move locks into appropriate functions Steven Rostedt
2012-07-21 2:20 ` [PATCH 17/19] ftrace: Make ftrace_location() a nop on !DYNAMIC_FTRACE Steven Rostedt
2012-07-21 2:20 ` [PATCH 18/19] kprobes: introduce ftrace based optimization Steven Rostedt
2012-07-21 2:20 ` [PATCH 19/19] kprobes/x86: ftrace based optimization for x86 Steven Rostedt
2012-07-30 15:51 ` [PATCH 00/19] [GIT PULL][v3.6] ftrace: Allow kprobes to work with ftace Steven Rostedt
2012-07-31 14:37 ` [GIT PULL][v3.7] (was: Re: [PATCH 00/19] [GIT PULL][v3.6]) " Steven Rostedt
2012-07-31 15:12 ` [PATCH 00/19] [GIT PULL][v3.6] " Ingo Molnar
2012-08-07 13:23 ` Steven Rostedt
2012-08-21 9:26 ` Ingo Molnar
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=20120721022108.934274530@goodmis.org \
--to=rostedt@goodmis.org \
--cc=akpm@linux-foundation.org \
--cc=fweisbec@gmail.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mingo@elte.hu \
--cc=tglx@linutronix.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox