diff options
| author | Jason Baron <jbaron@redhat.com> | 2009-08-10 16:52:47 -0400 |
|---|---|---|
| committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-08-11 14:35:28 -0400 |
| commit | fb34a08c3469b2be9eae626ccb96476b4687b810 (patch) | |
| tree | f308cd109de2c967a1f8bd485eb9c398992a9414 /include/linux | |
| parent | 69fd4f0eb2ececbf8ade55e31a933e174965745e (diff) | |
tracing: Add trace events for each syscall entry/exit
Layer Frederic's syscall tracer on tracepoints. We create trace events
via hooking into the SYSCALL_DEFINE macros. This allows us to
individually toggle syscall entry and exit points on/off.
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')
| -rw-r--r-- | include/linux/syscalls.h | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 80de7003d8c2..5e5b4d33a31c 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
| @@ -64,6 +64,7 @@ struct perf_counter_attr; | |||
| 64 | #include <linux/sem.h> | 64 | #include <linux/sem.h> |
| 65 | #include <asm/siginfo.h> | 65 | #include <asm/siginfo.h> |
| 66 | #include <asm/signal.h> | 66 | #include <asm/signal.h> |
| 67 | #include <linux/unistd.h> | ||
| 67 | #include <linux/quota.h> | 68 | #include <linux/quota.h> |
| 68 | #include <linux/key.h> | 69 | #include <linux/key.h> |
| 69 | #include <trace/syscall.h> | 70 | #include <trace/syscall.h> |
| @@ -112,6 +113,59 @@ struct perf_counter_attr; | |||
| 112 | #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) | 113 | #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) |
| 113 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) | 114 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) |
| 114 | 115 | ||
| 116 | |||
| 117 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ | ||
| 118 | static struct ftrace_event_call event_enter_##sname; \ | ||
| 119 | static int init_enter_##sname(void) \ | ||
| 120 | { \ | ||
| 121 | int num; \ | ||
| 122 | num = syscall_name_to_nr("sys"#sname); \ | ||
| 123 | if (num < 0) \ | ||
| 124 | return -ENOSYS; \ | ||
| 125 | register_ftrace_event(&event_syscall_enter); \ | ||
| 126 | INIT_LIST_HEAD(&event_enter_##sname.fields); \ | ||
| 127 | init_preds(&event_enter_##sname); \ | ||
| 128 | return 0; \ | ||
| 129 | } \ | ||
| 130 | static struct ftrace_event_call __used \ | ||
| 131 | __attribute__((__aligned__(4))) \ | ||
| 132 | __attribute__((section("_ftrace_events"))) \ | ||
| 133 | event_enter_##sname = { \ | ||
| 134 | .name = "sys_enter"#sname, \ | ||
| 135 | .system = "syscalls", \ | ||
| 136 | .event = &event_syscall_enter, \ | ||
| 137 | .raw_init = init_enter_##sname, \ | ||
| 138 | .regfunc = reg_event_syscall_enter, \ | ||
| 139 | .unregfunc = unreg_event_syscall_enter, \ | ||
| 140 | .data = "sys"#sname, \ | ||
| 141 | } | ||
| 142 | |||
| 143 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ | ||
| 144 | static struct ftrace_event_call event_exit_##sname; \ | ||
| 145 | static int init_exit_##sname(void) \ | ||
| 146 | { \ | ||
| 147 | int num; \ | ||
| 148 | num = syscall_name_to_nr("sys"#sname); \ | ||
| 149 | if (num < 0) \ | ||
| 150 | return -ENOSYS; \ | ||
| 151 | register_ftrace_event(&event_syscall_exit); \ | ||
| 152 | INIT_LIST_HEAD(&event_exit_##sname.fields); \ | ||
| 153 | init_preds(&event_exit_##sname); \ | ||
| 154 | return 0; \ | ||
| 155 | } \ | ||
| 156 | static struct ftrace_event_call __used \ | ||
| 157 | __attribute__((__aligned__(4))) \ | ||
| 158 | __attribute__((section("_ftrace_events"))) \ | ||
| 159 | event_exit_##sname = { \ | ||
| 160 | .name = "sys_exit"#sname, \ | ||
| 161 | .system = "syscalls", \ | ||
| 162 | .event = &event_syscall_exit, \ | ||
| 163 | .raw_init = init_exit_##sname, \ | ||
| 164 | .regfunc = reg_event_syscall_exit, \ | ||
| 165 | .unregfunc = unreg_event_syscall_exit, \ | ||
| 166 | .data = "sys"#sname, \ | ||
| 167 | } | ||
| 168 | |||
| 115 | #define SYSCALL_METADATA(sname, nb) \ | 169 | #define SYSCALL_METADATA(sname, nb) \ |
| 116 | static const struct syscall_metadata __used \ | 170 | static const struct syscall_metadata __used \ |
| 117 | __attribute__((__aligned__(4))) \ | 171 | __attribute__((__aligned__(4))) \ |
| @@ -121,7 +175,9 @@ struct perf_counter_attr; | |||
| 121 | .nb_args = nb, \ | 175 | .nb_args = nb, \ |
| 122 | .types = types_##sname, \ | 176 | .types = types_##sname, \ |
| 123 | .args = args_##sname, \ | 177 | .args = args_##sname, \ |
| 124 | } | 178 | }; \ |
| 179 | SYSCALL_TRACE_ENTER_EVENT(sname); \ | ||
| 180 | SYSCALL_TRACE_EXIT_EVENT(sname); | ||
| 125 | 181 | ||
| 126 | #define SYSCALL_DEFINE0(sname) \ | 182 | #define SYSCALL_DEFINE0(sname) \ |
| 127 | static const struct syscall_metadata __used \ | 183 | static const struct syscall_metadata __used \ |
| @@ -131,8 +187,9 @@ struct perf_counter_attr; | |||
| 131 | .name = "sys_"#sname, \ | 187 | .name = "sys_"#sname, \ |
| 132 | .nb_args = 0, \ | 188 | .nb_args = 0, \ |
| 133 | }; \ | 189 | }; \ |
| 190 | SYSCALL_TRACE_ENTER_EVENT(_##sname); \ | ||
| 191 | SYSCALL_TRACE_EXIT_EVENT(_##sname); \ | ||
| 134 | asmlinkage long sys_##sname(void) | 192 | asmlinkage long sys_##sname(void) |
| 135 | |||
| 136 | #else | 193 | #else |
| 137 | #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) | 194 | #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) |
| 138 | #endif | 195 | #endif |
