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 | |
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')
-rw-r--r-- | include/linux/syscalls.h | 61 | ||||
-rw-r--r-- | include/trace/syscall.h | 18 |
2 files changed, 68 insertions, 11 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 |
diff --git a/include/trace/syscall.h b/include/trace/syscall.h index 3951d774de18..73fb8b4a9955 100644 --- a/include/trace/syscall.h +++ b/include/trace/syscall.h | |||
@@ -2,6 +2,8 @@ | |||
2 | #define _TRACE_SYSCALL_H | 2 | #define _TRACE_SYSCALL_H |
3 | 3 | ||
4 | #include <linux/tracepoint.h> | 4 | #include <linux/tracepoint.h> |
5 | #include <linux/unistd.h> | ||
6 | #include <linux/ftrace_event.h> | ||
5 | 7 | ||
6 | #include <asm/ptrace.h> | 8 | #include <asm/ptrace.h> |
7 | 9 | ||
@@ -40,15 +42,13 @@ struct syscall_metadata { | |||
40 | 42 | ||
41 | #ifdef CONFIG_FTRACE_SYSCALLS | 43 | #ifdef CONFIG_FTRACE_SYSCALLS |
42 | extern struct syscall_metadata *syscall_nr_to_meta(int nr); | 44 | extern struct syscall_metadata *syscall_nr_to_meta(int nr); |
43 | extern void start_ftrace_syscalls(void); | 45 | extern int syscall_name_to_nr(char *name); |
44 | extern void stop_ftrace_syscalls(void); | 46 | extern struct trace_event event_syscall_enter; |
45 | extern void ftrace_syscall_enter(struct pt_regs *regs); | 47 | extern struct trace_event event_syscall_exit; |
46 | extern void ftrace_syscall_exit(struct pt_regs *regs); | 48 | extern int reg_event_syscall_enter(void *ptr); |
47 | #else | 49 | extern void unreg_event_syscall_enter(void *ptr); |
48 | static inline void start_ftrace_syscalls(void) { } | 50 | extern int reg_event_syscall_exit(void *ptr); |
49 | static inline void stop_ftrace_syscalls(void) { } | 51 | extern void unreg_event_syscall_exit(void *ptr); |
50 | static inline void ftrace_syscall_enter(struct pt_regs *regs) { } | ||
51 | static inline void ftrace_syscall_exit(struct pt_regs *regs) { } | ||
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | #endif /* _TRACE_SYSCALL_H */ | 54 | #endif /* _TRACE_SYSCALL_H */ |