diff options
author | Li Zefan <lizf@cn.fujitsu.com> | 2009-08-19 03:52:25 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-08-19 09:02:22 -0400 |
commit | e6971969c331caa5c3c88cbd1be4f465b3355452 (patch) | |
tree | 0d66906d1882566257db824b38ab905d8a0dc721 /kernel/trace/trace_syscalls.c | |
parent | 5e9ad7df9fd056f1071af8aa91034a1c3170257d (diff) |
tracing/syscalls: Fix fields format for enter events
The "format" file of a trace event is originally for parsers to
parse ftrace binary output.
But the "format" file of a syscall event can only be used by
perfcounter, because it describes the format of struct
syscall_enter_record not struct syscall_trace_enter.
To fix this, we remove struct syscall_enter_record, and then
struct syscall_trace_enter will be used by both perf profile
and ftrace.
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <4A8BAF39.1030404@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/trace/trace_syscalls.c')
-rw-r--r-- | kernel/trace/trace_syscalls.c | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index f130dacfeef4..d10daf0922b5 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
@@ -90,26 +90,39 @@ print_syscall_exit(struct trace_iterator *iter, int flags) | |||
90 | return TRACE_TYPE_HANDLED; | 90 | return TRACE_TYPE_HANDLED; |
91 | } | 91 | } |
92 | 92 | ||
93 | extern char *__bad_type_size(void); | ||
94 | |||
95 | #define SYSCALL_FIELD(type, name) \ | ||
96 | sizeof(type) != sizeof(trace.name) ? \ | ||
97 | __bad_type_size() : \ | ||
98 | #type, #name, offsetof(typeof(trace), name), sizeof(trace.name) | ||
99 | |||
93 | int ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s) | 100 | int ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s) |
94 | { | 101 | { |
95 | int i; | 102 | int i; |
96 | int nr; | 103 | int nr; |
97 | int ret = 0; | 104 | int ret; |
98 | struct syscall_metadata *entry; | 105 | struct syscall_metadata *entry; |
99 | int offset = sizeof(struct trace_entry); | 106 | struct syscall_trace_enter trace; |
107 | int offset = offsetof(struct syscall_trace_enter, args); | ||
100 | 108 | ||
101 | nr = syscall_name_to_nr((char *)call->data); | 109 | nr = syscall_name_to_nr(call->data); |
102 | entry = syscall_nr_to_meta(nr); | 110 | entry = syscall_nr_to_meta(nr); |
103 | 111 | ||
104 | if (!entry) | 112 | if (!entry) |
105 | return ret; | 113 | return 0; |
114 | |||
115 | ret = trace_seq_printf(s, "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n", | ||
116 | SYSCALL_FIELD(int, nr)); | ||
117 | if (!ret) | ||
118 | return 0; | ||
106 | 119 | ||
107 | for (i = 0; i < entry->nb_args; i++) { | 120 | for (i = 0; i < entry->nb_args; i++) { |
108 | ret = trace_seq_printf(s, "\tfield:%s %s;", entry->types[i], | 121 | ret = trace_seq_printf(s, "\tfield:%s %s;", entry->types[i], |
109 | entry->args[i]); | 122 | entry->args[i]); |
110 | if (!ret) | 123 | if (!ret) |
111 | return 0; | 124 | return 0; |
112 | ret = trace_seq_printf(s, "\toffset:%d;\tsize:%lu;\n", offset, | 125 | ret = trace_seq_printf(s, "\toffset:%d;\tsize:%zu;\n", offset, |
113 | sizeof(unsigned long)); | 126 | sizeof(unsigned long)); |
114 | if (!ret) | 127 | if (!ret) |
115 | return 0; | 128 | return 0; |
@@ -118,7 +131,7 @@ int ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s) | |||
118 | 131 | ||
119 | trace_seq_printf(s, "\nprint fmt: \""); | 132 | trace_seq_printf(s, "\nprint fmt: \""); |
120 | for (i = 0; i < entry->nb_args; i++) { | 133 | for (i = 0; i < entry->nb_args; i++) { |
121 | ret = trace_seq_printf(s, "%s: 0x%%0%lulx%s", entry->args[i], | 134 | ret = trace_seq_printf(s, "%s: 0x%%0%zulx%s", entry->args[i], |
122 | sizeof(unsigned long), | 135 | sizeof(unsigned long), |
123 | i == entry->nb_args - 1 ? "\", " : ", "); | 136 | i == entry->nb_args - 1 ? "\", " : ", "); |
124 | if (!ret) | 137 | if (!ret) |
@@ -287,16 +300,6 @@ struct trace_event event_syscall_exit = { | |||
287 | 300 | ||
288 | #ifdef CONFIG_EVENT_PROFILE | 301 | #ifdef CONFIG_EVENT_PROFILE |
289 | 302 | ||
290 | struct syscall_enter_record { | ||
291 | struct trace_entry entry; | ||
292 | unsigned long args[0]; | ||
293 | }; | ||
294 | |||
295 | struct syscall_exit_record { | ||
296 | struct trace_entry entry; | ||
297 | unsigned long ret; | ||
298 | }; | ||
299 | |||
300 | static DECLARE_BITMAP(enabled_prof_enter_syscalls, FTRACE_SYSCALL_MAX); | 303 | static DECLARE_BITMAP(enabled_prof_enter_syscalls, FTRACE_SYSCALL_MAX); |
301 | static DECLARE_BITMAP(enabled_prof_exit_syscalls, FTRACE_SYSCALL_MAX); | 304 | static DECLARE_BITMAP(enabled_prof_exit_syscalls, FTRACE_SYSCALL_MAX); |
302 | static int sys_prof_refcount_enter; | 305 | static int sys_prof_refcount_enter; |
@@ -304,7 +307,7 @@ static int sys_prof_refcount_exit; | |||
304 | 307 | ||
305 | static void prof_syscall_enter(struct pt_regs *regs, long id) | 308 | static void prof_syscall_enter(struct pt_regs *regs, long id) |
306 | { | 309 | { |
307 | struct syscall_enter_record *rec; | 310 | struct syscall_trace_enter *rec; |
308 | struct syscall_metadata *sys_data; | 311 | struct syscall_metadata *sys_data; |
309 | int syscall_nr; | 312 | int syscall_nr; |
310 | int size; | 313 | int size; |
@@ -328,9 +331,10 @@ static void prof_syscall_enter(struct pt_regs *regs, long id) | |||
328 | /* zero the dead bytes from align to not leak stack to user */ | 331 | /* zero the dead bytes from align to not leak stack to user */ |
329 | *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL; | 332 | *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL; |
330 | 333 | ||
331 | rec = (struct syscall_enter_record *) raw_data; | 334 | rec = (struct syscall_trace_enter *) raw_data; |
332 | tracing_generic_entry_update(&rec->entry, 0, 0); | 335 | tracing_generic_entry_update(&rec->ent, 0, 0); |
333 | rec->entry.type = sys_data->enter_id; | 336 | rec->ent.type = sys_data->enter_id; |
337 | rec->nr = syscall_nr; | ||
334 | syscall_get_arguments(current, regs, 0, sys_data->nb_args, | 338 | syscall_get_arguments(current, regs, 0, sys_data->nb_args, |
335 | (unsigned long *)&rec->args); | 339 | (unsigned long *)&rec->args); |
336 | perf_tpcounter_event(sys_data->enter_id, 0, 1, rec, size); | 340 | perf_tpcounter_event(sys_data->enter_id, 0, 1, rec, size); |
@@ -379,7 +383,7 @@ void unreg_prof_syscall_enter(char *name) | |||
379 | static void prof_syscall_exit(struct pt_regs *regs, long ret) | 383 | static void prof_syscall_exit(struct pt_regs *regs, long ret) |
380 | { | 384 | { |
381 | struct syscall_metadata *sys_data; | 385 | struct syscall_metadata *sys_data; |
382 | struct syscall_exit_record rec; | 386 | struct syscall_trace_exit rec; |
383 | int syscall_nr; | 387 | int syscall_nr; |
384 | 388 | ||
385 | syscall_nr = syscall_get_nr(current, regs); | 389 | syscall_nr = syscall_get_nr(current, regs); |
@@ -390,8 +394,9 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret) | |||
390 | if (!sys_data) | 394 | if (!sys_data) |
391 | return; | 395 | return; |
392 | 396 | ||
393 | tracing_generic_entry_update(&rec.entry, 0, 0); | 397 | tracing_generic_entry_update(&rec.ent, 0, 0); |
394 | rec.entry.type = sys_data->exit_id; | 398 | rec.ent.type = sys_data->exit_id; |
399 | rec.nr = syscall_nr; | ||
395 | rec.ret = syscall_get_return_value(current, regs); | 400 | rec.ret = syscall_get_return_value(current, regs); |
396 | 401 | ||
397 | perf_tpcounter_event(sys_data->exit_id, 0, 1, &rec, sizeof(rec)); | 402 | perf_tpcounter_event(sys_data->exit_id, 0, 1, &rec, sizeof(rec)); |