All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Ingo Molnar <mingo@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Frederic Weisbecker <fweisbec@gmail.com>
Subject: [for-next][PATCH 13/20] tracing: Add function probe to trigger stack traces
Date: Fri, 15 Mar 2013 15:39:48 -0400	[thread overview]
Message-ID: <20130315195124.516791964@goodmis.org> (raw)
In-Reply-To: 20130315193935.359219613@goodmis.org

[-- Attachment #1: Type: text/plain, Size: 7565 bytes --]

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

Add a function probe that will cause a stack trace to be traced in
the ring buffer when the given function(s) are called.

format is:

 <function>:stacktrace[:<count>]

 echo 'schedule:stacktrace' > /debug/tracing/set_ftrace_filter
 cat /debug/tracing/trace_pipe
     kworker/2:0-4329  [002] ...2  2933.558007: <stack trace>
 => kthread
 => ret_from_fork
          <idle>-0     [000] .N.2  2933.558019: <stack trace>
 => rest_init
 => start_kernel
 => x86_64_start_reservations
 => x86_64_start_kernel
     kworker/2:0-4329  [002] ...2  2933.558109: <stack trace>
 => kthread
 => ret_from_fork
[...]

This can be set to only trace a specific amount of times:

 echo 'schedule:stacktrace:3' > /debug/tracing/set_ftrace_filter
 cat /debug/tracing/trace_pipe
           <...>-58    [003] ...2   841.801694: <stack trace>
 => kthread
 => ret_from_fork
          <idle>-0     [001] .N.2   841.801697: <stack trace>
 => start_secondary
           <...>-2059  [001] ...2   841.801736: <stack trace>
 => wait_for_common
 => wait_for_completion
 => flush_work
 => tty_flush_to_ldisc
 => input_available_p
 => n_tty_poll
 => tty_poll
 => do_select
 => core_sys_select
 => sys_select
 => system_call_fastpath

To remove these:

 echo '!schedule:stacktrace' > /debug/tracing/set_ftrace_filter
 echo '!schedule:stacktrace:0' > /debug/tracing/set_ftrace_filter

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/trace/trace_functions.c |  150 ++++++++++++++++++++++++++++++----------
 1 file changed, 115 insertions(+), 35 deletions(-)

diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 043b242..c4d6d71 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -265,56 +265,103 @@ ftrace_traceoff(unsigned long ip, unsigned long parent_ip, void **data)
 	tracing_off();
 }
 
+/*
+ * Skip 4:
+ *   ftrace_stacktrace()
+ *   function_trace_probe_call()
+ *   ftrace_ops_list_func()
+ *   ftrace_call()
+ */
+#define STACK_SKIP 4
+
+static void
+ftrace_stacktrace(unsigned long ip, unsigned long parent_ip, void **data)
+{
+	trace_dump_stack(STACK_SKIP);
+}
+
+static void
+ftrace_stacktrace_count(unsigned long ip, unsigned long parent_ip, void **data)
+{
+	if (!tracing_is_on())
+		return;
+
+	if (update_count(data))
+		trace_dump_stack(STACK_SKIP);
+}
+
 static int
-ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
-			 struct ftrace_probe_ops *ops, void *data);
+ftrace_probe_print(const char *name, struct seq_file *m,
+		   unsigned long ip, void *data)
+{
+	long count = (long)data;
+
+	seq_printf(m, "%ps:%s", (void *)ip, name);
+
+	if (count == -1)
+		seq_printf(m, ":unlimited\n");
+	else
+		seq_printf(m, ":count=%ld\n", count);
+
+	return 0;
+}
+
+static int
+ftrace_traceon_print(struct seq_file *m, unsigned long ip,
+			 struct ftrace_probe_ops *ops, void *data)
+{
+	return ftrace_probe_print("traceon", m, ip, data);
+}
+
+static int
+ftrace_traceoff_print(struct seq_file *m, unsigned long ip,
+			 struct ftrace_probe_ops *ops, void *data)
+{
+	return ftrace_probe_print("traceoff", m, ip, data);
+}
+
+static int
+ftrace_stacktrace_print(struct seq_file *m, unsigned long ip,
+			struct ftrace_probe_ops *ops, void *data)
+{
+	return ftrace_probe_print("stacktrace", m, ip, data);
+}
 
 static struct ftrace_probe_ops traceon_count_probe_ops = {
 	.func			= ftrace_traceon_count,
-	.print			= ftrace_trace_onoff_print,
+	.print			= ftrace_traceon_print,
 };
 
 static struct ftrace_probe_ops traceoff_count_probe_ops = {
 	.func			= ftrace_traceoff_count,
-	.print			= ftrace_trace_onoff_print,
+	.print			= ftrace_traceoff_print,
+};
+
+static struct ftrace_probe_ops stacktrace_count_probe_ops = {
+	.func			= ftrace_stacktrace_count,
+	.print			= ftrace_stacktrace_print,
 };
 
 static struct ftrace_probe_ops traceon_probe_ops = {
 	.func			= ftrace_traceon,
-	.print			= ftrace_trace_onoff_print,
+	.print			= ftrace_traceon_print,
 };
 
 static struct ftrace_probe_ops traceoff_probe_ops = {
 	.func			= ftrace_traceoff,
-	.print			= ftrace_trace_onoff_print,
+	.print			= ftrace_traceoff_print,
 };
 
