1 #include <linux/ftrace.h>
2 #include <linux/kernel.h>
4 #include <asm/syscall.h>
6 #include "trace_output.h"
9 static atomic_t refcount
;
11 void start_ftrace_syscalls(void)
14 struct task_struct
*g
, *t
;
16 if (atomic_inc_return(&refcount
) != 1)
19 read_lock_irqsave(&tasklist_lock
, flags
);
21 do_each_thread(g
, t
) {
22 set_tsk_thread_flag(t
, TIF_SYSCALL_FTRACE
);
23 } while_each_thread(g
, t
);
25 read_unlock_irqrestore(&tasklist_lock
, flags
);
27 atomic_dec(&refcount
);
30 void stop_ftrace_syscalls(void)
33 struct task_struct
*g
, *t
;
35 if (atomic_dec_return(&refcount
))
38 read_lock_irqsave(&tasklist_lock
, flags
);
40 do_each_thread(g
, t
) {
41 clear_tsk_thread_flag(t
, TIF_SYSCALL_FTRACE
);
42 } while_each_thread(g
, t
);
44 read_unlock_irqrestore(&tasklist_lock
, flags
);
46 atomic_inc(&refcount
);
49 void ftrace_syscall_enter(struct pt_regs
*regs
)
53 syscall_nr
= syscall_get_nr(current
, regs
);
55 trace_printk("syscall %d enter\n", syscall_nr
);
58 void ftrace_syscall_exit(struct pt_regs
*regs
)
62 syscall_nr
= syscall_get_nr(current
, regs
);
64 trace_printk("syscall %d exit\n", syscall_nr
);
67 static int init_syscall_tracer(struct trace_array
*tr
)
69 start_ftrace_syscalls();
74 static void reset_syscall_tracer(struct trace_array
*tr
)
76 stop_ftrace_syscalls();
79 static struct trace_event syscall_enter_event
= {
80 .type
= TRACE_SYSCALL_ENTER
,
83 static struct trace_event syscall_exit_event
= {
84 .type
= TRACE_SYSCALL_EXIT
,
87 static struct tracer syscall_tracer __read_mostly
= {
89 .init
= init_syscall_tracer
,
90 .reset
= reset_syscall_tracer
93 __init
int register_ftrace_syscalls(void)
97 ret
= register_ftrace_event(&syscall_enter_event
);
99 printk(KERN_WARNING
"event %d failed to register\n",
100 syscall_enter_event
.type
);
104 ret
= register_ftrace_event(&syscall_exit_event
);
106 printk(KERN_WARNING
"event %d failed to register\n",
107 syscall_exit_event
.type
);
111 return register_tracer(&syscall_tracer
);
113 device_initcall(register_ftrace_syscalls
);