aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-03-06 23:52:59 -0500
committerIngo Molnar <mingo@elte.hu>2009-03-13 01:25:43 -0400
commitee08c6eccb7d1295516f7cf420fddf7b14e9146f (patch)
treeec6d209e47bb1a8910d16c1c8b4ea65959850689 /kernel
parent4c6ed8f496fe89ff81b3d6e617a531bedfb613e4 (diff)
tracing/ftrace: syscall tracing infrastructure, basics
Provide basic callbacks to do syscall tracing. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Acked-by: Steven Rostedt <rostedt@goodmis.org> Cc: Lai Jiangshan <laijs@cn.fujitsu.com> LKML-Reference: <1236401580-5758-2-git-send-email-fweisbec@gmail.com> [ simplified it to a trace_printk() for now. ] Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/Kconfig10
-rw-r--r--kernel/trace/Makefile1
-rw-r--r--kernel/trace/trace.h2
-rw-r--r--kernel/trace/trace_syscalls.c113
4 files changed, 126 insertions, 0 deletions
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 8e4a2a61cd75..95a0ad191f19 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -34,6 +34,9 @@ config HAVE_FTRACE_MCOUNT_RECORD
34config HAVE_HW_BRANCH_TRACER 34config HAVE_HW_BRANCH_TRACER
35 bool 35 bool
36 36
37config HAVE_FTRACE_SYSCALLS
38 bool
39
37config TRACER_MAX_TRACE 40config TRACER_MAX_TRACE
38 bool 41 bool
39 42
@@ -175,6 +178,13 @@ config EVENT_TRACER
175 allowing the user to pick and choose which trace point they 178 allowing the user to pick and choose which trace point they
176 want to trace. 179 want to trace.
177 180
181config FTRACE_SYSCALLS
182 bool "Trace syscalls"
183 depends on HAVE_FTRACE_SYSCALLS
184 select TRACING
185 help
186 Basic tracer to catch the syscall entry and exit events.
187
178config BOOT_TRACER 188config BOOT_TRACER
179 bool "Trace boot initcalls" 189 bool "Trace boot initcalls"
180 select TRACING 190 select TRACING
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index c7a2943796eb..c3feea01c3e0 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -43,5 +43,6 @@ obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o
43obj-$(CONFIG_EVENT_TRACER) += trace_events.o 43obj-$(CONFIG_EVENT_TRACER) += trace_events.o
44obj-$(CONFIG_EVENT_TRACER) += events.o 44obj-$(CONFIG_EVENT_TRACER) += events.o
45obj-$(CONFIG_EVENT_TRACER) += trace_export.o 45obj-$(CONFIG_EVENT_TRACER) += trace_export.o
46obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
46 47
47libftrace-y := ftrace.o 48libftrace-y := ftrace.o
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index c5e1d8865fe4..3d49daae47dc 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -30,6 +30,8 @@ enum trace_type {
30 TRACE_GRAPH_ENT, 30 TRACE_GRAPH_ENT,
31 TRACE_USER_STACK, 31 TRACE_USER_STACK,
32 TRACE_HW_BRANCHES, 32 TRACE_HW_BRANCHES,
33 TRACE_SYSCALL_ENTER,
34 TRACE_SYSCALL_EXIT,
33 TRACE_KMEM_ALLOC, 35 TRACE_KMEM_ALLOC,
34 TRACE_KMEM_FREE, 36 TRACE_KMEM_FREE,
35 TRACE_POWER, 37 TRACE_POWER,
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
new file mode 100644
index 000000000000..66cf97449af3
--- /dev/null
+++ b/kernel/trace/trace_syscalls.c
@@ -0,0 +1,113 @@
1#include <linux/ftrace.h>
2#include <linux/kernel.h>
3
4#include <asm/syscall.h>
5
6#include "trace_output.h"
7#include "trace.h"
8
9static atomic_t refcount;
10
11void start_ftrace_syscalls(void)
12{
13 unsigned long flags;
14 struct task_struct *g, *t;
15
16 if (atomic_inc_return(&refcount) != 1)
17 goto out;
18
19 read_lock_irqsave(&tasklist_lock, flags);
20
21 do_each_thread(g, t) {
22 set_tsk_thread_flag(t, TIF_SYSCALL_FTRACE);
23 } while_each_thread(g, t);
24
25 read_unlock_irqrestore(&tasklist_lock, flags);
26out:
27 atomic_dec(&refcount);
28}
29
30void stop_ftrace_syscalls(void)
31{
32 unsigned long flags;
33 struct task_struct *g, *t;
34
35 if (atomic_dec_return(&refcount))
36 goto out;
37
38 read_lock_irqsave(&tasklist_lock, flags);
39
40 do_each_thread(g, t) {
41 clear_tsk_thread_flag(t, TIF_SYSCALL_FTRACE);
42 } while_each_thread(g, t);
43
44 read_unlock_irqrestore(&tasklist_lock, flags);
45out:
46 atomic_inc(&refcount);
47}
48
49void ftrace_syscall_enter(struct pt_regs *regs)
50{
51 int syscall_nr;
52
53 syscall_nr = syscall_get_nr(current, regs);
54
55 trace_printk("syscall %d enter\n", syscall_nr);
56}
57
58void ftrace_syscall_exit(struct pt_regs *regs)
59{
60 int syscall_nr;
61
62 syscall_nr = syscall_get_nr(current, regs);
63
64 trace_printk("syscall %d exit\n", syscall_nr);
65}
66
67static int init_syscall_tracer(struct trace_array *tr)
68{
69 start_ftrace_syscalls();
70
71 return 0;
72}
73
74static void reset_syscall_tracer(struct trace_array *tr)
75{
76 stop_ftrace_syscalls();
77}
78
79static struct trace_event syscall_enter_event = {
80 .type = TRACE_SYSCALL_ENTER,
81};
82
83static struct trace_event syscall_exit_event = {
84 .type = TRACE_SYSCALL_EXIT,
85};
86
87static struct tracer syscall_tracer __read_mostly = {
88 .name = "syscall",
89 .init = init_syscall_tracer,
90 .reset = reset_syscall_tracer
91};
92
93__init int register_ftrace_syscalls(void)
94{
95 int ret;
96
97 ret = register_ftrace_event(&syscall_enter_event);
98 if (!ret) {
99 printk(KERN_WARNING "event %d failed to register\n",
100 syscall_enter_event.type);
101 WARN_ON_ONCE(1);
102 }
103
104 ret = register_ftrace_event(&syscall_exit_event);
105 if (!ret) {
106 printk(KERN_WARNING "event %d failed to register\n",
107 syscall_exit_event.type);
108 WARN_ON_ONCE(1);
109 }
110
111 return register_tracer(&syscall_tracer);
112}
113device_initcall(register_ftrace_syscalls);