-static int
-ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
-			 struct ftrace_probe_ops *ops, void *data)
-{
-	long count = (long)data;
-
-	seq_printf(m, "%ps:", (void *)ip);
-
-	if (ops == &traceon_probe_ops || ops == &traceon_count_probe_ops)
-		seq_printf(m, "traceon");
-	else
-		seq_printf(m, "traceoff");
-
-	if (count == -1)
-		seq_printf(m, ":unlimited\n");
-	else
-		seq_printf(m, ":count=%ld\n", count);
-
-	return 0;
-}
+static struct ftrace_probe_ops stacktrace_probe_ops = {
+	.func			= ftrace_stacktrace,
+	.print			= ftrace_stacktrace_print,
+};
 
 static int
-ftrace_trace_onoff_callback(struct ftrace_hash *hash,
-			    char *glob, char *cmd, char *param, int enable)
+ftrace_trace_probe_callback(struct ftrace_probe_ops *ops,
+			    struct ftrace_hash *hash, char *glob,
+			    char *cmd, char *param, int enable)
 {
-	struct ftrace_probe_ops *ops;
 	void *count = (void *)-1;
 	char *number;
 	int ret;
@@ -323,12 +370,6 @@ ftrace_trace_onoff_callback(struct ftrace_hash *hash,
 	if (!enable)
 		return -EINVAL;
 
-	/* we register both traceon and traceoff to this callback */
-	if (strcmp(cmd, "traceon") == 0)
-		ops = param ? &traceon_count_probe_ops : &traceon_probe_ops;
-	else
-		ops = param ? &traceoff_count_probe_ops : &traceoff_probe_ops;
-
 	if (glob[0] == '!') {
 		unregister_ftrace_function_probe_func(glob+1, ops);
 		return 0;
@@ -356,6 +397,34 @@ ftrace_trace_onoff_callback(struct ftrace_hash *hash,
 	return ret < 0 ? ret : 0;
 }
 
+static int
+ftrace_trace_onoff_callback(struct ftrace_hash *hash,
+			    char *glob, char *cmd, char *param, int enable)
+{
+	struct ftrace_probe_ops *ops;
+
+	/* we register both traceon and traceoff to this callback */
+	if (strcmp(cmd, "traceon") == 0)
+		ops = param ? &traceon_count_probe_ops : &traceon_probe_ops;
+	else
+		ops = param ? &traceoff_count_probe_ops : &traceoff_probe_ops;
+
+	return ftrace_trace_probe_callback(ops, hash, glob, cmd,
+					   param, enable);
+}
+
+static int
+ftrace_stacktrace_callback(struct ftrace_hash *hash,
+			   char *glob, char *cmd, char *param, int enable)
+{
+	struct ftrace_probe_ops *ops;
+
+	ops = param ? &stacktrace_count_probe_ops : &stacktrace_probe_ops;
+
+	return ftrace_trace_probe_callback(ops, hash, glob, cmd,
+					   param, enable);
+}
+
 static struct ftrace_func_command ftrace_traceon_cmd = {
 	.name			= "traceon",
 	.func			= ftrace_trace_onoff_callback,
@@ -366,6 +435,11 @@ static struct ftrace_func_command ftrace_traceoff_cmd = {
 	.func			= ftrace_trace_onoff_callback,
 };
 
+static struct ftrace_func_command ftrace_stacktrace_cmd = {
+	.name			= "stacktrace",
+	.func			= ftrace_stacktrace_callback,
+};
+
 static int __init init_func_cmd_traceon(void)
 {
 	int ret;
@@ -377,6 +451,12 @@ static int __init init_func_cmd_traceon(void)
 	ret = register_ftrace_command(&ftrace_traceon_cmd);
 	if (ret)
 		unregister_ftrace_command(&ftrace_traceoff_cmd);
+
+	ret = register_ftrace_command(&ftrace_stacktrace_cmd);
+	if (ret) {
+		unregister_ftrace_command(&ftrace_traceoff_cmd);
+		unregister_ftrace_command(&ftrace_traceon_cmd);
+	}
 	return ret;
 }
 #else
-- 
1.7.10.4



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

  parent reply	other threads:[~2013-03-15 19:53 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-15 19:39 [for-next][PATCH 00/20] tracing: function triggers, stack tracer fixes, clocks and documenation Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 01/20] tracing: Consolidate updating of count for traceon/off Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 02/20] tracing: Consolidate ftrace_trace_onoff_unreg() into callback Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 03/20] ftrace: Separate unlimited probes from count limited probes Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 04/20] ftrace: Fix function probe to only enable needed functions Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 05/20] tracing: Add alloc/free_snapshot() to replace duplicate code Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 06/20] tracing: Add snapshot trigger to function probes Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 07/20] tracing: Fix comments for ftrace_event_file/call flags Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 08/20] ftrace: Clean up function probe methods Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 09/20] ftrace: Use manual free after synchronize_sched() not call_rcu_sched() Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 10/20] tracing: Add a way to soft disable trace events Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 11/20] tracing: Add function probe triggers to enable/disable events Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 12/20] tracing: Add skip argument to trace_dump_stack() Steven Rostedt
2013-03-15 19:39 ` Steven Rostedt [this message]
2013-03-15 19:39 ` [for-next][PATCH 14/20] tracing: Use stack of calling function for stack tracer Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 15/20] tracing: Fix stack tracer with fentry use Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 16/20] tracing: Remove most or all of stack tracer stack size from stack_max_size Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 17/20] tracing: Add function-trace option to disable function tracing of latency tracers Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 18/20] tracing: Add "uptime" trace clock that uses jiffies Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 19/20] tracing: Add "perf" trace_clock Steven Rostedt
2013-03-15 19:39 ` [for-next][PATCH 20/20] tracing: Bring Documentation/trace/ftrace.txt up to date Steven Rostedt

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=20130315195124.516791964@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=akpm@linux-foundation.org \
    --cc=fweisbec@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    /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.