diff options
author | Jason Baron <jbaron@redhat.com> | 2009-08-10 16:53:02 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-08-11 14:35:29 -0400 |
commit | f4b5ffccc83c82947f5d9f15d6f1b6edb1b71cd7 (patch) | |
tree | 06ec4a005b40ba0b6039e6c3425dd186486b8c6f /include/linux/syscalls.h | |
parent | 64c12e0444fcc6b75eb49144ba46d43dbdc6bc8f (diff) |
tracing: Add perf counter support for syscalls tracing
The perf counter support is automated for usual trace events. But we
have to define specific callbacks for this to handle syscalls trace
events
Make 'perf stat -e syscalls:sys_enter_blah' work with syscall style
tracepoints.
Signed-off-by: Jason Baron <jbaron@redhat.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Jiaying Zhang <jiayingz@google.com>
Cc: Martin Bligh <mbligh@google.com>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'include/linux/syscalls.h')
-rw-r--r-- | include/linux/syscalls.h | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index ce4b01c658eb..5541e75e140a 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -98,6 +98,53 @@ struct perf_counter_attr; | |||
98 | #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) | 98 | #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) |
99 | #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) | 99 | #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) |
100 | 100 | ||
101 | #ifdef CONFIG_EVENT_PROFILE | ||
102 | #define TRACE_SYS_ENTER_PROFILE(sname) \ | ||
103 | static int prof_sysenter_enable_##sname(struct ftrace_event_call *event_call) \ | ||
104 | { \ | ||
105 | int ret = 0; \ | ||
106 | if (!atomic_inc_return(&event_enter_##sname.profile_count)) \ | ||
107 | ret = reg_prof_syscall_enter("sys"#sname); \ | ||
108 | return ret; \ | ||
109 | } \ | ||
110 | \ | ||
111 | static void prof_sysenter_disable_##sname(struct ftrace_event_call *event_call)\ | ||
112 | { \ | ||
113 | if (atomic_add_negative(-1, &event_enter_##sname.profile_count)) \ | ||
114 | unreg_prof_syscall_enter("sys"#sname); \ | ||
115 | } | ||
116 | |||
117 | #define TRACE_SYS_EXIT_PROFILE(sname) \ | ||
118 | static int prof_sysexit_enable_##sname(struct ftrace_event_call *event_call) \ | ||
119 | { \ | ||
120 | int ret = 0; \ | ||
121 | if (!atomic_inc_return(&event_exit_##sname.profile_count)) \ | ||
122 | ret = reg_prof_syscall_exit("sys"#sname); \ | ||
123 | return ret; \ | ||
124 | } \ | ||
125 | \ | ||
126 | static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \ | ||
127 | { \ | ||
128 | if (atomic_add_negative(-1, &event_exit_##sname.profile_count)) \ | ||
129 | unreg_prof_syscall_exit("sys"#sname); \ | ||
130 | } | ||
131 | |||
132 | #define TRACE_SYS_ENTER_PROFILE_INIT(sname) \ | ||
133 | .profile_count = ATOMIC_INIT(-1), \ | ||
134 | .profile_enable = prof_sysenter_enable_##sname, \ | ||
135 | .profile_disable = prof_sysenter_disable_##sname, | ||
136 | |||
137 | #define TRACE_SYS_EXIT_PROFILE_INIT(sname) \ | ||
138 | .profile_count = ATOMIC_INIT(-1), \ | ||
139 | .profile_enable = prof_sysexit_enable_##sname, \ | ||
140 | .profile_disable = prof_sysexit_disable_##sname, | ||
141 | #else | ||
142 | #define TRACE_SYS_ENTER_PROFILE(sname) | ||
143 | #define TRACE_SYS_ENTER_PROFILE_INIT(sname) | ||
144 | #define TRACE_SYS_EXIT_PROFILE(sname) | ||
145 | #define TRACE_SYS_EXIT_PROFILE_INIT(sname) | ||
146 | #endif | ||
147 | |||
101 | #ifdef CONFIG_FTRACE_SYSCALLS | 148 | #ifdef CONFIG_FTRACE_SYSCALLS |
102 | #define __SC_STR_ADECL1(t, a) #a | 149 | #define __SC_STR_ADECL1(t, a) #a |
103 | #define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__) | 150 | #define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__) |
@@ -113,7 +160,6 @@ struct perf_counter_attr; | |||
113 | #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) | 160 | #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) |
114 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) | 161 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) |
115 | 162 | ||
116 | |||
117 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ | 163 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ |
118 | static struct ftrace_event_call event_enter_##sname; \ | 164 | static struct ftrace_event_call event_enter_##sname; \ |
119 | struct trace_event enter_syscall_print_##sname = { \ | 165 | struct trace_event enter_syscall_print_##sname = { \ |
@@ -134,6 +180,7 @@ struct perf_counter_attr; | |||
134 | init_preds(&event_enter_##sname); \ | 180 | init_preds(&event_enter_##sname); \ |
135 | return 0; \ | 181 | return 0; \ |
136 | } \ | 182 | } \ |
183 | TRACE_SYS_ENTER_PROFILE(sname); \ | ||
137 | static struct ftrace_event_call __used \ | 184 | static struct ftrace_event_call __used \ |
138 | __attribute__((__aligned__(4))) \ | 185 | __attribute__((__aligned__(4))) \ |
139 | __attribute__((section("_ftrace_events"))) \ | 186 | __attribute__((section("_ftrace_events"))) \ |
@@ -145,6 +192,7 @@ struct perf_counter_attr; | |||
145 | .regfunc = reg_event_syscall_enter, \ | 192 | .regfunc = reg_event_syscall_enter, \ |
146 | .unregfunc = unreg_event_syscall_enter, \ | 193 | .unregfunc = unreg_event_syscall_enter, \ |
147 | .data = "sys"#sname, \ | 194 | .data = "sys"#sname, \ |
195 | TRACE_SYS_ENTER_PROFILE_INIT(sname) \ | ||
148 | } | 196 | } |
149 | 197 | ||
150 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ | 198 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ |
@@ -167,6 +215,7 @@ struct perf_counter_attr; | |||
167 | init_preds(&event_exit_##sname); \ | 215 | init_preds(&event_exit_##sname); \ |
168 | return 0; \ | 216 | return 0; \ |
169 | } \ | 217 | } \ |
218 | TRACE_SYS_EXIT_PROFILE(sname); \ | ||
170 | static struct ftrace_event_call __used \ | 219 | static struct ftrace_event_call __used \ |
171 | __attribute__((__aligned__(4))) \ | 220 | __attribute__((__aligned__(4))) \ |
172 | __attribute__((section("_ftrace_events"))) \ | 221 | __attribute__((section("_ftrace_events"))) \ |
@@ -178,6 +227,7 @@ struct perf_counter_attr; | |||
178 | .regfunc = reg_event_syscall_exit, \ | 227 | .regfunc = reg_event_syscall_exit, \ |
179 | .unregfunc = unreg_event_syscall_exit, \ | 228 | .unregfunc = unreg_event_syscall_exit, \ |
180 | .data = "sys"#sname, \ | 229 | .data = "sys"#sname, \ |
230 | TRACE_SYS_EXIT_PROFILE_INIT(sname) \ | ||
181 | } | 231 | } |
182 | 232 | ||
183 | #define SYSCALL_METADATA(sname, nb) \ | 233 | #define SYSCALL_METADATA(sname, nb) \ |