12 #include <linux/module.h>
14 #include <linux/hash.h>
16 #include <asm/local.h>
22 #ifdef CONFIG_BRANCH_TRACER
24 static struct tracer branch_trace;
31 probe_likely_condition(
struct ftrace_branch_data *
f,
int val,
int expect)
36 struct trace_branch *
entry;
60 sizeof(*entry), flags, pc);
67 p = f->file +
strlen(f->file);
68 while (p >= f->file && *p !=
'/')
76 entry->line = f->line;
77 entry->correct = val == expect;
79 if (!filter_check_discard(call, entry, buffer, event))
88 void trace_likely_condition(
struct ftrace_branch_data *f,
int val,
int expect)
90 if (!branch_tracing_enabled)
93 probe_likely_condition(f, val, expect);
105 branch_tracing_enabled++;
111 void disable_branch_tracing(
void)
115 if (!branch_tracing_enabled)
118 branch_tracing_enabled--;
124 static void start_branch_trace(
struct trace_array *tr)
126 enable_branch_tracing(tr);
129 static void stop_branch_trace(
struct trace_array *tr)
131 disable_branch_tracing();
134 static int branch_trace_init(
struct trace_array *tr)
136 start_branch_trace(tr);
140 static void branch_trace_reset(
struct trace_array *tr)
142 stop_branch_trace(tr);
148 struct trace_branch *
field;
153 field->correct ?
" ok " :
" MISS ",
162 static void branch_print_header(
struct seq_file *
s)
164 seq_puts(s,
"# TASK-PID CPU# TIMESTAMP CORRECT"
165 " FUNC:FILE:LINE\n");
171 .
trace = trace_branch_print,
176 .funcs = &trace_branch_funcs,
182 .init = branch_trace_init,
183 .reset = branch_trace_reset,
184 #ifdef CONFIG_FTRACE_SELFTEST
185 .selftest = trace_selftest_startup_branch,
187 .print_header = branch_print_header,
190 __init static int init_branch_tracer(
void)
206 void trace_likely_condition(
struct ftrace_branch_data *f,
int val,
int expect)
219 trace_likely_condition(f, val, expect);
232 static int annotated_branch_stat_headers(
struct seq_file *
m)
237 " ------- --------- - "
243 static inline long get_incorrect_percent(
struct ftrace_branch_data *p)
248 percent = p->incorrect * 100;
249 percent /= p->correct + p->incorrect;
251 percent = p->incorrect ? 100 : -1;
256 static int branch_stat_show(
struct seq_file *
m,
void *
v)
258 struct ftrace_branch_data *p =
v;
263 f = p->file +
strlen(p->file);
264 while (f >= p->file && *f !=
'/')
271 percent = get_incorrect_percent(p);
273 seq_printf(m,
"%8lu %8lu ", p->correct, p->incorrect);
278 seq_printf(m,
"%-30.30s %-20.20s %d\n", p->func, f, p->line);
284 return __start_annotated_branch_profile;
288 annotated_branch_stat_next(
void *v,
int idx)
290 struct ftrace_branch_data *p =
v;
294 if ((
void *)p >= (
void *)__stop_annotated_branch_profile)
300 static int annotated_branch_stat_cmp(
void *
p1,
void *p2)
302 struct ftrace_branch_data *
a =
p1;
303 struct ftrace_branch_data *
b = p2;
305 long percent_a, percent_b;
307 percent_a = get_incorrect_percent(a);
308 percent_b = get_incorrect_percent(b);
310 if (percent_a < percent_b)
312 if (percent_a > percent_b)
315 if (a->incorrect < b->incorrect)
317 if (a->incorrect > b->incorrect)
325 if (a->correct > b->correct)
327 if (a->correct < b->correct)
333 static struct tracer_stat annotated_branch_stats = {
334 .name =
"branch_annotated",
335 .stat_start = annotated_branch_stat_start,
336 .stat_next = annotated_branch_stat_next,
337 .stat_cmp = annotated_branch_stat_cmp,
338 .stat_headers = annotated_branch_stat_headers,
339 .stat_show = branch_stat_show
342 __init static int init_annotated_branch_stats(
void)
349 "annotated branches stats\n");
356 #ifdef CONFIG_PROFILE_ALL_BRANCHES
358 extern unsigned long __start_branch_profile[];
359 extern unsigned long __stop_branch_profile[];
361 static int all_branch_stat_headers(
struct seq_file *m)
366 " ------- --------- - "
374 return __start_branch_profile;
378 all_branch_stat_next(
void *v,
int idx)
380 struct ftrace_branch_data *p =
v;
384 if ((
void *)p >= (
void *)__stop_branch_profile)
391 .
name =
"branch_all",
392 .stat_start = all_branch_stat_start,
393 .stat_next = all_branch_stat_next,
394 .stat_headers = all_branch_stat_headers,
395 .stat_show = branch_stat_show
398 __init static int all_annotated_branch_stats(
void)
405 "all branches stats\n");