Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 134e6a03 authored by Steven Rostedt (VMware)'s avatar Steven Rostedt (VMware)
Browse files

tracing: Show number of constants profiled in likely profiler



Now that constants are traced, it is useful to see the number of constants
that are traced in the likely/unlikely profiler in order to know if they
should be ignored or not.

The likely/unlikely will display a number after the "correct" number if a
"constant" count exists.

Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent d45ae1f7
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -101,13 +101,18 @@ struct ftrace_branch_data {
	};
};

struct ftrace_likely_data {
	struct ftrace_branch_data	data;
	unsigned long			constant;
};

/*
 * Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code
 * to disable branch tracing on a per file basis.
 */
#if defined(CONFIG_TRACE_BRANCH_PROFILING) \
    && !defined(DISABLE_BRANCH_PROFILING) && !defined(__CHECKER__)
void ftrace_likely_update(struct ftrace_branch_data *f, int val,
void ftrace_likely_update(struct ftrace_likely_data *f, int val,
			  int expect, int is_constant);

#define likely_notrace(x)	__builtin_expect(!!(x), 1)
@@ -115,13 +120,13 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val,

#define __branch_check__(x, expect, is_constant) ({			\
			int ______r;					\
			static struct ftrace_branch_data		\
			static struct ftrace_likely_data		\
				__attribute__((__aligned__(4)))		\
				__attribute__((section("_ftrace_annotated_branch"))) \
				______f = {				\
				.func = __func__,			\
				.file = __FILE__,			\
				.line = __LINE__,			\
				.data.func = __func__,			\
				.data.file = __FILE__,			\
				.data.line = __LINE__,			\
			};						\
			______r = __builtin_expect(!!(x), expect);	\
			ftrace_likely_update(&______f, ______r,		\
+55 −13
Original line number Diff line number Diff line
@@ -200,25 +200,27 @@ void trace_likely_condition(struct ftrace_branch_data *f, int val, int expect)
}
#endif /* CONFIG_BRANCH_TRACER */

void ftrace_likely_update(struct ftrace_branch_data *f, int val,
void ftrace_likely_update(struct ftrace_likely_data *f, int val,
			  int expect, int is_constant)
{
	/* A constant is always correct */
	if (is_constant)
	if (is_constant) {
		f->constant++;
		val = expect;
	}
	/*
	 * I would love to have a trace point here instead, but the
	 * trace point code is so inundated with unlikely and likely
	 * conditions that the recursive nightmare that exists is too
	 * much to try to get working. At least for now.
	 */
	trace_likely_condition(f, val, expect);
	trace_likely_condition(&f->data, val, expect);

	/* FIXME: Make this atomic! */
	if (val == expect)
		f->correct++;
		f->data.correct++;
	else
		f->incorrect++;
		f->data.incorrect++;
}
EXPORT_SYMBOL(ftrace_likely_update);

@@ -249,29 +251,60 @@ static inline long get_incorrect_percent(struct ftrace_branch_data *p)
	return percent;
}

static int branch_stat_show(struct seq_file *m, void *v)
static const char *branch_stat_process_file(struct ftrace_branch_data *p)
{
	struct ftrace_branch_data *p = v;
	const char *f;
	long percent;

	/* Only print the file, not the path */
	f = p->file + strlen(p->file);
	while (f >= p->file && *f != '/')
		f--;
	f++;
	return ++f;
}

static void branch_stat_show(struct seq_file *m,
			     struct ftrace_branch_data *p, const char *f)
{
	long percent;

	/*
	 * The miss is overlayed on correct, and hit on incorrect.
	 */
	percent = get_incorrect_percent(p);

	seq_printf(m, "%8lu %8lu ",  p->correct, p->incorrect);
	if (percent < 0)
		seq_puts(m, "  X ");
	else
		seq_printf(m, "%3ld ", percent);

	seq_printf(m, "%-30.30s %-20.20s %d\n", p->func, f, p->line);
}

static int branch_stat_show_normal(struct seq_file *m,
				   struct ftrace_branch_data *p, const char *f)
{
	seq_printf(m, "%8lu %8lu ",  p->correct, p->incorrect);
	branch_stat_show(m, p, f);
	return 0;
}

static int annotate_branch_stat_show(struct seq_file *m, void *v)
{
	struct ftrace_likely_data *p = v;
	const char *f;
	int l;

	f = branch_stat_process_file(&p->data);

	if (!p->constant)
		return branch_stat_show_normal(m, &p->data, f);

	l = snprintf(NULL, 0, "/%lu", p->constant);
	l = l > 8 ? 0 : 8 - l;

	seq_printf(m, "%8lu/%lu %*lu ",
		   p->data.correct, p->constant, l, p->data.incorrect);
	branch_stat_show(m, &p->data, f);
	return 0;
}

@@ -283,7 +316,7 @@ static void *annotated_branch_stat_start(struct tracer_stat *trace)
static void *
annotated_branch_stat_next(void *v, int idx)
{
	struct ftrace_branch_data *p = v;
	struct ftrace_likely_data *p = v;

	++p;

@@ -332,7 +365,7 @@ static struct tracer_stat annotated_branch_stats = {
	.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 = annotate_branch_stat_show
};

__init static int init_annotated_branch_stats(void)
@@ -383,12 +416,21 @@ all_branch_stat_next(void *v, int idx)
	return p;
}

static int all_branch_stat_show(struct seq_file *m, void *v)
{
	struct ftrace_branch_data *p = v;
	const char *f;

	f = branch_stat_process_file(p);
	return branch_stat_show_normal(m, p, f);
}

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
	.stat_show = all_branch_stat_show
};

__init static int all_annotated_branch_stats(void)