Skip to content

Commit

Permalink
tracing/ftrace: separate events tracing and stats tracing engine
Browse files Browse the repository at this point in the history
Impact: tracing's Api change

Currently, the stat tracing depends on the events tracing.
When you switch to a new tracer, the stats files of the previous tracer
will disappear. But it's more scalable to separate those two engines.
This way, we can keep the stat files of one or several tracers when we
want, without bothering of multiple tracer stat files or tracer switching.

To build/destroys its stats files, a tracer just have to call
register_stat_tracer/unregister_stat_tracer everytimes it wants to.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Frederic Weisbecker authored and Ingo Molnar committed Jan 14, 2009
1 parent a14a07b commit 002bb86
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 180 deletions.
2 changes: 0 additions & 2 deletions kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -2353,7 +2353,6 @@ static int tracing_set_tracer(char *buf)
if (ret)
goto out;
}
init_tracer_stat(t);

trace_branch_enable(tr);
out:
Expand Down Expand Up @@ -3218,7 +3217,6 @@ __init static int tracer_alloc_buffers(void)
#else
current_trace = &nop_trace;
#endif
init_tracer_stat(current_trace);
/* All seems OK, enable tracing */
tracing_disabled = 0;

Expand Down
20 changes: 0 additions & 20 deletions kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,24 +334,6 @@ struct tracer_flags {
/* Makes more easy to define a tracer opt */
#define TRACER_OPT(s, b) .name = #s, .bit = b

/*
* If you want to provide a stat file (one-shot statistics), fill
* an iterator with stat_start/stat_next and a stat_show callbacks.
* The others callbacks are optional.
*/
struct tracer_stat {
/* The name of your stat file */
const char *name;
/* Iteration over statistic entries */
void *(*stat_start)(void);
void *(*stat_next)(void *prev, int idx);
/* Compare two entries for sorting (optional) for stats */
int (*stat_cmp)(void *p1, void *p2);
/* Print a stat entry */
int (*stat_show)(struct seq_file *s, void *p);
/* Print the headers of your stat entries */
int (*stat_headers)(struct seq_file *s);
};

/*
* A specific tracer, represented by methods that operate on a trace array:
Expand Down Expand Up @@ -466,8 +448,6 @@ void tracing_start_sched_switch_record(void);
int register_tracer(struct tracer *type);
void unregister_tracer(struct tracer *type);

void init_tracer_stat(struct tracer *trace);

extern unsigned long nsecs_to_usecs(unsigned long nsecs);

extern unsigned long tracing_max_latency;
Expand Down
108 changes: 60 additions & 48 deletions kernel/trace/trace_branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
#include <asm/local.h>

#include "trace.h"
#include "trace_stat.h"
#include "trace_output.h"

static struct tracer branch_trace;

#ifdef CONFIG_BRANCH_TRACER

static struct tracer branch_trace;
static int branch_tracing_enabled __read_mostly;
static DEFINE_MUTEX(branch_tracing_mutex);

Expand Down Expand Up @@ -191,6 +191,30 @@ static struct trace_event trace_branch_event = {
.binary = trace_nop_print,
};

static struct tracer branch_trace __read_mostly =
{
.name = "branch",
.init = branch_trace_init,
.reset = branch_trace_reset,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_branch,
#endif /* CONFIG_FTRACE_SELFTEST */
};

__init static int init_branch_tracer(void)
{
int ret;

ret = register_ftrace_event(&trace_branch_event);
if (!ret) {
printk(KERN_WARNING "Warning: could not register "
"branch events\n");
return 1;
}
return register_tracer(&branch_trace);
}
device_initcall(init_branch_tracer);

#else
static inline
void trace_likely_condition(struct ftrace_branch_data *f, int val, int expect)
Expand Down Expand Up @@ -305,6 +329,29 @@ static int annotated_branch_stat_cmp(void *p1, void *p2)
return 0;
}

static struct tracer_stat annotated_branch_stats = {
.name = "branch_annotated",
.stat_start = annotated_branch_stat_start,
.stat_next = annotated_branch_stat_next,
.stat_cmp = annotated_branch_stat_cmp,
.stat_headers = annotated_branch_stat_headers,
.stat_show = branch_stat_show
};

__init static int init_annotated_branch_stats(void)
{
int ret;

ret = register_stat_tracer(&annotated_branch_stats);
if (!ret) {
printk(KERN_WARNING "Warning: could not register "
"annotated branches stats\n");
return 1;
}
return 0;
}
fs_initcall(init_annotated_branch_stats);

#ifdef CONFIG_PROFILE_ALL_BRANCHES

extern unsigned long __start_branch_profile[];
Expand Down Expand Up @@ -339,60 +386,25 @@ all_branch_stat_next(void *v, int idx)
return p;
}

static struct tracer_stat branch_stats[] = {
{.name = "annotated",
.stat_start = annotated_branch_stat_start,
.stat_next = annotated_branch_stat_next,
.stat_cmp = annotated_branch_stat_cmp,
.stat_headers = annotated_branch_stat_headers,
.stat_show = branch_stat_show},

{.name = "all",
static struct tracer_stat all_branch_stats = {
.name = "branch_all",
.stat_start = all_branch_stat_start,
.stat_next = all_branch_stat_next,
.stat_headers = all_branch_stat_headers,
.stat_show = branch_stat_show},

{ }
};
#else
static struct tracer_stat branch_stats[] = {
{.name = "annotated",
.stat_start = annotated_branch_stat_start,
.stat_next = annotated_branch_stat_next,
.stat_cmp = annotated_branch_stat_cmp,
.stat_headers = annotated_branch_stat_headers,
.stat_show = branch_stat_show},

{ }
.stat_show = branch_stat_show
};
#endif /* CONFIG_PROFILE_ALL_BRANCHES */


static struct tracer branch_trace __read_mostly =
__init static int all_annotated_branch_stats(void)
{
.name = "branch",
#ifdef CONFIG_BRANCH_TRACER
.init = branch_trace_init,
.reset = branch_trace_reset,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_branch,
#endif /* CONFIG_FTRACE_SELFTEST */
#endif
.stats = branch_stats
};

__init static int init_branch_trace(void)
{
#ifdef CONFIG_BRANCH_TRACER
int ret;
ret = register_ftrace_event(&trace_branch_event);

ret = register_stat_tracer(&all_branch_stats);
if (!ret) {
printk(KERN_WARNING "Warning: could not register branch events\n");
printk(KERN_WARNING "Warning: could not register "
"all branches stats\n");
return 1;
}
#endif

return register_tracer(&branch_trace);
return 0;
}
device_initcall(init_branch_trace);
fs_initcall(all_annotated_branch_stats);
#endif /* CONFIG_PROFILE_ALL_BRANCHES */
Loading

0 comments on commit 002bb86

Please sign in to comment.