aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2008-11-21 01:30:54 -0500
committerIngo Molnar <mingo@elte.hu>2008-11-23 05:41:01 -0500
commit2bcd521a684cc94befbe2ce7d5b613c841b0d304 (patch)
tree63bc4dbc52defa27c8cac9e46dddadfcb36c1c7a /kernel/trace
parentbac28bfe42ba98ee67503f78984d1d5e1ebbbb78 (diff)
trace: profile all if conditionals
Impact: feature to profile if statements This patch adds a branch profiler for all if () statements. The results will be found in: /debugfs/tracing/profile_branch For example: miss hit % Function File Line ------- --------- - -------- ---- ---- 0 1 100 x86_64_start_reservations head64.c 127 0 1 100 copy_bootdata head64.c 69 1 0 0 x86_64_start_kernel head64.c 111 32 0 0 set_intr_gate desc.h 319 1 0 0 reserve_ebda_region head.c 51 1 0 0 reserve_ebda_region head.c 47 0 1 100 reserve_ebda_region head.c 42 0 0 X maxcpus main.c 165 Miss means the branch was not taken. Hit means the branch was taken. The percent is the percentage the branch was taken. This adds a significant amount of overhead and should only be used by those analyzing their system. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/Kconfig16
-rw-r--r--kernel/trace/trace_branch.c33
2 files changed, 47 insertions, 2 deletions
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 7e3548705708..61e8cca6ff45 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -173,6 +173,22 @@ config TRACE_BRANCH_PROFILING
173 173
174 Say N if unsure. 174 Say N if unsure.
175 175
176config PROFILE_ALL_BRANCHES
177 bool "Profile all if conditionals"
178 depends on TRACE_BRANCH_PROFILING
179 help
180 This tracer profiles all branch conditions. Every if ()
181 taken in the kernel is recorded whether it hit or miss.
182 The results will be displayed in:
183
184 /debugfs/tracing/profile_branch
185
186 This configuration, when enabled, will impose a great overhead
187 on the system. This should only be enabled when the system
188 is to be analyzed
189
190 Say N if unsure.
191
176config TRACING_BRANCHES 192config TRACING_BRANCHES
177 bool 193 bool
178 help 194 help
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c
index 142acb3b4e00..85792aec64d2 100644
--- a/kernel/trace/trace_branch.c
+++ b/kernel/trace/trace_branch.c
@@ -185,6 +185,7 @@ EXPORT_SYMBOL(ftrace_likely_update);
185struct ftrace_pointer { 185struct ftrace_pointer {
186 void *start; 186 void *start;
187 void *stop; 187 void *stop;
188 int hit;
188}; 189};
189 190
190static void * 191static void *
@@ -223,13 +224,17 @@ static void t_stop(struct seq_file *m, void *p)
223 224
224static int t_show(struct seq_file *m, void *v) 225static int t_show(struct seq_file *m, void *v)
225{ 226{
227 struct ftrace_pointer *fp = m->private;
226 struct ftrace_branch_data *p = v; 228 struct ftrace_branch_data *p = v;
227 const char *f; 229 const char *f;
228 long percent; 230 long percent;
229 231
230 if (v == (void *)1) { 232 if (v == (void *)1) {
231 seq_printf(m, " correct incorrect %% " 233 if (fp->hit)
232 " Function " 234 seq_printf(m, " miss hit %% ");
235 else
236 seq_printf(m, " correct incorrect %% ");
237 seq_printf(m, " Function "
233 " File Line\n" 238 " File Line\n"
234 " ------- --------- - " 239 " ------- --------- - "
235 " -------- " 240 " -------- "
@@ -243,6 +248,9 @@ static int t_show(struct seq_file *m, void *v)
243 f--; 248 f--;
244 f++; 249 f++;
245 250
251 /*
252 * The miss is overlayed on correct, and hit on incorrect.
253 */
246 if (p->correct) { 254 if (p->correct) {
247 percent = p->incorrect * 100; 255 percent = p->incorrect * 100;
248 percent /= p->correct + p->incorrect; 256 percent /= p->correct + p->incorrect;
@@ -284,6 +292,18 @@ static const struct file_operations tracing_branch_fops = {
284 .llseek = seq_lseek, 292 .llseek = seq_lseek,
285}; 293};
286 294
295#ifdef CONFIG_PROFILE_ALL_BRANCHES
296extern unsigned long __start_branch_profile[];
297extern unsigned long __stop_branch_profile[];
298
299static struct ftrace_pointer ftrace_branch_pos = {
300 .start = __start_branch_profile,
301 .stop = __stop_branch_profile,
302 .hit = 1,
303};
304
305#endif /* CONFIG_PROFILE_ALL_BRANCHES */
306
287extern unsigned long __start_annotated_branch_profile[]; 307extern unsigned long __start_annotated_branch_profile[];
288extern unsigned long __stop_annotated_branch_profile[]; 308extern unsigned long __stop_annotated_branch_profile[];
289 309
@@ -306,6 +326,15 @@ static __init int ftrace_branch_init(void)
306 pr_warning("Could not create debugfs " 326 pr_warning("Could not create debugfs "
307 "'profile_annotatet_branch' entry\n"); 327 "'profile_annotatet_branch' entry\n");
308 328
329#ifdef CONFIG_PROFILE_ALL_BRANCHES
330 entry = debugfs_create_file("profile_branch", 0444, d_tracer,
331 &ftrace_branch_pos,
332 &tracing_branch_fops);
333 if (!entry)
334 pr_warning("Could not create debugfs"
335 " 'profile_branch' entry\n");
336#endif
337
309 return 0; 338 return 0;
310} 339}
311 340