Bläddra i källkod

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: Ingo Molnar <mingo@elte.hu>
Ingo Molnar 15 år sedan
förälder
incheckning
35dce1a99d

+ 1 - 1
arch/s390/Kconfig

@@ -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

+ 1 - 1
arch/s390/defconfig

@@ -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

+ 2 - 2
arch/s390/include/asm/thread_info.h

@@ -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)
 #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)

+ 1 - 1
arch/s390/kernel/entry.S

@@ -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

+ 1 - 1
arch/s390/kernel/entry64.S

@@ -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)
 
 

+ 6 - 6
arch/s390/kernel/ptrace.c

@@ -51,8 +51,8 @@
 #include "compat_ptrace.h"
 #include "compat_ptrace.h"
 #endif
 #endif
 
 
-DEFINE_TRACE(syscall_enter);
-DEFINE_TRACE(syscall_exit);
+#define CREATE_TRACE_POINTS
+#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)
 		ret = -1;
 		ret = -1;
 	}
 	}
 
 
-	if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
-		trace_syscall_enter(regs, regs->gprs[2]);
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		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)
 		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)))
-		trace_syscall_exit(regs, regs->gprs[2]);
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		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);

+ 1 - 1
arch/x86/Kconfig

@@ -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

+ 1 - 1
arch/x86/configs/i386_defconfig

@@ -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

+ 1 - 1
arch/x86/configs/x86_64_defconfig

@@ -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

+ 7 - 6
arch/x86/include/asm/thread_info.h

@@ -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 {
 #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_AUDIT | _TIF_SECCOMP | _TIF_SINGLESTEP)
+	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_AUDIT |	\
+	 _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 {
 	   _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						\

+ 7 - 9
arch/x86/kernel/ptrace.c

@@ -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)
 	    tracehook_report_syscall_entry(regs))
 	    tracehook_report_syscall_entry(regs))
 		ret = -1L;
 		ret = -1L;
 
 
-	if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
-		trace_syscall_enter(regs, regs->orig_ax);
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		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)
 	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)))
-		trace_syscall_exit(regs, regs->ax);
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		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);

+ 18 - 28
include/linux/tracepoint.h

@@ -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 {
  * 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 {
 	}								\
 	}								\
 	static inline int register_trace_##name(void (*probe)(proto))	\
 	static inline int register_trace_##name(void (*probe)(proto))	\
 	{								\
 	{								\
-		int ret;						\
-		void (*func)(void) = reg;				\
-									\
-		ret = tracepoint_probe_register(#name, (void *)probe);	\
-		if (func && !ret)					\
-			func();						\
-		return ret;						\
+		return tracepoint_probe_register(#name, (void *)probe);	\
 	}								\
 	}								\
 	static inline int unregister_trace_##name(void (*probe)(proto))	\
 	static inline int unregister_trace_##name(void (*probe)(proto))	\
 	{								\
 	{								\
-		int ret;						\
-		void (*func)(void) = unreg;				\
-									\
-		ret = tracepoint_probe_unregister(#name, (void *)probe);\
-		if (func && !ret)					\
-			func();						\
-		return ret;						\
+		return tracepoint_probe_unregister(#name, (void *)probe);\
 	}
 	}
 
 
 
 
-#define DECLARE_TRACE(name, proto, args)				 \
-	DECLARE_TRACE_WITH_CALLBACK(name, TP_PROTO(proto), TP_ARGS(args),\
-					NULL, NULL);
-
-#define DEFINE_TRACE(name)						\
+#define DEFINE_TRACE_FN(name, reg, unreg)				\
 	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,
 	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,
 		return -ENOSYS;						\
 		return -ENOSYS;						\
 	}
 	}
 
 
-#define DECLARE_TRACE(name, proto, args)				 \
-	DECLARE_TRACE_WITH_CALLBACK(name, TP_PROTO(proto), TP_ARGS(args),\
-					NULL, NULL);
-
+#define DEFINE_TRACE_FN(name, reg, unreg)
 #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)
  * 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) */

+ 5 - 0
include/trace/define_trace.h

@@ -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)

+ 70 - 0
include/trace/events/syscalls.h

@@ -0,0 +1,70 @@
+#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>
+

+ 9 - 0
include/trace/ftrace.h

@@ -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)
 
 
 
 

+ 0 - 17
include/trace/syscall.h

@@ -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.
  *
  *

+ 2 - 2
kernel/trace/Kconfig

@@ -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
 
 
 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

+ 9 - 8
kernel/trace/trace_syscalls.c

@@ -1,4 +1,5 @@
 #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)
 		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)
 	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)
 		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)
 	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)
 
 
 	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)
 	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)
 
 
 	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)
 	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);
 }
 }
 
 

+ 12 - 8
kernel/tracepoint.c

@@ -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,
  */
  */
 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);
 
 
 #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)
 	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)
 	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