aboutsummaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2015-02-09 16:32:19 -0500
committerSteven Rostedt <rostedt@goodmis.org>2015-02-09 18:05:39 -0500
commit6adc13f8c096736957444ffa2aa11421b5671aef (patch)
tree705f6ba74c25d29405f80e339a6562c81d145018 /samples
parentc4c7eb29382c456b9be9858c357a490ae0ccd0f6 (diff)
tracing: Add TRACE_EVENT_FN example
If a function should be called before a tracepoint is enabled and/or after it is disabled, the TRACE_EVENT_FN() serves this purpose. But it is not well documented. Having it as a sample would help developers to know how to use it. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'samples')
-rw-r--r--samples/trace_events/trace-events-sample.c51
-rw-r--r--samples/trace_events/trace-events-sample.h44
2 files changed, 95 insertions, 0 deletions
diff --git a/samples/trace_events/trace-events-sample.c b/samples/trace_events/trace-events-sample.c
index c396a49b5d78..39d4484aef53 100644
--- a/samples/trace_events/trace-events-sample.c
+++ b/samples/trace_events/trace-events-sample.c
@@ -49,6 +49,52 @@ static int simple_thread(void *arg)
49} 49}
50 50
51static struct task_struct *simple_tsk; 51static struct task_struct *simple_tsk;
52static struct task_struct *simple_tsk_fn;
53
54static void simple_thread_func_fn(int cnt)
55{
56 set_current_state(TASK_INTERRUPTIBLE);
57 schedule_timeout(HZ);
58
59 /* More silly tracepoints */
60 trace_foo_bar_with_fn("Look at me", cnt);
61}
62
63static int simple_thread_fn(void *arg)
64{
65 int cnt = 0;
66
67 while (!kthread_should_stop())
68 simple_thread_func_fn(cnt++);
69
70 return 0;
71}
72
73static DEFINE_MUTEX(thread_mutex);
74
75void foo_bar_reg(void)
76{
77 pr_info("Starting thread for foo_bar_fn\n");
78 /*
79 * We shouldn't be able to start a trace when the module is
80 * unloading (there's other locks to prevent that). But
81 * for consistency sake, we still take the thread_mutex.
82 */
83 mutex_lock(&thread_mutex);
84 simple_tsk_fn = kthread_run(simple_thread_fn, NULL, "event-sample-fn");
85 mutex_unlock(&thread_mutex);
86}
87
88void foo_bar_unreg(void)
89{
90 pr_info("Killing thread for foo_bar_fn\n");
91 /* protect against module unloading */
92 mutex_lock(&thread_mutex);
93 if (simple_tsk_fn)
94 kthread_stop(simple_tsk_fn);
95 simple_tsk_fn = NULL;
96 mutex_unlock(&thread_mutex);
97}
52 98
53static int __init trace_event_init(void) 99static int __init trace_event_init(void)
54{ 100{
@@ -62,6 +108,11 @@ static int __init trace_event_init(void)
62static void __exit trace_event_exit(void) 108static void __exit trace_event_exit(void)
63{ 109{
64 kthread_stop(simple_tsk); 110 kthread_stop(simple_tsk);
111 mutex_lock(&thread_mutex);
112 if (simple_tsk_fn)
113 kthread_stop(simple_tsk_fn);
114 simple_tsk_fn = NULL;
115 mutex_unlock(&thread_mutex);
65} 116}
66 117
67module_init(trace_event_init); 118module_init(trace_event_init);
diff --git a/samples/trace_events/trace-events-sample.h b/samples/trace_events/trace-events-sample.h
index c3232340914d..d0be8411b527 100644
--- a/samples/trace_events/trace-events-sample.h
+++ b/samples/trace_events/trace-events-sample.h
@@ -270,6 +270,50 @@ TRACE_EVENT_CONDITION(foo_bar_with_cond,
270 270
271 TP_printk("foo %s %d", __get_str(foo), __entry->bar) 271 TP_printk("foo %s %d", __get_str(foo), __entry->bar)
272); 272);
273
274void foo_bar_reg(void);
275void foo_bar_unreg(void);
276
277/*
278 * Now in the case that some function needs to be called when the
279 * tracepoint is enabled and/or when it is disabled, the
280 * TRACE_EVENT_FN() serves this purpose. This is just like TRACE_EVENT()
281 * but adds two more parameters at the end:
282 *
283 * TRACE_EVENT_FN( name, proto, args, struct, assign, printk, reg, unreg)
284 *
285 * reg and unreg are functions with the prototype of:
286 *
287 * void reg(void)
288 *
289 * The reg function gets called before the tracepoint is enabled, and
290 * the unreg function gets called after the tracepoint is disabled.
291 *
292 * Note, reg and unreg are allowed to be NULL. If you only need to
293 * call a function before enabling, or after disabling, just set one
294 * function and pass in NULL for the other parameter.
295 */
296TRACE_EVENT_FN(foo_bar_with_fn,
297
298 TP_PROTO(const char *foo, int bar),
299
300 TP_ARGS(foo, bar),
301
302 TP_STRUCT__entry(
303 __string( foo, foo )
304 __field( int, bar )
305 ),
306
307 TP_fast_assign(
308 __assign_str(foo, foo);
309 __entry->bar = bar;
310 ),
311
312 TP_printk("foo %s %d", __get_str(foo), __entry->bar),
313
314 foo_bar_reg, foo_bar_unreg
315);
316
273#endif 317#endif
274 318
275/***** NOTICE! The #if protection ends here. *****/ 319/***** NOTICE! The #if protection ends here. *****/