diff options
author | Steven Rostedt <srostedt@redhat.com> | 2008-11-21 01:30:54 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-23 05:41:01 -0500 |
commit | 2bcd521a684cc94befbe2ce7d5b613c841b0d304 (patch) | |
tree | 63bc4dbc52defa27c8cac9e46dddadfcb36c1c7a /include | |
parent | bac28bfe42ba98ee67503f78984d1d5e1ebbbb78 (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 'include')
-rw-r--r-- | include/asm-generic/vmlinux.lds.h | 11 | ||||
-rw-r--r-- | include/linux/compiler.h | 38 |
2 files changed, 46 insertions, 3 deletions
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 8bccb49981e5..eba835a2c2cd 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -53,6 +53,14 @@ | |||
53 | #define LIKELY_PROFILE() | 53 | #define LIKELY_PROFILE() |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | #ifdef CONFIG_PROFILE_ALL_BRANCHES | ||
57 | #define BRANCH_PROFILE() VMLINUX_SYMBOL(__start_branch_profile) = .; \ | ||
58 | *(_ftrace_branch) \ | ||
59 | VMLINUX_SYMBOL(__stop_branch_profile) = .; | ||
60 | #else | ||
61 | #define BRANCH_PROFILE() | ||
62 | #endif | ||
63 | |||
56 | /* .data section */ | 64 | /* .data section */ |
57 | #define DATA_DATA \ | 65 | #define DATA_DATA \ |
58 | *(.data) \ | 66 | *(.data) \ |
@@ -72,7 +80,8 @@ | |||
72 | VMLINUX_SYMBOL(__start___tracepoints) = .; \ | 80 | VMLINUX_SYMBOL(__start___tracepoints) = .; \ |
73 | *(__tracepoints) \ | 81 | *(__tracepoints) \ |
74 | VMLINUX_SYMBOL(__stop___tracepoints) = .; \ | 82 | VMLINUX_SYMBOL(__stop___tracepoints) = .; \ |
75 | LIKELY_PROFILE() | 83 | LIKELY_PROFILE() \ |
84 | BRANCH_PROFILE() | ||
76 | 85 | ||
77 | #define RO_DATA(align) \ | 86 | #define RO_DATA(align) \ |
78 | . = ALIGN((align)); \ | 87 | . = ALIGN((align)); \ |
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 0628a2013fae..ea7c6be354b7 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
@@ -63,8 +63,16 @@ struct ftrace_branch_data { | |||
63 | const char *func; | 63 | const char *func; |
64 | const char *file; | 64 | const char *file; |
65 | unsigned line; | 65 | unsigned line; |
66 | unsigned long correct; | 66 | union { |
67 | unsigned long incorrect; | 67 | struct { |
68 | unsigned long correct; | ||
69 | unsigned long incorrect; | ||
70 | }; | ||
71 | struct { | ||
72 | unsigned long miss; | ||
73 | unsigned long hit; | ||
74 | }; | ||
75 | }; | ||
68 | }; | 76 | }; |
69 | 77 | ||
70 | /* | 78 | /* |
@@ -103,6 +111,32 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); | |||
103 | # ifndef unlikely | 111 | # ifndef unlikely |
104 | # define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0)) | 112 | # define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0)) |
105 | # endif | 113 | # endif |
114 | |||
115 | #ifdef CONFIG_PROFILE_ALL_BRANCHES | ||
116 | /* | ||
117 | * "Define 'is'", Bill Clinton | ||
118 | * "Define 'if'", Steven Rostedt | ||
119 | */ | ||
120 | #define if(cond) if (__builtin_constant_p((cond)) ? !!(cond) : \ | ||
121 | ({ \ | ||
122 | int ______r; \ | ||
123 | static struct ftrace_branch_data \ | ||
124 | __attribute__((__aligned__(4))) \ | ||
125 | __attribute__((section("_ftrace_branch"))) \ | ||
126 | ______f = { \ | ||
127 | .func = __func__, \ | ||
128 | .file = __FILE__, \ | ||
129 | .line = __LINE__, \ | ||
130 | }; \ | ||
131 | ______r = !!(cond); \ | ||
132 | if (______r) \ | ||
133 | ______f.hit++; \ | ||
134 | else \ | ||
135 | ______f.miss++; \ | ||
136 | ______r; \ | ||
137 | })) | ||
138 | #endif /* CONFIG_PROFILE_ALL_BRANCHES */ | ||
139 | |||
106 | #else | 140 | #else |
107 | # define likely(x) __builtin_expect(!!(x), 1) | 141 | # define likely(x) __builtin_expect(!!(x), 1) |
108 | # define unlikely(x) __builtin_expect(!!(x), 0) | 142 | # define unlikely(x) __builtin_expect(!!(x), 0) |