Commit 35dce1a9 authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'tracing/core' of...

Merge branch 'tracing/core' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing into tracing/core

Conflicts:
	include/linux/tracepoint.h
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parents 7cb2e3ee 1c569f02
...@@ -84,7 +84,7 @@ config S390 ...@@ -84,7 +84,7 @@ config S390
select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FTRACE_SYSCALLS select HAVE_SYSCALL_TRACEPOINTS
select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_DEFAULT_NO_SPIN_MUTEXES select HAVE_DEFAULT_NO_SPIN_MUTEXES
......
...@@ -900,7 +900,7 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ...@@ -900,7 +900,7 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FTRACE_SYSCALLS=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_TRACING_SUPPORT=y CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set # CONFIG_FUNCTION_TRACER is not set
......
...@@ -92,7 +92,7 @@ static inline struct thread_info *current_thread_info(void) ...@@ -92,7 +92,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_TRACE 8 /* syscall trace active */ #define TIF_SYSCALL_TRACE 8 /* syscall trace active */
#define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */
#define TIF_SECCOMP 10 /* secure computing */ #define TIF_SECCOMP 10 /* secure computing */
#define TIF_SYSCALL_FTRACE 11 /* ftrace syscall instrumentation */ #define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling
TIF_NEED_RESCHED */ TIF_NEED_RESCHED */
...@@ -111,7 +111,7 @@ static inline struct thread_info *current_thread_info(void) ...@@ -111,7 +111,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_SYSCALL_FTRACE (1<<TIF_SYSCALL_FTRACE) #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
#define _TIF_USEDFPU (1<<TIF_USEDFPU) #define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_31BIT (1<<TIF_31BIT) #define _TIF_31BIT (1<<TIF_31BIT)
......
...@@ -54,7 +54,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ ...@@ -54,7 +54,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING) _TIF_MCCK_PENDING)
_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
_TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8) _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8)
STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
STACK_SIZE = 1 << STACK_SHIFT STACK_SIZE = 1 << STACK_SHIFT
......
...@@ -57,7 +57,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ ...@@ -57,7 +57,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING) _TIF_MCCK_PENDING)
_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
_TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8) _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8)
#define BASED(name) name-system_call(%r13) #define BASED(name) name-system_call(%r13)
......
...@@ -51,8 +51,8 @@ ...@@ -51,8 +51,8 @@
#include "compat_ptrace.h" #include "compat_ptrace.h"
#endif #endif
DEFINE_TRACE(syscall_enter); #define CREATE_TRACE_POINTS
DEFINE_TRACE(syscall_exit); #include <trace/events/syscalls.h>
enum s390_regset { enum s390_regset {
REGSET_GENERAL, REGSET_GENERAL,
...@@ -664,8 +664,8 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) ...@@ -664,8 +664,8 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
ret = -1; ret = -1;
} }
if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
trace_syscall_enter(regs, regs->gprs[2]); trace_sys_enter(regs, regs->gprs[2]);
if (unlikely(current->audit_context)) if (unlikely(current->audit_context))
audit_syscall_entry(is_compat_task() ? audit_syscall_entry(is_compat_task() ?
...@@ -682,8 +682,8 @@ asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) ...@@ -682,8 +682,8 @@ asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]),
regs->gprs[2]); regs->gprs[2]);
if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
trace_syscall_exit(regs, regs->gprs[2]); trace_sys_exit(regs, regs->gprs[2]);
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, 0); tracehook_report_syscall_exit(regs, 0);
......
...@@ -37,7 +37,7 @@ config X86 ...@@ -37,7 +37,7 @@ config X86
select HAVE_FUNCTION_GRAPH_FP_TEST select HAVE_FUNCTION_GRAPH_FP_TEST
select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
select HAVE_FTRACE_SYSCALLS select HAVE_SYSCALL_TRACEPOINTS
select HAVE_KVM select HAVE_KVM
select HAVE_ARCH_KGDB select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRACEHOOK
......
...@@ -2355,7 +2355,7 @@ CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y ...@@ -2355,7 +2355,7 @@ CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_HW_BRANCH_TRACER=y CONFIG_HAVE_HW_BRANCH_TRACER=y
CONFIG_HAVE_FTRACE_SYSCALLS=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_RING_BUFFER=y CONFIG_RING_BUFFER=y
CONFIG_TRACING=y CONFIG_TRACING=y
CONFIG_TRACING_SUPPORT=y CONFIG_TRACING_SUPPORT=y
......
...@@ -2329,7 +2329,7 @@ CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y ...@@ -2329,7 +2329,7 @@ CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_HW_BRANCH_TRACER=y CONFIG_HAVE_HW_BRANCH_TRACER=y
CONFIG_HAVE_FTRACE_SYSCALLS=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_RING_BUFFER=y CONFIG_RING_BUFFER=y
CONFIG_TRACING=y CONFIG_TRACING=y
CONFIG_TRACING_SUPPORT=y CONFIG_TRACING_SUPPORT=y
......
...@@ -95,7 +95,7 @@ struct thread_info { ...@@ -95,7 +95,7 @@ struct thread_info {
#define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */ #define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */
#define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */ #define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */
#define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */ #define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */
#define TIF_SYSCALL_FTRACE 28 /* for ftrace syscall instrumentation */ #define TIF_SYSCALL_TRACEPOINT 28 /* syscall tracepoint instrumentation */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
...@@ -118,17 +118,17 @@ struct thread_info { ...@@ -118,17 +118,17 @@ struct thread_info {
#define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR) #define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR)
#define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR) #define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR)
#define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES) #define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES)
#define _TIF_SYSCALL_FTRACE (1 << TIF_SYSCALL_FTRACE) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
/* work to do in syscall_trace_enter() */ /* work to do in syscall_trace_enter() */
#define _TIF_WORK_SYSCALL_ENTRY \ #define _TIF_WORK_SYSCALL_ENTRY \
(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_FTRACE | \ (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_AUDIT | \
_TIF_SYSCALL_AUDIT | _TIF_SECCOMP | _TIF_SINGLESTEP) _TIF_SECCOMP | _TIF_SINGLESTEP | _TIF_SYSCALL_TRACEPOINT)
/* work to do in syscall_trace_leave() */ /* work to do in syscall_trace_leave() */
#define _TIF_WORK_SYSCALL_EXIT \ #define _TIF_WORK_SYSCALL_EXIT \
(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP | \ (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP | \
_TIF_SYSCALL_FTRACE) _TIF_SYSCALL_TRACEPOINT)
/* work to do on interrupt/exception return */ /* work to do on interrupt/exception return */
#define _TIF_WORK_MASK \ #define _TIF_WORK_MASK \
...@@ -137,7 +137,8 @@ struct thread_info { ...@@ -137,7 +137,8 @@ struct thread_info {
_TIF_SINGLESTEP|_TIF_SECCOMP|_TIF_SYSCALL_EMU)) _TIF_SINGLESTEP|_TIF_SECCOMP|_TIF_SYSCALL_EMU))
/* work to do on any return to user space */ /* work to do on any return to user space */
#define _TIF_ALLWORK_MASK ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_FTRACE) #define _TIF_ALLWORK_MASK \
((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_TRACEPOINT)
/* Only used for 64 bit */ /* Only used for 64 bit */
#define _TIF_DO_NOTIFY_MASK \ #define _TIF_DO_NOTIFY_MASK \
......
...@@ -35,13 +35,11 @@ ...@@ -35,13 +35,11 @@
#include <asm/proto.h> #include <asm/proto.h>
#include <asm/ds.h> #include <asm/ds.h>
#include <trace/syscall.h>
DEFINE_TRACE(syscall_enter);
DEFINE_TRACE(syscall_exit);
#include "tls.h" #include "tls.h"
#define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h>
enum x86_regset { enum x86_regset {
REGSET_GENERAL, REGSET_GENERAL,
REGSET_FP, REGSET_FP,
...@@ -1500,8 +1498,8 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs) ...@@ -1500,8 +1498,8 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs)
tracehook_report_syscall_entry(regs)) tracehook_report_syscall_entry(regs))
ret = -1L; ret = -1L;
if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
trace_syscall_enter(regs, regs->orig_ax); trace_sys_enter(regs, regs->orig_ax);
if (unlikely(current->audit_context)) { if (unlikely(current->audit_context)) {
if (IS_IA32) if (IS_IA32)
...@@ -1526,8 +1524,8 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) ...@@ -1526,8 +1524,8 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
if (unlikely(current->audit_context)) if (unlikely(current->audit_context))
audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
trace_syscall_exit(regs, regs->ax); trace_sys_exit(regs, regs->ax);
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, 0); tracehook_report_syscall_exit(regs, 0);
......
...@@ -23,6 +23,8 @@ struct tracepoint; ...@@ -23,6 +23,8 @@ struct tracepoint;
struct tracepoint { struct tracepoint {
const char *name; /* Tracepoint name */ const char *name; /* Tracepoint name */
int state; /* State. */ int state; /* State. */
void (*regfunc)(void);
void (*unregfunc)(void);
void **funcs; void **funcs;
} __attribute__((aligned(32))); /* } __attribute__((aligned(32))); /*
* Aligned on 32 bytes because it is * Aligned on 32 bytes because it is
...@@ -60,10 +62,8 @@ struct tracepoint { ...@@ -60,10 +62,8 @@ struct tracepoint {
* Make sure the alignment of the structure in the __tracepoints section will * Make sure the alignment of the structure in the __tracepoints section will
* not add unwanted padding between the beginning of the section and the * not add unwanted padding between the beginning of the section and the
* structure. Force alignment to the same alignment as the section start. * structure. Force alignment to the same alignment as the section start.
* An optional set of (un)registration functions can be passed to perform any
* additional (un)registration work.
*/ */
#define DECLARE_TRACE_WITH_CALLBACK(name, proto, args, reg, unreg) \ #define DECLARE_TRACE(name, proto, args) \
extern struct tracepoint __tracepoint_##name; \ extern struct tracepoint __tracepoint_##name; \
static inline void trace_##name(proto) \ static inline void trace_##name(proto) \
{ \ { \
...@@ -73,36 +73,23 @@ struct tracepoint { ...@@ -73,36 +73,23 @@ struct tracepoint {
} \ } \
static inline int register_trace_##name(void (*probe)(proto)) \ static inline int register_trace_##name(void (*probe)(proto)) \
{ \ { \
int ret; \ return tracepoint_probe_register(#name, (void *)probe); \
void (*func)(void) = reg; \
\
ret = tracepoint_probe_register(#name, (void *)probe); \
if (func && !ret) \
func(); \
return ret; \
} \ } \
static inline int unregister_trace_##name(void (*probe)(proto)) \ static inline int unregister_trace_##name(void (*probe)(proto)) \
{ \ { \
int ret; \ return tracepoint_probe_unregister(#name, (void *)probe);\
void (*func)(void) = unreg; \
\
ret = tracepoint_probe_unregister(#name, (void *)probe);\
if (func && !ret) \
func(); \
return ret; \
} }
#define DECLARE_TRACE(name, proto, args) \ #define DEFINE_TRACE_FN(name, reg, unreg) \
DECLARE_TRACE_WITH_CALLBACK(name, TP_PROTO(proto), TP_ARGS(args),\
NULL, NULL);
#define DEFINE_TRACE(name) \
static const char __tpstrtab_##name[] \ static const char __tpstrtab_##name[] \
__attribute__((section("__tracepoints_strings"))) = #name; \ __attribute__((section("__tracepoints_strings"))) = #name; \
struct tracepoint __tracepoint_##name \ struct tracepoint __tracepoint_##name \
__attribute__((section("__tracepoints"), aligned(32))) = \ __attribute__((section("__tracepoints"), aligned(32))) = \
{ __tpstrtab_##name, 0, NULL } { __tpstrtab_##name, 0, reg, unreg, NULL }
#define DEFINE_TRACE(name) \
DEFINE_TRACE_FN(name, NULL, NULL);
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \ #define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
EXPORT_SYMBOL_GPL(__tracepoint_##name) EXPORT_SYMBOL_GPL(__tracepoint_##name)
...@@ -113,7 +100,7 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin, ...@@ -113,7 +100,7 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,
struct tracepoint *end); struct tracepoint *end);
#else /* !CONFIG_TRACEPOINTS */ #else /* !CONFIG_TRACEPOINTS */
#define DECLARE_TRACE_WITH_CALLBACK(name, proto, args, reg, unreg) \ #define DECLARE_TRACE(name, proto, args) \
static inline void _do_trace_##name(struct tracepoint *tp, proto) \ static inline void _do_trace_##name(struct tracepoint *tp, proto) \
{ } \ { } \
static inline void trace_##name(proto) \ static inline void trace_##name(proto) \
...@@ -127,10 +114,7 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin, ...@@ -127,10 +114,7 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,
return -ENOSYS; \ return -ENOSYS; \
} }
#define DECLARE_TRACE(name, proto, args) \ #define DEFINE_TRACE_FN(name, reg, unreg)
DECLARE_TRACE_WITH_CALLBACK(name, TP_PROTO(proto), TP_ARGS(args),\
NULL, NULL);
#define DEFINE_TRACE(name) #define DEFINE_TRACE(name)
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) #define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
#define EXPORT_TRACEPOINT_SYMBOL(name) #define EXPORT_TRACEPOINT_SYMBOL(name)
...@@ -291,9 +275,15 @@ static inline void tracepoint_synchronize_unregister(void) ...@@ -291,9 +275,15 @@ static inline void tracepoint_synchronize_unregister(void)
* can also by used by generic instrumentation like SystemTap), and * can also by used by generic instrumentation like SystemTap), and
* it is also used to expose a structured trace record in * it is also used to expose a structured trace record in
* /sys/kernel/debug/tracing/events/. * /sys/kernel/debug/tracing/events/.
*
* A set of (un)registration functions can be passed to the variant
* TRACE_EVENT_FN to perform any (un)registration work.
*/ */
#define TRACE_EVENT(name, proto, args, struct, assign, print) \ #define TRACE_EVENT(name, proto, args, struct, assign, print) \
DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
#define TRACE_EVENT_FN(name, proto, args, struct, \
assign, print, reg, unreg) \
DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
#endif /* ifdef TRACE_EVENT (see note above) */ #endif /* ifdef TRACE_EVENT (see note above) */
...@@ -26,6 +26,11 @@ ...@@ -26,6 +26,11 @@
#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ #define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
DEFINE_TRACE(name) DEFINE_TRACE(name)
#undef TRACE_EVENT_FN
#define TRACE_EVENT_FN(name, proto, args, tstruct, \
assign, print, reg, unreg) \
DEFINE_TRACE_FN(name, reg, unreg)
#undef DECLARE_TRACE #undef DECLARE_TRACE
#define DECLARE_TRACE(name, proto, args) \ #define DECLARE_TRACE(name, proto, args) \
DEFINE_TRACE(name) DEFINE_TRACE(name)
......
#undef TRACE_SYSTEM
#define TRACE_SYSTEM syscalls
#if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_EVENTS_SYSCALLS_H
#include <linux/tracepoint.h>
#include <asm/ptrace.h>
#include <asm/syscall.h>
#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
extern void syscall_regfunc(void);
extern void syscall_unregfunc(void);
TRACE_EVENT_FN(sys_enter,
TP_PROTO(struct pt_regs *regs, long id),
TP_ARGS(regs, id),
TP_STRUCT__entry(
__field( long, id )
__array( unsigned long, args, 6 )
),
TP_fast_assign(
__entry->id = id;
syscall_get_arguments(current, regs, 0, 6, __entry->args);
),
TP_printk("NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)",
__entry->id,
__entry->args[0], __entry->args[1], __entry->args[2],
__entry->args[3], __entry->args[4], __entry->args[5]),
syscall_regfunc, syscall_unregfunc
);
TRACE_EVENT_FN(sys_exit,
TP_PROTO(struct pt_regs *regs, long ret),
TP_ARGS(regs, ret),
TP_STRUCT__entry(
__field( long, id )
__field( long, ret )
),
TP_fast_assign(
__entry->id = syscall_get_nr(current, regs);
__entry->ret = ret;
),
TP_printk("NR %ld = %ld",
__entry->id, __entry->ret),
syscall_regfunc, syscall_unregfunc
);
#endif /* CONFIG_HAVE_SYSCALL_TRACEPOINTS */
#endif /* _TRACE_EVENTS_SYSCALLS_H */
/* This part must be outside protection */
#include <trace/define_trace.h>
...@@ -45,6 +45,15 @@ ...@@ -45,6 +45,15 @@
}; \ }; \
static struct ftrace_event_call event_##name static struct ftrace_event_call event_##name
/* Callbacks are meaningless to ftrace. */
#undef TRACE_EVENT_FN
#define TRACE_EVENT_FN(name, proto, args, tstruct, \
assign, print, reg, unreg) \
TRACE_EVENT(name, TP_PROTO(proto), TP_ARGS(args), \
TP_STRUCT__entry(tstruct), \
TP_fast_assign(assign), \
TP_printk(print))
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
......
...@@ -8,23 +8,6 @@ ...@@ -8,23 +8,6 @@
#include <asm/ptrace.h> #include <asm/ptrace.h>
extern void syscall_regfunc(void);
extern void syscall_unregfunc(void);
DECLARE_TRACE_WITH_CALLBACK(syscall_enter,
TP_PROTO(struct pt_regs *regs, long id),
TP_ARGS(regs, id),
syscall_regfunc,
syscall_unregfunc
);
DECLARE_TRACE_WITH_CALLBACK(syscall_exit,
TP_PROTO(struct pt_regs *regs, long ret),
TP_ARGS(regs, ret),
syscall_regfunc,
syscall_unregfunc
);
/* /*
* A syscall entry in the ftrace syscalls array. * A syscall entry in the ftrace syscalls array.
* *
......
...@@ -41,7 +41,7 @@ config HAVE_FTRACE_MCOUNT_RECORD ...@@ -41,7 +41,7 @@ config HAVE_FTRACE_MCOUNT_RECORD
config HAVE_HW_BRANCH_TRACER config HAVE_HW_BRANCH_TRACER
bool bool
config HAVE_FTRACE_SYSCALLS config HAVE_SYSCALL_TRACEPOINTS
bool bool
config TRACER_MAX_TRACE config TRACER_MAX_TRACE
...@@ -211,7 +211,7 @@ config ENABLE_DEFAULT_TRACERS ...@@ -211,7 +211,7 @@ config ENABLE_DEFAULT_TRACERS
config FTRACE_SYSCALLS config FTRACE_SYSCALLS
bool "Trace syscalls" bool "Trace syscalls"
depends on HAVE_FTRACE_SYSCALLS depends on HAVE_SYSCALL_TRACEPOINTS
select GENERIC_TRACER select GENERIC_TRACER
select KALLSYMS select KALLSYMS
help help
......
#include <trace/syscall.h> #include <trace/syscall.h>
#include <trace/events/syscalls.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/ftrace.h> #include <linux/ftrace.h>
#include <linux/perf_counter.h> #include <linux/perf_counter.h>
...@@ -288,7 +289,7 @@ int reg_event_syscall_enter(void *ptr) ...@@ -288,7 +289,7 @@ int reg_event_syscall_enter(void *ptr)
return -ENOSYS; return -ENOSYS;
mutex_lock(&syscall_trace_lock); mutex_lock(&syscall_trace_lock);
if (!sys_refcount_enter) if (!sys_refcount_enter)
ret = register_trace_syscall_enter(ftrace_syscall_enter); ret = register_trace_sys_enter(ftrace_syscall_enter);
if (ret) { if (ret) {
pr_info("event trace: Could not activate" pr_info("event trace: Could not activate"
"syscall entry trace point"); "syscall entry trace point");
...@@ -313,7 +314,7 @@ void unreg_event_syscall_enter(void *ptr) ...@@ -313,7 +314,7 @@ void unreg_event_syscall_enter(void *ptr)
sys_refcount_enter--; sys_refcount_enter--;
clear_bit(num, enabled_enter_syscalls); clear_bit(num, enabled_enter_syscalls);
if (!sys_refcount_enter) if (!sys_refcount_enter)
unregister_trace_syscall_enter(ftrace_syscall_enter); unregister_trace_sys_enter(ftrace_syscall_enter);
mutex_unlock(&syscall_trace_lock); mutex_unlock(&syscall_trace_lock);
} }
...@@ -329,7 +330,7 @@ int reg_event_syscall_exit(void *ptr) ...@@ -329,7 +330,7 @@ int reg_event_syscall_exit(void *ptr)
return -ENOSYS; return -ENOSYS;
mutex_lock(&syscall_trace_lock); mutex_lock(&syscall_trace_lock);
if (!sys_refcount_exit) if (!sys_refcount_exit)
ret = register_trace_syscall_exit(ftrace_syscall_exit); ret = register_trace_sys_exit(ftrace_syscall_exit);
if (ret) { if (ret) {
pr_info("event trace: Could not activate" pr_info("event trace: Could not activate"
"syscall exit trace point"); "syscall exit trace point");
...@@ -354,7 +355,7 @@ void unreg_event_syscall_exit(void *ptr) ...@@ -354,7 +355,7 @@ void unreg_event_syscall_exit(void *ptr)
sys_refcount_exit--; sys_refcount_exit--;
clear_bit(num, enabled_exit_syscalls); clear_bit(num, enabled_exit_syscalls);
if (!sys_refcount_exit) if (!sys_refcount_exit)
unregister_trace_syscall_exit(ftrace_syscall_exit); unregister_trace_sys_exit(ftrace_syscall_exit);
mutex_unlock(&syscall_trace_lock); mutex_unlock(&syscall_trace_lock);
} }
...@@ -420,7 +421,7 @@ int reg_prof_syscall_enter(char *name) ...@@ -420,7 +421,7 @@ int reg_prof_syscall_enter(char *name)
mutex_lock(&syscall_trace_lock); mutex_lock(&syscall_trace_lock);
if (!sys_prof_refcount_enter) if (!sys_prof_refcount_enter)
ret = register_trace_syscall_enter(prof_syscall_enter); ret = register_trace_sys_enter(prof_syscall_enter);
if (ret) { if (ret) {
pr_info("event trace: Could not activate" pr_info("event trace: Could not activate"
"syscall entry trace point"); "syscall entry trace point");
...@@ -444,7 +445,7 @@ void unreg_prof_syscall_enter(char *name) ...@@ -444,7 +445,7 @@ void unreg_prof_syscall_enter(char *name)
sys_prof_refcount_enter--; sys_prof_refcount_enter--;
clear_bit(num, enabled_prof_enter_syscalls); clear_bit(num, enabled_prof_enter_syscalls);
if (!sys_prof_refcount_enter) if (!sys_prof_refcount_enter)
unregister_trace_syscall_enter(prof_syscall_enter); unregister_trace_sys_enter(prof_syscall_enter);
mutex_unlock(&syscall_trace_lock); mutex_unlock(&syscall_trace_lock);
} }
...@@ -481,7 +482,7 @@ int reg_prof_syscall_exit(char *name) ...@@ -481,7 +482,7 @@ int reg_prof_syscall_exit(char *name)
mutex_lock(&syscall_trace_lock); mutex_lock(&syscall_trace_lock);
if (!sys_prof_refcount_exit) if (!sys_prof_refcount_exit)
ret = register_trace_syscall_exit(prof_syscall_exit); ret = register_trace_sys_exit(prof_syscall_exit);
if (ret) { if (ret) {
pr_info("event trace: Could not activate" pr_info("event trace: Could not activate"
"syscall entry trace point"); "syscall entry trace point");
...@@ -505,7 +506,7 @@ void unreg_prof_syscall_exit(char *name) ...@@ -505,7 +506,7 @@ void unreg_prof_syscall_exit(char *name)
sys_prof_refcount_exit--; sys_prof_refcount_exit--;
clear_bit(num, enabled_prof_exit_syscalls); clear_bit(num, enabled_prof_exit_syscalls);
if (!sys_prof_refcount_exit) if (!sys_prof_refcount_exit)
unregister_trace_syscall_exit(prof_syscall_exit); unregister_trace_sys_exit(prof_syscall_exit);
mutex_unlock(&syscall_trace_lock); mutex_unlock(&syscall_trace_lock);
} }
......
...@@ -243,6 +243,11 @@ static void set_tracepoint(struct tracepoint_entry **entry, ...@@ -243,6 +243,11 @@ static void set_tracepoint(struct tracepoint_entry **entry,
{ {
WARN_ON(strcmp((*entry)->name, elem->name) != 0); WARN_ON(strcmp((*entry)->name, elem->name) != 0);
if (elem->regfunc && !elem->state && active)
elem->regfunc();
else if (elem->unregfunc && elem->state && !active)
elem->unregfunc();
/* /*
* rcu_assign_pointer has a smp_wmb() which makes sure that the new * rcu_assign_pointer has a smp_wmb() which makes sure that the new
* probe callbacks array is consistent before setting a pointer to it. * probe callbacks array is consistent before setting a pointer to it.
...@@ -262,6 +267,9 @@ static void set_tracepoint(struct tracepoint_entry **entry, ...@@ -262,6 +267,9 @@ static void set_tracepoint(struct tracepoint_entry **entry,
*/ */
static void disable_tracepoint(struct tracepoint *elem) static void disable_tracepoint(struct tracepoint *elem)
{ {
if (elem->unregfunc && elem->state)
elem->unregfunc();
elem->state = 0; elem->state = 0;
rcu_assign_pointer(elem->funcs, NULL); rcu_assign_pointer(elem->funcs, NULL);
} }
...@@ -576,9 +584,9 @@ __initcall(init_tracepoints); ...@@ -576,9 +584,9 @@ __initcall(init_tracepoints);
#endif /* CONFIG_MODULES */ #endif /* CONFIG_MODULES */
#ifdef CONFIG_FTRACE_SYSCALLS #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
static DEFINE_MUTEX(regfunc_mutex); /* NB: reg/unreg are called while guarded with the tracepoints_mutex */
static int sys_tracepoint_refcount; static int sys_tracepoint_refcount;
void syscall_regfunc(void) void syscall_regfunc(void)
...@@ -586,16 +594,14 @@ void syscall_regfunc(void) ...@@ -586,16 +594,14 @@ void syscall_regfunc(void)
unsigned long flags; unsigned long flags;
struct task_struct *g, *t; struct task_struct *g, *t;
mutex_lock(&regfunc_mutex);
if (!sys_tracepoint_refcount) { if (!sys_tracepoint_refcount) {
read_lock_irqsave(&tasklist_lock, flags); read_lock_irqsave(&tasklist_lock, flags);
do_each_thread(g, t) { do_each_thread(g, t) {
set_tsk_thread_flag(t, TIF_SYSCALL_FTRACE); set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
} while_each_thread(g, t); } while_each_thread(g, t);
read_unlock_irqrestore(&tasklist_lock, flags); read_unlock_irqrestore(&tasklist_lock, flags);
} }
sys_tracepoint_refcount++; sys_tracepoint_refcount++;
mutex_unlock(&regfunc_mutex);
} }
void syscall_unregfunc(void) void syscall_unregfunc(void)
...@@ -603,15 +609,13 @@ void syscall_unregfunc(void) ...@@ -603,15 +609,13 @@ void syscall_unregfunc(void)
unsigned long flags; unsigned long flags;
struct task_struct *g, *t; struct task_struct *g, *t;
mutex_lock(&regfunc_mutex);
sys_tracepoint_refcount--; sys_tracepoint_refcount--;
if (!sys_tracepoint_refcount) { if (!sys_tracepoint_refcount) {
read_lock_irqsave(&tasklist_lock, flags); read_lock_irqsave(&tasklist_lock, flags);
do_each_thread(g, t) { do_each_thread(g, t) {
clear_tsk_thread_flag(t, TIF_SYSCALL_FTRACE); clear_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
} while_each_thread(g, t); } while_each_thread(g, t);
read_unlock_irqrestore(&tasklist_lock, flags); read_unlock_irqrestore(&tasklist_lock, flags);
} }
mutex_unlock(&regfunc_mutex);
} }
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment