aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-11 16:24:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-11 16:24:03 -0400
commit483e3cd6a34ad2d7e41100bc1b98614ac42a4567 (patch)
treeef544ccdd1e95991c32fd8b656714583b7398371 /include/linux
parent774a694f8cd08115d130a290d73c6d8563f26b1b (diff)
parentd28daf923ac5e4a0d7cecebae56f3e339189366b (diff)
Merge branch 'tracing-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'tracing-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (105 commits) ring-buffer: only enable ring_buffer_swap_cpu when needed ring-buffer: check for swapped buffers in start of committing tracing: report error in trace if we fail to swap latency buffer tracing: add trace_array_printk for internal tracers to use tracing: pass around ring buffer instead of tracer tracing: make tracing_reset safe for external use tracing: use timestamp to determine start of latency traces tracing: Remove mentioning of legacy latency_trace file from documentation tracing/filters: Defer pred allocation, fix memory leak tracing: remove users of tracing_reset tracing: disable buffers and synchronize_sched before resetting tracing: disable update max tracer while reading trace tracing: print out start and stop in latency traces ring-buffer: disable all cpu buffers when one finds a problem ring-buffer: do not count discarded events ring-buffer: remove ring_buffer_event_discard ring-buffer: fix ring_buffer_read crossing pages ring-buffer: remove unnecessary cpu_relax ring-buffer: do not swap buffers during a commit ring-buffer: do not reset while in a commit ...
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/ftrace_event.h51
-rw-r--r--include/linux/module.h14
-rw-r--r--include/linux/perf_counter.h2
-rw-r--r--include/linux/ring_buffer.h24
-rw-r--r--include/linux/syscalls.h131
-rw-r--r--include/linux/tracepoint.h29
6 files changed, 207 insertions, 44 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index a81170de7f6b..23f7179bf74e 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -93,16 +93,22 @@ void tracing_generic_entry_update(struct trace_entry *entry,
93 unsigned long flags, 93 unsigned long flags,
94 int pc); 94 int pc);
95struct ring_buffer_event * 95struct ring_buffer_event *
96trace_current_buffer_lock_reserve(int type, unsigned long len, 96trace_current_buffer_lock_reserve(struct ring_buffer **current_buffer,
97 int type, unsigned long len,
97 unsigned long flags, int pc); 98 unsigned long flags, int pc);
98void trace_current_buffer_unlock_commit(struct ring_buffer_event *event, 99void trace_current_buffer_unlock_commit(struct ring_buffer *buffer,
100 struct ring_buffer_event *event,
99 unsigned long flags, int pc); 101 unsigned long flags, int pc);
100void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event, 102void trace_nowake_buffer_unlock_commit(struct ring_buffer *buffer,
103 struct ring_buffer_event *event,
101 unsigned long flags, int pc); 104 unsigned long flags, int pc);
102void trace_current_buffer_discard_commit(struct ring_buffer_event *event); 105void trace_current_buffer_discard_commit(struct ring_buffer *buffer,
106 struct ring_buffer_event *event);
103 107
104void tracing_record_cmdline(struct task_struct *tsk); 108void tracing_record_cmdline(struct task_struct *tsk);
105 109
110struct event_filter;
111
106struct ftrace_event_call { 112struct ftrace_event_call {
107 struct list_head list; 113 struct list_head list;
108 char *name; 114 char *name;
@@ -110,16 +116,18 @@ struct ftrace_event_call {
110 struct dentry *dir; 116 struct dentry *dir;
111 struct trace_event *event; 117 struct trace_event *event;
112 int enabled; 118 int enabled;
113 int (*regfunc)(void); 119 int (*regfunc)(void *);
114 void (*unregfunc)(void); 120 void (*unregfunc)(void *);
115 int id; 121 int id;
116 int (*raw_init)(void); 122 int (*raw_init)(void);
117 int (*show_format)(struct trace_seq *s); 123 int (*show_format)(struct ftrace_event_call *call,
118 int (*define_fields)(void); 124 struct trace_seq *s);
125 int (*define_fields)(struct ftrace_event_call *);
119 struct list_head fields; 126 struct list_head fields;
120 int filter_active; 127 int filter_active;
121 void *filter; 128 struct event_filter *filter;
122 void *mod; 129 void *mod;
130 void *data;
123 131
124 atomic_t profile_count; 132 atomic_t profile_count;
125 int (*profile_enable)(struct ftrace_event_call *); 133 int (*profile_enable)(struct ftrace_event_call *);
@@ -129,15 +137,25 @@ struct ftrace_event_call {
129#define MAX_FILTER_PRED 32 137#define MAX_FILTER_PRED 32
130#define MAX_FILTER_STR_VAL 128 138#define MAX_FILTER_STR_VAL 128
131 139
132extern int init_preds(struct ftrace_event_call *call);
133extern void destroy_preds(struct ftrace_event_call *call); 140extern void destroy_preds(struct ftrace_event_call *call);
134extern int filter_match_preds(struct ftrace_event_call *call, void *rec); 141extern int filter_match_preds(struct ftrace_event_call *call, void *rec);
135extern int filter_current_check_discard(struct ftrace_event_call *call, 142extern int filter_current_check_discard(struct ring_buffer *buffer,
143 struct ftrace_event_call *call,
136 void *rec, 144 void *rec,
137 struct ring_buffer_event *event); 145 struct ring_buffer_event *event);
138 146
139extern int trace_define_field(struct ftrace_event_call *call, char *type, 147enum {
140 char *name, int offset, int size, int is_signed); 148 FILTER_OTHER = 0,
149 FILTER_STATIC_STRING,
150 FILTER_DYN_STRING,
151 FILTER_PTR_STRING,
152};
153
154extern int trace_define_field(struct ftrace_event_call *call,
155 const char *type, const char *name,
156 int offset, int size, int is_signed,
157 int filter_type);
158extern int trace_define_common_fields(struct ftrace_event_call *call);
141 159
142#define is_signed_type(type) (((type)(-1)) < 0) 160#define is_signed_type(type) (((type)(-1)) < 0)
143 161
@@ -162,11 +180,4 @@ do { \
162 __trace_printk(ip, fmt, ##args); \ 180 __trace_printk(ip, fmt, ##args); \
163} while (0) 181} while (0)
164 182
165#define __common_field(type, item, is_signed) \
166 ret = trace_define_field(event_call, #type, "common_" #item, \
167 offsetof(typeof(field.ent), item), \
168 sizeof(field.ent.item), is_signed); \
169 if (ret) \
170 return ret;
171
172#endif /* _LINUX_FTRACE_EVENT_H */ 183#endif /* _LINUX_FTRACE_EVENT_H */
diff --git a/include/linux/module.h b/include/linux/module.h
index 098bdb7bfacf..f8f92d015efe 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -17,10 +17,12 @@
17#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
18#include <linux/marker.h> 18#include <linux/marker.h>
19#include <linux/tracepoint.h> 19#include <linux/tracepoint.h>
20#include <asm/local.h>
21 20
21#include <asm/local.h>
22#include <asm/module.h> 22#include <asm/module.h>
23 23
24#include <trace/events/module.h>
25
24/* Not Yet Implemented */ 26/* Not Yet Implemented */
25#define MODULE_SUPPORTED_DEVICE(name) 27#define MODULE_SUPPORTED_DEVICE(name)
26 28
@@ -462,7 +464,10 @@ static inline local_t *__module_ref_addr(struct module *mod, int cpu)
462static inline void __module_get(struct module *module) 464static inline void __module_get(struct module *module)
463{ 465{
464 if (module) { 466 if (module) {
465 local_inc(__module_ref_addr(module, get_cpu())); 467 unsigned int cpu = get_cpu();
468 local_inc(__module_ref_addr(module, cpu));
469 trace_module_get(module, _THIS_IP_,
470 local_read(__module_ref_addr(module, cpu)));
466 put_cpu(); 471 put_cpu();
467 } 472 }
468} 473}
@@ -473,8 +478,11 @@ static inline int try_module_get(struct module *module)
473 478
474 if (module) { 479 if (module) {
475 unsigned int cpu = get_cpu(); 480 unsigned int cpu = get_cpu();
476 if (likely(module_is_live(module))) 481 if (likely(module_is_live(module))) {
477 local_inc(__module_ref_addr(module, cpu)); 482 local_inc(__module_ref_addr(module, cpu));
483 trace_module_get(module, _THIS_IP_,
484 local_read(__module_ref_addr(module, cpu)));
485 }
478 else 486 else
479 ret = 0; 487 ret = 0;
480 put_cpu(); 488 put_cpu();
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
index e022b847c90d..972f90d7a32f 100644
--- a/include/linux/perf_counter.h
+++ b/include/linux/perf_counter.h
@@ -766,6 +766,8 @@ extern int sysctl_perf_counter_mlock;
766extern int sysctl_perf_counter_sample_rate; 766extern int sysctl_perf_counter_sample_rate;
767 767
768extern void perf_counter_init(void); 768extern void perf_counter_init(void);
769extern void perf_tpcounter_event(int event_id, u64 addr, u64 count,
770 void *record, int entry_size);
769 771
770#ifndef perf_misc_flags 772#ifndef perf_misc_flags
771#define perf_misc_flags(regs) (user_mode(regs) ? PERF_EVENT_MISC_USER : \ 773#define perf_misc_flags(regs) (user_mode(regs) ? PERF_EVENT_MISC_USER : \
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index 29f8599e6bea..5fcc31ed5771 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -75,20 +75,6 @@ ring_buffer_event_time_delta(struct ring_buffer_event *event)
75} 75}
76 76
77/* 77/*
78 * ring_buffer_event_discard can discard any event in the ring buffer.
79 * it is up to the caller to protect against a reader from
80 * consuming it or a writer from wrapping and replacing it.
81 *
82 * No external protection is needed if this is called before
83 * the event is commited. But in that case it would be better to
84 * use ring_buffer_discard_commit.
85 *
86 * Note, if an event that has not been committed is discarded
87 * with ring_buffer_event_discard, it must still be committed.
88 */
89void ring_buffer_event_discard(struct ring_buffer_event *event);
90
91/*
92 * ring_buffer_discard_commit will remove an event that has not 78 * ring_buffer_discard_commit will remove an event that has not
93 * ben committed yet. If this is used, then ring_buffer_unlock_commit 79 * ben committed yet. If this is used, then ring_buffer_unlock_commit
94 * must not be called on the discarded event. This function 80 * must not be called on the discarded event. This function
@@ -154,8 +140,17 @@ unsigned long ring_buffer_size(struct ring_buffer *buffer);
154void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu); 140void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu);
155void ring_buffer_reset(struct ring_buffer *buffer); 141void ring_buffer_reset(struct ring_buffer *buffer);
156 142
143#ifdef CONFIG_RING_BUFFER_ALLOW_SWAP
157int ring_buffer_swap_cpu(struct ring_buffer *buffer_a, 144int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
158 struct ring_buffer *buffer_b, int cpu); 145 struct ring_buffer *buffer_b, int cpu);
146#else
147static inline int
148ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
149 struct ring_buffer *buffer_b, int cpu)
150{
151 return -ENODEV;
152}
153#endif
159 154
160int ring_buffer_empty(struct ring_buffer *buffer); 155int ring_buffer_empty(struct ring_buffer *buffer);
161int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu); 156int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu);
@@ -170,7 +165,6 @@ unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
170unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu); 165unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu);
171unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu); 166unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu);
172unsigned long ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu); 167unsigned long ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu);
173unsigned long ring_buffer_nmi_dropped_cpu(struct ring_buffer *buffer, int cpu);
174 168
175u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu); 169u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu);
176void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer, 170void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer,
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 80de7003d8c2..a8e37821cc60 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -64,6 +64,7 @@ struct perf_counter_attr;
64#include <linux/sem.h> 64#include <linux/sem.h>
65#include <asm/siginfo.h> 65#include <asm/siginfo.h>
66#include <asm/signal.h> 66#include <asm/signal.h>
67#include <linux/unistd.h>
67#include <linux/quota.h> 68#include <linux/quota.h>
68#include <linux/key.h> 69#include <linux/key.h>
69#include <trace/syscall.h> 70#include <trace/syscall.h>
@@ -97,6 +98,53 @@ struct perf_counter_attr;
97#define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) 98#define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__)
98#define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) 99#define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__)
99 100
101#ifdef CONFIG_EVENT_PROFILE
102#define TRACE_SYS_ENTER_PROFILE(sname) \
103static int prof_sysenter_enable_##sname(struct ftrace_event_call *event_call) \
104{ \
105 int ret = 0; \
106 if (!atomic_inc_return(&event_enter_##sname.profile_count)) \
107 ret = reg_prof_syscall_enter("sys"#sname); \
108 return ret; \
109} \
110 \
111static void prof_sysenter_disable_##sname(struct ftrace_event_call *event_call)\
112{ \
113 if (atomic_add_negative(-1, &event_enter_##sname.profile_count)) \
114 unreg_prof_syscall_enter("sys"#sname); \
115}
116
117#define TRACE_SYS_EXIT_PROFILE(sname) \
118static int prof_sysexit_enable_##sname(struct ftrace_event_call *event_call) \
119{ \
120 int ret = 0; \
121 if (!atomic_inc_return(&event_exit_##sname.profile_count)) \
122 ret = reg_prof_syscall_exit("sys"#sname); \
123 return ret; \
124} \
125 \
126static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \
127{ \
128 if (atomic_add_negative(-1, &event_exit_##sname.profile_count)) \
129 unreg_prof_syscall_exit("sys"#sname); \
130}
131
132#define TRACE_SYS_ENTER_PROFILE_INIT(sname) \
133 .profile_count = ATOMIC_INIT(-1), \
134 .profile_enable = prof_sysenter_enable_##sname, \
135 .profile_disable = prof_sysenter_disable_##sname,
136
137#define TRACE_SYS_EXIT_PROFILE_INIT(sname) \
138 .profile_count = ATOMIC_INIT(-1), \
139 .profile_enable = prof_sysexit_enable_##sname, \
140 .profile_disable = prof_sysexit_disable_##sname,
141#else
142#define TRACE_SYS_ENTER_PROFILE(sname)
143#define TRACE_SYS_ENTER_PROFILE_INIT(sname)
144#define TRACE_SYS_EXIT_PROFILE(sname)
145#define TRACE_SYS_EXIT_PROFILE_INIT(sname)
146#endif
147
100#ifdef CONFIG_FTRACE_SYSCALLS 148#ifdef CONFIG_FTRACE_SYSCALLS
101#define __SC_STR_ADECL1(t, a) #a 149#define __SC_STR_ADECL1(t, a) #a
102#define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__) 150#define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__)
@@ -112,7 +160,81 @@ struct perf_counter_attr;
112#define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) 160#define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__)
113#define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) 161#define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__)
114 162
163#define SYSCALL_TRACE_ENTER_EVENT(sname) \
164 static struct ftrace_event_call event_enter_##sname; \
165 struct trace_event enter_syscall_print_##sname = { \
166 .trace = print_syscall_enter, \
167 }; \
168 static int init_enter_##sname(void) \
169 { \
170 int num, id; \
171 num = syscall_name_to_nr("sys"#sname); \
172 if (num < 0) \
173 return -ENOSYS; \
174 id = register_ftrace_event(&enter_syscall_print_##sname);\
175 if (!id) \
176 return -ENODEV; \
177 event_enter_##sname.id = id; \
178 set_syscall_enter_id(num, id); \
179 INIT_LIST_HEAD(&event_enter_##sname.fields); \
180 return 0; \
181 } \
182 TRACE_SYS_ENTER_PROFILE(sname); \
183 static struct ftrace_event_call __used \
184 __attribute__((__aligned__(4))) \
185 __attribute__((section("_ftrace_events"))) \
186 event_enter_##sname = { \
187 .name = "sys_enter"#sname, \
188 .system = "syscalls", \
189 .event = &event_syscall_enter, \
190 .raw_init = init_enter_##sname, \
191 .show_format = syscall_enter_format, \
192 .define_fields = syscall_enter_define_fields, \
193 .regfunc = reg_event_syscall_enter, \
194 .unregfunc = unreg_event_syscall_enter, \
195 .data = "sys"#sname, \
196 TRACE_SYS_ENTER_PROFILE_INIT(sname) \
197 }
198
199#define SYSCALL_TRACE_EXIT_EVENT(sname) \
200 static struct ftrace_event_call event_exit_##sname; \
201 struct trace_event exit_syscall_print_##sname = { \
202 .trace = print_syscall_exit, \
203 }; \
204 static int init_exit_##sname(void) \
205 { \
206 int num, id; \
207 num = syscall_name_to_nr("sys"#sname); \
208 if (num < 0) \
209 return -ENOSYS; \
210 id = register_ftrace_event(&exit_syscall_print_##sname);\
211 if (!id) \
212 return -ENODEV; \
213 event_exit_##sname.id = id; \
214 set_syscall_exit_id(num, id); \
215 INIT_LIST_HEAD(&event_exit_##sname.fields); \
216 return 0; \
217 } \
218 TRACE_SYS_EXIT_PROFILE(sname); \
219 static struct ftrace_event_call __used \
220 __attribute__((__aligned__(4))) \
221 __attribute__((section("_ftrace_events"))) \
222 event_exit_##sname = { \
223 .name = "sys_exit"#sname, \
224 .system = "syscalls", \
225 .event = &event_syscall_exit, \
226 .raw_init = init_exit_##sname, \
227 .show_format = syscall_exit_format, \
228 .define_fields = syscall_exit_define_fields, \
229 .regfunc = reg_event_syscall_exit, \
230 .unregfunc = unreg_event_syscall_exit, \
231 .data = "sys"#sname, \
232 TRACE_SYS_EXIT_PROFILE_INIT(sname) \
233 }
234
115#define SYSCALL_METADATA(sname, nb) \ 235#define SYSCALL_METADATA(sname, nb) \
236 SYSCALL_TRACE_ENTER_EVENT(sname); \
237 SYSCALL_TRACE_EXIT_EVENT(sname); \
116 static const struct syscall_metadata __used \ 238 static const struct syscall_metadata __used \
117 __attribute__((__aligned__(4))) \ 239 __attribute__((__aligned__(4))) \
118 __attribute__((section("__syscalls_metadata"))) \ 240 __attribute__((section("__syscalls_metadata"))) \
@@ -121,18 +243,23 @@ struct perf_counter_attr;
121 .nb_args = nb, \ 243 .nb_args = nb, \
122 .types = types_##sname, \ 244 .types = types_##sname, \
123 .args = args_##sname, \ 245 .args = args_##sname, \
124 } 246 .enter_event = &event_enter_##sname, \
247 .exit_event = &event_exit_##sname, \
248 };
125 249
126#define SYSCALL_DEFINE0(sname) \ 250#define SYSCALL_DEFINE0(sname) \
251 SYSCALL_TRACE_ENTER_EVENT(_##sname); \
252 SYSCALL_TRACE_EXIT_EVENT(_##sname); \
127 static const struct syscall_metadata __used \ 253 static const struct syscall_metadata __used \
128 __attribute__((__aligned__(4))) \ 254 __attribute__((__aligned__(4))) \
129 __attribute__((section("__syscalls_metadata"))) \ 255 __attribute__((section("__syscalls_metadata"))) \
130 __syscall_meta_##sname = { \ 256 __syscall_meta_##sname = { \
131 .name = "sys_"#sname, \ 257 .name = "sys_"#sname, \
132 .nb_args = 0, \ 258 .nb_args = 0, \
259 .enter_event = &event_enter__##sname, \
260 .exit_event = &event_exit__##sname, \
133 }; \ 261 }; \
134 asmlinkage long sys_##sname(void) 262 asmlinkage long sys_##sname(void)
135
136#else 263#else
137#define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) 264#define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void)
138#endif 265#endif
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index b9dc4ca0246f..63a3f7a80580 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -23,6 +23,8 @@ struct tracepoint;
23struct tracepoint { 23struct tracepoint {
24 const char *name; /* Tracepoint name */ 24 const char *name; /* Tracepoint name */
25 int state; /* State. */ 25 int state; /* State. */
26 void (*regfunc)(void);
27 void (*unregfunc)(void);
26 void **funcs; 28 void **funcs;
27} __attribute__((aligned(32))); /* 29} __attribute__((aligned(32))); /*
28 * Aligned on 32 bytes because it is 30 * Aligned on 32 bytes because it is
@@ -78,12 +80,16 @@ struct tracepoint {
78 return tracepoint_probe_unregister(#name, (void *)probe);\ 80 return tracepoint_probe_unregister(#name, (void *)probe);\
79 } 81 }
80 82
81#define DEFINE_TRACE(name) \ 83
84#define DEFINE_TRACE_FN(name, reg, unreg) \
82 static const char __tpstrtab_##name[] \ 85 static const char __tpstrtab_##name[] \
83 __attribute__((section("__tracepoints_strings"))) = #name; \ 86 __attribute__((section("__tracepoints_strings"))) = #name; \
84 struct tracepoint __tracepoint_##name \ 87 struct tracepoint __tracepoint_##name \
85 __attribute__((section("__tracepoints"), aligned(32))) = \ 88 __attribute__((section("__tracepoints"), aligned(32))) = \
86 { __tpstrtab_##name, 0, NULL } 89 { __tpstrtab_##name, 0, reg, unreg, NULL }
90
91#define DEFINE_TRACE(name) \
92 DEFINE_TRACE_FN(name, NULL, NULL);
87 93
88#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \ 94#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
89 EXPORT_SYMBOL_GPL(__tracepoint_##name) 95 EXPORT_SYMBOL_GPL(__tracepoint_##name)
@@ -108,6 +114,7 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,
108 return -ENOSYS; \ 114 return -ENOSYS; \
109 } 115 }
110 116
117#define DEFINE_TRACE_FN(name, reg, unreg)
111#define DEFINE_TRACE(name) 118#define DEFINE_TRACE(name)
112#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) 119#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
113#define EXPORT_TRACEPOINT_SYMBOL(name) 120#define EXPORT_TRACEPOINT_SYMBOL(name)
@@ -158,6 +165,15 @@ static inline void tracepoint_synchronize_unregister(void)
158 165
159#define PARAMS(args...) args 166#define PARAMS(args...) args
160 167
168#endif /* _LINUX_TRACEPOINT_H */
169
170/*
171 * Note: we keep the TRACE_EVENT outside the include file ifdef protection.
172 * This is due to the way trace events work. If a file includes two
173 * trace event headers under one "CREATE_TRACE_POINTS" the first include
174 * will override the TRACE_EVENT and break the second include.
175 */
176
161#ifndef TRACE_EVENT 177#ifndef TRACE_EVENT
162/* 178/*
163 * For use with the TRACE_EVENT macro: 179 * For use with the TRACE_EVENT macro:
@@ -259,10 +275,15 @@ static inline void tracepoint_synchronize_unregister(void)
259 * can also by used by generic instrumentation like SystemTap), and 275 * can also by used by generic instrumentation like SystemTap), and
260 * it is also used to expose a structured trace record in 276 * it is also used to expose a structured trace record in
261 * /sys/kernel/debug/tracing/events/. 277 * /sys/kernel/debug/tracing/events/.
278 *
279 * A set of (un)registration functions can be passed to the variant
280 * TRACE_EVENT_FN to perform any (un)registration work.
262 */ 281 */
263 282
264#define TRACE_EVENT(name, proto, args, struct, assign, print) \ 283#define TRACE_EVENT(name, proto, args, struct, assign, print) \
265 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) 284 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
266#endif 285#define TRACE_EVENT_FN(name, proto, args, struct, \
286 assign, print, reg, unreg) \
287 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
267 288
268#endif 289#endif /* ifdef TRACE_EVENT (see note above) */