diff options
author | Josh Stone <jistone@redhat.com> | 2009-08-24 17:43:14 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-08-25 18:41:48 -0400 |
commit | 1c569f0264ea629c10bbab471dd0626ce4d3f19f (patch) | |
tree | 00fcbf85a7318c568f468518c3aa665a200c871e | |
parent | 97419875865859fd2403e66266c02ce028e2f5ab (diff) |
tracing: Create generic syscall TRACE_EVENTs
This converts the syscall_enter/exit tracepoints into TRACE_EVENTs, so
you can have generic ftrace events that capture all system calls with
arguments and return values. These generic events are also renamed to
sys_enter/exit, so they're more closely aligned to the specific
sys_enter_foo events.
Signed-off-by: Josh Stone <jistone@redhat.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Li Zefan <lizf@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: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
LKML-Reference: <1251150194-1713-5-git-send-email-jistone@redhat.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
-rw-r--r-- | arch/s390/kernel/ptrace.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/ptrace.c | 12 | ||||
-rw-r--r-- | include/trace/events/syscalls.h | 70 | ||||
-rw-r--r-- | include/trace/syscall.h | 17 | ||||
-rw-r--r-- | kernel/trace/trace_syscalls.c | 17 |
5 files changed, 88 insertions, 36 deletions
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index c05b44b80c23..f3ddd7ac06c5 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -51,8 +51,8 @@ | |||
51 | #include "compat_ptrace.h" | 51 | #include "compat_ptrace.h" |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | DEFINE_TRACE_FN(syscall_enter, syscall_regfunc, syscall_unregfunc); | 54 | #define CREATE_TRACE_POINTS |
55 | DEFINE_TRACE_FN(syscall_exit, syscall_regfunc, syscall_unregfunc); | 55 | #include <trace/events/syscalls.h> |
56 | 56 | ||
57 | enum s390_regset { | 57 | enum s390_regset { |
58 | REGSET_GENERAL, | 58 | REGSET_GENERAL, |
@@ -665,7 +665,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) | |||
665 | } | 665 | } |
666 | 666 | ||
667 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) | 667 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
668 | trace_syscall_enter(regs, regs->gprs[2]); | 668 | trace_sys_enter(regs, regs->gprs[2]); |
669 | 669 | ||
670 | if (unlikely(current->audit_context)) | 670 | if (unlikely(current->audit_context)) |
671 | audit_syscall_entry(is_compat_task() ? | 671 | audit_syscall_entry(is_compat_task() ? |
@@ -683,7 +683,7 @@ asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) | |||
683 | regs->gprs[2]); | 683 | regs->gprs[2]); |
684 | 684 | ||
685 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) | 685 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
686 | trace_syscall_exit(regs, regs->gprs[2]); | 686 | trace_sys_exit(regs, regs->gprs[2]); |
687 | 687 | ||
688 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 688 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
689 | tracehook_report_syscall_exit(regs, 0); | 689 | tracehook_report_syscall_exit(regs, 0); |
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 31e9b97ec4d6..8d7d5c9c1be3 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -35,13 +35,11 @@ | |||
35 | #include <asm/proto.h> | 35 | #include <asm/proto.h> |
36 | #include <asm/ds.h> | 36 | #include <asm/ds.h> |
37 | 37 | ||
38 | #include <trace/syscall.h> | ||
39 | |||
40 | DEFINE_TRACE_FN(syscall_enter, syscall_regfunc, syscall_unregfunc); | ||
41 | DEFINE_TRACE_FN(syscall_exit, syscall_regfunc, syscall_unregfunc); | ||
42 | |||
43 | #include "tls.h" | 38 | #include "tls.h" |
44 | 39 | ||
40 | #define CREATE_TRACE_POINTS | ||
41 | #include <trace/events/syscalls.h> | ||
42 | |||
45 | enum x86_regset { | 43 | enum x86_regset { |
46 | REGSET_GENERAL, | 44 | REGSET_GENERAL, |
47 | REGSET_FP, | 45 | REGSET_FP, |
@@ -1501,7 +1499,7 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs) | |||
1501 | ret = -1L; | 1499 | ret = -1L; |
1502 | 1500 | ||
1503 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) | 1501 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
1504 | trace_syscall_enter(regs, regs->orig_ax); | 1502 | trace_sys_enter(regs, regs->orig_ax); |
1505 | 1503 | ||
1506 | if (unlikely(current->audit_context)) { | 1504 | if (unlikely(current->audit_context)) { |
1507 | if (IS_IA32) | 1505 | if (IS_IA32) |
@@ -1527,7 +1525,7 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) | |||
1527 | audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); | 1525 | audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); |
1528 | 1526 | ||
1529 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) | 1527 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
1530 | trace_syscall_exit(regs, regs->ax); | 1528 | trace_sys_exit(regs, regs->ax); |
1531 | 1529 | ||
1532 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 1530 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
1533 | tracehook_report_syscall_exit(regs, 0); | 1531 | tracehook_report_syscall_exit(regs, 0); |
diff --git a/include/trace/events/syscalls.h b/include/trace/events/syscalls.h new file mode 100644 index 000000000000..397dff2dbd5a --- /dev/null +++ b/include/trace/events/syscalls.h | |||
@@ -0,0 +1,70 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM syscalls | ||
3 | |||
4 | #if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ) | ||
5 | #define _TRACE_EVENTS_SYSCALLS_H | ||
6 | |||
7 | #include <linux/tracepoint.h> | ||
8 | |||
9 | #include <asm/ptrace.h> | ||
10 | #include <asm/syscall.h> | ||
11 | |||
12 | |||
13 | #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS | ||
14 | |||
15 | extern void syscall_regfunc(void); | ||
16 | extern void syscall_unregfunc(void); | ||
17 | |||
18 | TRACE_EVENT_FN(sys_enter, | ||
19 | |||
20 | TP_PROTO(struct pt_regs *regs, long id), | ||
21 | |||
22 | TP_ARGS(regs, id), | ||
23 | |||
24 | TP_STRUCT__entry( | ||
25 | __field( long, id ) | ||
26 | __array( unsigned long, args, 6 ) | ||
27 | ), | ||
28 | |||
29 | TP_fast_assign( | ||
30 | __entry->id = id; | ||
31 | syscall_get_arguments(current, regs, 0, 6, __entry->args); | ||
32 | ), | ||
33 | |||
34 | TP_printk("NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)", | ||
35 | __entry->id, | ||
36 | __entry->args[0], __entry->args[1], __entry->args[2], | ||
37 | __entry->args[3], __entry->args[4], __entry->args[5]), | ||
38 | |||
39 | syscall_regfunc, syscall_unregfunc | ||
40 | ); | ||
41 | |||
42 | TRACE_EVENT_FN(sys_exit, | ||
43 | |||
44 | TP_PROTO(struct pt_regs *regs, long ret), | ||
45 | |||
46 | TP_ARGS(regs, ret), | ||
47 | |||
48 | TP_STRUCT__entry( | ||
49 | __field( long, id ) | ||
50 | __field( long, ret ) | ||
51 | ), | ||
52 | |||
53 | TP_fast_assign( | ||
54 | __entry->id = syscall_get_nr(current, regs); | ||
55 | __entry->ret = ret; | ||
56 | ), | ||
57 | |||
58 | TP_printk("NR %ld = %ld", | ||
59 | __entry->id, __entry->ret), | ||
60 | |||
61 | syscall_regfunc, syscall_unregfunc | ||
62 | ); | ||
63 | |||
64 | #endif /* CONFIG_HAVE_SYSCALL_TRACEPOINTS */ | ||
65 | |||
66 | #endif /* _TRACE_EVENTS_SYSCALLS_H */ | ||
67 | |||
68 | /* This part must be outside protection */ | ||
69 | #include <trace/define_trace.h> | ||
70 | |||
diff --git a/include/trace/syscall.h b/include/trace/syscall.h index 4e1943001854..5dc283ba5ae0 100644 --- a/include/trace/syscall.h +++ b/include/trace/syscall.h | |||
@@ -8,23 +8,6 @@ | |||
8 | #include <asm/ptrace.h> | 8 | #include <asm/ptrace.h> |
9 | 9 | ||
10 | 10 | ||
11 | #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS | ||
12 | |||
13 | extern void syscall_regfunc(void); | ||
14 | extern void syscall_unregfunc(void); | ||
15 | |||
16 | DECLARE_TRACE(syscall_enter, | ||
17 | TP_PROTO(struct pt_regs *regs, long id), | ||
18 | TP_ARGS(regs, id) | ||
19 | ); | ||
20 | |||
21 | DECLARE_TRACE(syscall_exit, | ||
22 | TP_PROTO(struct pt_regs *regs, long ret), | ||
23 | TP_ARGS(regs, ret) | ||
24 | ); | ||
25 | |||
26 | #endif | ||
27 | |||
28 | /* | 11 | /* |
29 | * A syscall entry in the ftrace syscalls array. | 12 | * A syscall entry in the ftrace syscalls array. |
30 | * | 13 | * |
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 46c1b977a2cb..2698fe401ebd 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <trace/syscall.h> | 1 | #include <trace/syscall.h> |
2 | #include <trace/events/syscalls.h> | ||
2 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
3 | #include <linux/ftrace.h> | 4 | #include <linux/ftrace.h> |
4 | #include <linux/perf_counter.h> | 5 | #include <linux/perf_counter.h> |
@@ -286,7 +287,7 @@ int reg_event_syscall_enter(void *ptr) | |||
286 | return -ENOSYS; | 287 | return -ENOSYS; |
287 | mutex_lock(&syscall_trace_lock); | 288 | mutex_lock(&syscall_trace_lock); |
288 | if (!sys_refcount_enter) | 289 | if (!sys_refcount_enter) |
289 | ret = register_trace_syscall_enter(ftrace_syscall_enter); | 290 | ret = register_trace_sys_enter(ftrace_syscall_enter); |
290 | if (ret) { | 291 | if (ret) { |
291 | pr_info("event trace: Could not activate" | 292 | pr_info("event trace: Could not activate" |
292 | "syscall entry trace point"); | 293 | "syscall entry trace point"); |
@@ -311,7 +312,7 @@ void unreg_event_syscall_enter(void *ptr) | |||
311 | sys_refcount_enter--; | 312 | sys_refcount_enter--; |
312 | clear_bit(num, enabled_enter_syscalls); | 313 | clear_bit(num, enabled_enter_syscalls); |
313 | if (!sys_refcount_enter) | 314 | if (!sys_refcount_enter) |
314 | unregister_trace_syscall_enter(ftrace_syscall_enter); | 315 | unregister_trace_sys_enter(ftrace_syscall_enter); |
315 | mutex_unlock(&syscall_trace_lock); | 316 | mutex_unlock(&syscall_trace_lock); |
316 | } | 317 | } |
317 | 318 | ||
@@ -327,7 +328,7 @@ int reg_event_syscall_exit(void *ptr) | |||
327 | return -ENOSYS; | 328 | return -ENOSYS; |
328 | mutex_lock(&syscall_trace_lock); | 329 | mutex_lock(&syscall_trace_lock); |
329 | if (!sys_refcount_exit) | 330 | if (!sys_refcount_exit) |
330 | ret = register_trace_syscall_exit(ftrace_syscall_exit); | 331 | ret = register_trace_sys_exit(ftrace_syscall_exit); |
331 | if (ret) { | 332 | if (ret) { |
332 | pr_info("event trace: Could not activate" | 333 | pr_info("event trace: Could not activate" |
333 | "syscall exit trace point"); | 334 | "syscall exit trace point"); |
@@ -352,7 +353,7 @@ void unreg_event_syscall_exit(void *ptr) | |||
352 | sys_refcount_exit--; | 353 | sys_refcount_exit--; |
353 | clear_bit(num, enabled_exit_syscalls); | 354 | clear_bit(num, enabled_exit_syscalls); |
354 | if (!sys_refcount_exit) | 355 | if (!sys_refcount_exit) |
355 | unregister_trace_syscall_exit(ftrace_syscall_exit); | 356 | unregister_trace_sys_exit(ftrace_syscall_exit); |
356 | mutex_unlock(&syscall_trace_lock); | 357 | mutex_unlock(&syscall_trace_lock); |
357 | } | 358 | } |
358 | 359 | ||
@@ -418,7 +419,7 @@ int reg_prof_syscall_enter(char *name) | |||
418 | 419 | ||
419 | mutex_lock(&syscall_trace_lock); | 420 | mutex_lock(&syscall_trace_lock); |
420 | if (!sys_prof_refcount_enter) | 421 | if (!sys_prof_refcount_enter) |
421 | ret = register_trace_syscall_enter(prof_syscall_enter); | 422 | ret = register_trace_sys_enter(prof_syscall_enter); |
422 | if (ret) { | 423 | if (ret) { |
423 | pr_info("event trace: Could not activate" | 424 | pr_info("event trace: Could not activate" |
424 | "syscall entry trace point"); | 425 | "syscall entry trace point"); |
@@ -442,7 +443,7 @@ void unreg_prof_syscall_enter(char *name) | |||
442 | sys_prof_refcount_enter--; | 443 | sys_prof_refcount_enter--; |
443 | clear_bit(num, enabled_prof_enter_syscalls); | 444 | clear_bit(num, enabled_prof_enter_syscalls); |
444 | if (!sys_prof_refcount_enter) | 445 | if (!sys_prof_refcount_enter) |
445 | unregister_trace_syscall_enter(prof_syscall_enter); | 446 | unregister_trace_sys_enter(prof_syscall_enter); |
446 | mutex_unlock(&syscall_trace_lock); | 447 | mutex_unlock(&syscall_trace_lock); |
447 | } | 448 | } |
448 | 449 | ||
@@ -479,7 +480,7 @@ int reg_prof_syscall_exit(char *name) | |||
479 | 480 | ||
480 | mutex_lock(&syscall_trace_lock); | 481 | mutex_lock(&syscall_trace_lock); |
481 | if (!sys_prof_refcount_exit) | 482 | if (!sys_prof_refcount_exit) |
482 | ret = register_trace_syscall_exit(prof_syscall_exit); | 483 | ret = register_trace_sys_exit(prof_syscall_exit); |
483 | if (ret) { | 484 | if (ret) { |
484 | pr_info("event trace: Could not activate" | 485 | pr_info("event trace: Could not activate" |
485 | "syscall entry trace point"); | 486 | "syscall entry trace point"); |
@@ -503,7 +504,7 @@ void unreg_prof_syscall_exit(char *name) | |||
503 | sys_prof_refcount_exit--; | 504 | sys_prof_refcount_exit--; |
504 | clear_bit(num, enabled_prof_exit_syscalls); | 505 | clear_bit(num, enabled_prof_exit_syscalls); |
505 | if (!sys_prof_refcount_exit) | 506 | if (!sys_prof_refcount_exit) |
506 | unregister_trace_syscall_exit(prof_syscall_exit); | 507 | unregister_trace_sys_exit(prof_syscall_exit); |
507 | mutex_unlock(&syscall_trace_lock); | 508 | mutex_unlock(&syscall_trace_lock); |
508 | } | 509 | } |
509 | 510 | ||