ftrace: Separate unlimited probes from count limited probes
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>
Sat, 9 Mar 2013 13:56:43 +0000 (08:56 -0500)
committerSteven Rostedt <rostedt@goodmis.org>
Fri, 15 Mar 2013 04:35:59 +0000 (00:35 -0400)
The function tracing probes that trigger traceon or traceoff can be
set to unlimited, or given a count of # of times to execute.

By separating these two types of probes, we can then use the dynamic
ftrace function filtering directly, and remove the brute force
"check if this function called is my probe" routines in ftrace.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
kernel/trace/trace_functions.c

index a88a3e0b0cc2a21b05b25d5d9bc89aaea067c35f..043b2425ae73c5d3ad590503efa2b9d564c8f7cb 100644 (file)
@@ -228,7 +228,7 @@ static int update_count(void **data)
 }
 
 static void
-ftrace_traceon(unsigned long ip, unsigned long parent_ip, void **data)
+ftrace_traceon_count(unsigned long ip, unsigned long parent_ip, void **data)
 {
        if (tracing_is_on())
                return;
@@ -238,7 +238,7 @@ ftrace_traceon(unsigned long ip, unsigned long parent_ip, void **data)
 }
 
 static void
-ftrace_traceoff(unsigned long ip, unsigned long parent_ip, void **data)
+ftrace_traceoff_count(unsigned long ip, unsigned long parent_ip, void **data)
 {
        if (!tracing_is_on())
                return;
@@ -247,10 +247,38 @@ ftrace_traceoff(unsigned long ip, unsigned long parent_ip, void **data)
                tracing_off();
 }
 
+static void
+ftrace_traceon(unsigned long ip, unsigned long parent_ip, void **data)
+{
+       if (tracing_is_on())
+               return;
+
+       tracing_on();
+}
+
+static void
+ftrace_traceoff(unsigned long ip, unsigned long parent_ip, void **data)
+{
+       if (!tracing_is_on())
+               return;
+
+       tracing_off();
+}
+
 static int
 ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
                         struct ftrace_probe_ops *ops, void *data);
 
+static struct ftrace_probe_ops traceon_count_probe_ops = {
+       .func                   = ftrace_traceon_count,
+       .print                  = ftrace_trace_onoff_print,
+};
+
+static struct ftrace_probe_ops traceoff_count_probe_ops = {
+       .func                   = ftrace_traceoff_count,
+       .print                  = ftrace_trace_onoff_print,
+};
+
 static struct ftrace_probe_ops traceon_probe_ops = {
        .func                   = ftrace_traceon,
        .print                  = ftrace_trace_onoff_print,
@@ -269,7 +297,7 @@ ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
 
        seq_printf(m, "%ps:", (void *)ip);
 
-       if (ops == &traceon_probe_ops)
+       if (ops == &traceon_probe_ops || ops == &traceon_count_probe_ops)
                seq_printf(m, "traceon");
        else
                seq_printf(m, "traceoff");
@@ -297,9 +325,9 @@ ftrace_trace_onoff_callback(struct ftrace_hash *hash,
 
        /* we register both traceon and traceoff to this callback */
        if (strcmp(cmd, "traceon") == 0)
-               ops = &traceon_probe_ops;
+               ops = param ? &traceon_count_probe_ops : &traceon_probe_ops;
        else
-               ops = &traceoff_probe_ops;
+               ops = param ? &traceoff_count_probe_ops : &traceoff_probe_ops;
 
        if (glob[0] == '!') {
                unregister_ftrace_function_probe_func(glob+1, ops);