1 commit 2c2a566b64b4254c530fb0c2222b30e8a739bac9
2 Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 Date: Sat Sep 1 17:45:09 2012 -0700
5 tracing: Let tracepoints have data passed to tracepoint callbacks (backport)
7 Backport of commit 38516ab59fbc5b3bb278cf5e1fe2867c70cff32e for
8 2.6.34.x. Keeping kABI compatibility.
10 Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
13 include/linux/tracepoint.h | 149 +++++++++++++++++++++++++--------
14 kernel/tracepoint.c | 144 ++++++++++++++++++++++---------
15 samples/tracepoints/tp-samples-trace.h | 4 +-
16 3 files changed, 220 insertions(+), 77 deletions(-)
18 Index: linux/include/linux/tracepoint.h
19 ===================================================================
20 --- linux.orig/include/linux/tracepoint.h
21 +++ linux/include/linux/tracepoint.h
26 +#define HAVE_KABI_2635_TRACEPOINT
28 +struct tracepoint_func {
35 const char *name; /* Tracepoint name */
36 int state; /* State. */
37 void (*regfunc)(void);
38 void (*unregfunc)(void);
40 + struct tracepoint_func *funcs;
41 } __attribute__((aligned(32))); /*
42 * Aligned on 32 bytes because it is
43 * globally visible and gcc happily
44 @@ -43,17 +51,33 @@ struct tracepoint {
46 * it_func[0] is never NULL because there is at least one element in the array
47 * when the array itself is non NULL.
49 -#define __DO_TRACE(tp, proto, args) \
53 + * Note, the proto and args passed in includes "__data" as the first parameter.
54 + * The reason for this is to handle the "void" prototype. If a tracepoint
55 + * has a "void" prototype, then it is invalid to declare a function
56 + * as "(void *, void)". The DECLARE_TRACE_NOARGS() will pass in just
57 + * "void *data", where as the DECLARE_TRACE() will pass in "void *data, proto".
59 +#define __DO_TRACE(tp, data_proto, data_args, proto, args) \
61 + struct tracepoint_func *it_func_ptr; \
64 + rcu_read_lock_sched_notrace(); \
65 + it_func_ptr = rcu_dereference_sched((tp)->funcs); \
66 + if (it_func_ptr) { \
68 + if (it_func_ptr->kabi_2635) { \
71 - rcu_read_lock_sched_notrace(); \
72 - it_func = rcu_dereference_sched((tp)->funcs); \
75 - ((void(*)(proto))(*it_func))(args); \
76 - } while (*(++it_func)); \
77 + it_func = (it_func_ptr)->func; \
78 + __data = (it_func_ptr)->data; \
79 + ((void(*)(data_proto))(it_func))(data_args); \
81 + it_func = (it_func_ptr)->func; \
82 + ((void(*)(proto))(it_func))(args); \
84 + } while ((++it_func_ptr)->func); \
86 rcu_read_unlock_sched_notrace(); \
88 @@ -63,22 +87,39 @@ struct tracepoint {
89 * not add unwanted padding between the beginning of the section and the
90 * structure. Force alignment to the same alignment as the section start.
92 -#define DECLARE_TRACE(name, proto, args) \
93 +#define __DECLARE_TRACE(name, proto, args, data_proto, data_args) \
94 extern struct tracepoint __tracepoint_##name; \
95 static inline void trace_##name(proto) \
97 if (unlikely(__tracepoint_##name.state)) \
98 __DO_TRACE(&__tracepoint_##name, \
99 - TP_PROTO(proto), TP_ARGS(args)); \
100 + TP_PROTO(data_proto), \
101 + TP_ARGS(data_args), \
105 - static inline int register_trace_##name(void (*probe)(proto)) \
107 + static inline int \
108 + register_trace_##name(void (*probe)(proto)) \
110 return tracepoint_probe_register(#name, (void *)probe); \
112 - static inline int unregister_trace_##name(void (*probe)(proto)) \
114 - return tracepoint_probe_unregister(#name, (void *)probe);\
117 + static inline int \
118 + unregister_trace_##name(void (*probe)(proto)) \
120 + return tracepoint_probe_unregister(#name, (void *)probe); \
122 + static inline int \
123 + kabi_2635_register_trace_##name(void (*probe)(data_proto), void *data) \
125 + return kabi_2635_tracepoint_probe_register(#name, (void *)probe, \
128 + static inline int \
129 + kabi_2635_unregister_trace_##name(void (*probe)(data_proto), void *data) \
131 + return kabi_2635_tracepoint_probe_unregister(#name, (void *)probe, \
136 #define DEFINE_TRACE_FN(name, reg, unreg) \
137 @@ -100,19 +141,29 @@ extern void tracepoint_update_probe_rang
138 struct tracepoint *end);
140 #else /* !CONFIG_TRACEPOINTS */
141 -#define DECLARE_TRACE(name, proto, args) \
142 - static inline void _do_trace_##name(struct tracepoint *tp, proto) \
144 - static inline void trace_##name(proto) \
146 - static inline int register_trace_##name(void (*probe)(proto)) \
150 - static inline int unregister_trace_##name(void (*probe)(proto)) \
154 +#define __DECLARE_TRACE(name, proto, args, data_proto, data_args) \
155 + static inline void trace_##name(proto) \
157 + static inline int \
158 + register_trace_##name(void (*probe)(proto)) \
162 + static inline int \
163 + unregister_trace_##name(void (*probe)(proto)) \
167 + static inline int \
168 + kabi_2635_register_trace_##name(void (*probe)(data_proto), void *data) \
172 + static inline int \
173 + kabi_2635_unregister_trace_##name(void (*probe)(data_proto), void *data) \
178 #define DEFINE_TRACE_FN(name, reg, unreg)
179 #define DEFINE_TRACE(name)
180 @@ -123,6 +174,28 @@ static inline void tracepoint_update_pro
181 struct tracepoint *end)
183 #endif /* CONFIG_TRACEPOINTS */
186 + * The need for the DECLARE_TRACE_NOARGS() is to handle the prototype
187 + * (void). "void" is a special value in a function prototype and can
188 + * not be combined with other arguments. Since the DECLARE_TRACE()
189 + * macro adds a data element at the beginning of the prototype,
190 + * we need a way to differentiate "(void *data, proto)" from
191 + * "(void *data, void)". The second prototype is invalid.
193 + * DECLARE_TRACE_NOARGS() passes "void" as the tracepoint prototype
194 + * and "void *__data" as the callback prototype.
196 + * DECLARE_TRACE() passes "proto" as the tracepoint protoype and
197 + * "void *__data, proto" as the callback prototype.
199 +#define DECLARE_TRACE_NOARGS(name) \
200 + __DECLARE_TRACE(name, void, , void *__data, __data)
201 +#define DECLARE_TRACE(name, proto, args) \
202 + __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \
203 + PARAMS(void *__data, proto), \
204 + PARAMS(__data, args))
206 #endif /* DECLARE_TRACE */
209 @@ -130,15 +203,23 @@ static inline void tracepoint_update_pro
210 * Internal API, should not be used directly.
212 extern int tracepoint_probe_register(const char *name, void *probe);
213 +extern int kabi_2635_tracepoint_probe_register(const char *name, void *probe, void *data);
216 * Disconnect a probe from a tracepoint.
217 * Internal API, should not be used directly.
219 -extern int tracepoint_probe_unregister(const char *name, void *probe);
221 +tracepoint_probe_unregister(const char *name, void *probe);
223 +kabi_2635_tracepoint_probe_unregister(const char *name, void *probe, void *data);
225 extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
226 +extern int kabi_2635_tracepoint_probe_register_noupdate(const char *name, void *probe,
228 extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
229 +extern int kabi_2635_tracepoint_probe_unregister_noupdate(const char *name, void *probe,
231 extern void tracepoint_probe_update_all(void);
233 struct tracepoint_iter {
234 Index: linux/kernel/tracepoint.c
235 ===================================================================
236 --- linux.orig/kernel/tracepoint.c
237 +++ linux/kernel/tracepoint.c
238 @@ -54,7 +54,7 @@ static struct hlist_head tracepoint_tabl
240 struct tracepoint_entry {
241 struct hlist_node hlist;
243 + struct tracepoint_func *funcs;
244 int refcount; /* Number of times armed. 0 if disarmed. */
247 @@ -64,12 +64,12 @@ struct tp_probes {
249 struct list_head list;
252 + struct tracepoint_func probes[0];
255 static inline void *allocate_probes(int count)
257 - struct tp_probes *p = kmalloc(count * sizeof(void *)
258 + struct tp_probes *p = kmalloc(count * sizeof(struct tracepoint_func)
259 + sizeof(struct tp_probes), GFP_KERNEL);
260 return p == NULL ? NULL : p->probes;
262 @@ -79,7 +79,7 @@ static void rcu_free_old_probes(struct r
263 kfree(container_of(head, struct tp_probes, u.rcu));
266 -static inline void release_probes(void *old)
267 +static inline void release_probes(struct tracepoint_func *old)
270 struct tp_probes *tp_probes = container_of(old,
271 @@ -95,15 +95,16 @@ static void debug_print_probes(struct tr
272 if (!tracepoint_debug || !entry->funcs)
275 - for (i = 0; entry->funcs[i]; i++)
276 - printk(KERN_DEBUG "Probe %d : %p\n", i, entry->funcs[i]);
277 + for (i = 0; entry->funcs[i].func; i++)
278 + printk(KERN_DEBUG "Probe %d : %p\n", i, entry->funcs[i].func);
282 -tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe)
283 +static struct tracepoint_func *
284 +tracepoint_entry_add_probe(struct tracepoint_entry *entry,
285 + void *probe, void *data, bool kabi_2635)
289 + struct tracepoint_func *old, *new;
293 @@ -111,8 +112,9 @@ tracepoint_entry_add_probe(struct tracep
296 /* (N -> N+1), (N != 0, 1) probes */
297 - for (nr_probes = 0; old[nr_probes]; nr_probes++)
298 - if (old[nr_probes] == probe)
299 + for (nr_probes = 0; old[nr_probes].func; nr_probes++)
300 + if (old[nr_probes].func == probe &&
301 + old[nr_probes].data == data)
302 return ERR_PTR(-EEXIST);
304 /* + 2 : one for new probe, one for NULL func */
305 @@ -120,9 +122,11 @@ tracepoint_entry_add_probe(struct tracep
307 return ERR_PTR(-ENOMEM);
309 - memcpy(new, old, nr_probes * sizeof(void *));
310 - new[nr_probes] = probe;
311 - new[nr_probes + 1] = NULL;
312 + memcpy(new, old, nr_probes * sizeof(struct tracepoint_func));
313 + new[nr_probes].func = probe;
314 + new[nr_probes].data = data;
315 + new[nr_probes].kabi_2635 = kabi_2635;
316 + new[nr_probes + 1].func = NULL;
317 entry->refcount = nr_probes + 1;
319 debug_print_probes(entry);
320 @@ -130,10 +134,11 @@ tracepoint_entry_add_probe(struct tracep
324 -tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
325 +tracepoint_entry_remove_probe(struct tracepoint_entry *entry,
326 + void *probe, void *data)
328 int nr_probes = 0, nr_del = 0, i;
330 + struct tracepoint_func *old, *new;
334 @@ -142,8 +147,10 @@ tracepoint_entry_remove_probe(struct tra
336 debug_print_probes(entry);
337 /* (N -> M), (N > 1, M >= 0) probes */
338 - for (nr_probes = 0; old[nr_probes]; nr_probes++) {
339 - if ((!probe || old[nr_probes] == probe))
340 + for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
342 + (old[nr_probes].func == probe &&
343 + old[nr_probes].data == data))
347 @@ -160,10 +167,11 @@ tracepoint_entry_remove_probe(struct tra
348 new = allocate_probes(nr_probes - nr_del + 1);
350 return ERR_PTR(-ENOMEM);
351 - for (i = 0; old[i]; i++)
352 - if ((probe && old[i] != probe))
353 + for (i = 0; old[i].func; i++)
355 + (old[i].func != probe || old[i].data != data))
357 - new[nr_probes - nr_del] = NULL;
358 + new[nr_probes - nr_del].func = NULL;
359 entry->refcount = nr_probes - nr_del;
362 @@ -315,18 +323,19 @@ static void tracepoint_update_probes(voi
363 module_update_tracepoints();
366 -static void *tracepoint_add_probe(const char *name, void *probe)
367 +static struct tracepoint_func *
368 +tracepoint_add_probe(const char *name, void *probe, void *data, bool kabi_2635)
370 struct tracepoint_entry *entry;
372 + struct tracepoint_func *old;
374 entry = get_tracepoint(name);
376 entry = add_tracepoint(name);
379 + return (struct tracepoint_func *)entry;
381 - old = tracepoint_entry_add_probe(entry, probe);
382 + old = tracepoint_entry_add_probe(entry, probe, data, kabi_2635);
383 if (IS_ERR(old) && !entry->refcount)
384 remove_tracepoint(entry);
386 @@ -340,12 +349,14 @@ static void *tracepoint_add_probe(const
387 * Returns 0 if ok, error value on error.
388 * The probe address must at least be aligned on the architecture pointer size.
390 -int tracepoint_probe_register(const char *name, void *probe)
392 +int ___tracepoint_probe_register(const char *name, void *probe, void *data,
396 + struct tracepoint_func *old;
398 mutex_lock(&tracepoints_mutex);
399 - old = tracepoint_add_probe(name, probe);
400 + old = tracepoint_add_probe(name, probe, data, kabi_2635);
401 mutex_unlock(&tracepoints_mutex);
404 @@ -354,17 +365,30 @@ int tracepoint_probe_register(const char
409 +int kabi_2635_tracepoint_probe_register(const char *name, void *probe, void *data)
411 + return ___tracepoint_probe_register(name, probe, data, 1);
413 +EXPORT_SYMBOL_GPL(kabi_2635_tracepoint_probe_register);
416 +int tracepoint_probe_register(const char *name, void *probe)
418 + return ___tracepoint_probe_register(name, probe, NULL, 0);
420 EXPORT_SYMBOL_GPL(tracepoint_probe_register);
422 -static void *tracepoint_remove_probe(const char *name, void *probe)
423 +static struct tracepoint_func *
424 +tracepoint_remove_probe(const char *name, void *probe, void *data)
426 struct tracepoint_entry *entry;
428 + struct tracepoint_func *old;
430 entry = get_tracepoint(name);
432 return ERR_PTR(-ENOENT);
433 - old = tracepoint_entry_remove_probe(entry, probe);
434 + old = tracepoint_entry_remove_probe(entry, probe, data);
437 if (!entry->refcount)
438 @@ -382,12 +406,13 @@ static void *tracepoint_remove_probe(con
439 * itself uses stop_machine(), which insures that every preempt disabled section
442 -int tracepoint_probe_unregister(const char *name, void *probe)
444 +int ___tracepoint_probe_unregister(const char *name, void *probe, void *data)
447 + struct tracepoint_func *old;
449 mutex_lock(&tracepoints_mutex);
450 - old = tracepoint_remove_probe(name, probe);
451 + old = tracepoint_remove_probe(name, probe, data);
452 mutex_unlock(&tracepoints_mutex);
455 @@ -396,6 +421,17 @@ int tracepoint_probe_unregister(const ch
460 +int kabi_2635_tracepoint_probe_unregister(const char *name, void *probe, void *data)
462 + return ___tracepoint_probe_unregister(name, probe, data);
464 +EXPORT_SYMBOL_GPL(kabi_2635_tracepoint_probe_unregister);
466 +int tracepoint_probe_unregister(const char *name, void *probe)
468 + return ___tracepoint_probe_unregister(name, probe, NULL);
470 EXPORT_SYMBOL_GPL(tracepoint_probe_unregister);
472 static LIST_HEAD(old_probes);
473 @@ -418,12 +454,14 @@ static void tracepoint_add_old_probes(vo
475 * caller must call tracepoint_probe_update_all()
477 -int tracepoint_probe_register_noupdate(const char *name, void *probe)
479 +int ___tracepoint_probe_register_noupdate(const char *name, void *probe,
480 + void *data, bool kabi_2635)
483 + struct tracepoint_func *old;
485 mutex_lock(&tracepoints_mutex);
486 - old = tracepoint_add_probe(name, probe);
487 + old = tracepoint_add_probe(name, probe, data, kabi_2635);
489 mutex_unlock(&tracepoints_mutex);
491 @@ -432,6 +470,18 @@ int tracepoint_probe_register_noupdate(c
492 mutex_unlock(&tracepoints_mutex);
496 +int kabi_2635_tracepoint_probe_register_noupdate(const char *name, void *probe,
499 + return ___tracepoint_probe_register_noupdate(name, probe, data, 1);
501 +EXPORT_SYMBOL_GPL(kabi_2635_tracepoint_probe_register_noupdate);
503 +int tracepoint_probe_register_noupdate(const char *name, void *probe)
505 + return ___tracepoint_probe_register_noupdate(name, probe, NULL, 0);
507 EXPORT_SYMBOL_GPL(tracepoint_probe_register_noupdate);
510 @@ -441,12 +491,14 @@ EXPORT_SYMBOL_GPL(tracepoint_probe_regis
512 * caller must call tracepoint_probe_update_all()
514 -int tracepoint_probe_unregister_noupdate(const char *name, void *probe)
516 +int ___tracepoint_probe_unregister_noupdate(const char *name, void *probe,
520 + struct tracepoint_func *old;
522 mutex_lock(&tracepoints_mutex);
523 - old = tracepoint_remove_probe(name, probe);
524 + old = tracepoint_remove_probe(name, probe, data);
526 mutex_unlock(&tracepoints_mutex);
528 @@ -455,6 +507,18 @@ int tracepoint_probe_unregister_noupdate
529 mutex_unlock(&tracepoints_mutex);
533 +int kabi_2635_tracepoint_probe_unregister_noupdate(const char *name, void *probe,
536 + return ___tracepoint_probe_unregister_noupdate(name, probe, data);
538 +EXPORT_SYMBOL_GPL(kabi_2635_tracepoint_probe_unregister_noupdate);
540 +int tracepoint_probe_unregister_noupdate(const char *name, void *probe)
542 + return ___tracepoint_probe_unregister_noupdate(name, probe, NULL);
544 EXPORT_SYMBOL_GPL(tracepoint_probe_unregister_noupdate);
547 Index: linux/samples/tracepoints/tp-samples-trace.h
548 ===================================================================
549 --- linux.orig/samples/tracepoints/tp-samples-trace.h
550 +++ linux/samples/tracepoints/tp-samples-trace.h
552 DECLARE_TRACE(subsys_event,
553 TP_PROTO(struct inode *inode, struct file *file),
554 TP_ARGS(inode, file));
555 -DECLARE_TRACE(subsys_eventb,
558 +DECLARE_TRACE_NOARGS(subsys_eventb);