aboutsummaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-12 11:37:41 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-12 11:37:41 -0500
commit41cbc01f6e49e48bc3d78158cec0a2d4ff6c906d (patch)
treec96efc28f4b3b7d5b785fd4e4b44a0376adcfa12 /samples
parent12df4289ee8e4dccf932b7186b391bb6d2b915fa (diff)
parent1e0d6714aceb770b04161fbedd7765d0e1fc27bd (diff)
Merge tag 'trace-v3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing updates from Steven Rostedt: "The updates included in this pull request for ftrace are: o Several clean ups to the code One such clean up was to convert to 64 bit time keeping, in the ring buffer benchmark code. o Adding of __print_array() helper macro for TRACE_EVENT() o Updating the sample/trace_events/ to add samples of different ways to make trace events. Lots of features have been added since the sample code was made, and these features are mostly unknown. Developers have been making their own hacks to do things that are already available. o Performance improvements. Most notably, I found a performance bug where a waiter that is waiting for a full page from the ring buffer will see that a full page is not available, and go to sleep. The sched event caused by it going to sleep would cause it to wake up again. It would see that there was still not a full page, and go back to sleep again, and that would wake it up again, until finally it would see a full page. This change has been marked for stable. Other improvements include removing global locks from fast paths" * tag 'trace-v3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: ring-buffer: Do not wake up a splice waiter when page is not full tracing: Fix unmapping loop in tracing_mark_write tracing: Add samples of DECLARE_EVENT_CLASS() and DEFINE_EVENT() tracing: Add TRACE_EVENT_FN example tracing: Add TRACE_EVENT_CONDITION sample tracing: Update the TRACE_EVENT fields available in the sample code tracing: Separate out initializing top level dir from instances tracing: Make tracing_init_dentry_tr() static trace: Use 64-bit timekeeping tracing: Add array printing helper tracing: Remove newline from trace_printk warning banner tracing: Use IS_ERR() check for return value of tracing_init_dentry() tracing: Remove unneeded includes of debugfs.h and fs.h tracing: Remove taking of trace_types_lock in pipe files tracing: Add ref count to tracer for when they are being read by pipe
Diffstat (limited to 'samples')
-rw-r--r--samples/trace_events/trace-events-sample.c80
-rw-r--r--samples/trace_events/trace-events-sample.h328
2 files changed, 394 insertions, 14 deletions
diff --git a/samples/trace_events/trace-events-sample.c b/samples/trace_events/trace-events-sample.c
index aabc4e970911..880a7d1d27d2 100644
--- a/samples/trace_events/trace-events-sample.c
+++ b/samples/trace_events/trace-events-sample.c
@@ -10,12 +10,38 @@
10#define CREATE_TRACE_POINTS 10#define CREATE_TRACE_POINTS
11#include "trace-events-sample.h" 11#include "trace-events-sample.h"
12 12
13static const char *random_strings[] = {
14 "Mother Goose",
15 "Snoopy",
16 "Gandalf",
17 "Frodo",
18 "One ring to rule them all"
19};
13 20
14static void simple_thread_func(int cnt) 21static void simple_thread_func(int cnt)
15{ 22{
23 int array[6];
24 int len = cnt % 5;
25 int i;
26
16 set_current_state(TASK_INTERRUPTIBLE); 27 set_current_state(TASK_INTERRUPTIBLE);
17 schedule_timeout(HZ); 28 schedule_timeout(HZ);
18 trace_foo_bar("hello", cnt); 29
30 for (i = 0; i < len; i++)
31 array[i] = i + 1;
32 array[i] = 0;
33
34 /* Silly tracepoints */
35 trace_foo_bar("hello", cnt, array, random_strings[len],
36 tsk_cpus_allowed(current));
37
38 trace_foo_with_template_simple("HELLO", cnt);
39
40 trace_foo_bar_with_cond("Some times print", cnt);
41
42 trace_foo_with_template_cond("prints other times", cnt);
43
44 trace_foo_with_template_print("I have to be different", cnt);
19} 45}
20 46
21static int simple_thread(void *arg) 47static int simple_thread(void *arg)
@@ -29,6 +55,53 @@ static int simple_thread(void *arg)
29} 55}
30 56
31static struct task_struct *simple_tsk; 57static struct task_struct *simple_tsk;
58static struct task_struct *simple_tsk_fn;
59
60static void simple_thread_func_fn(int cnt)
61{
62 set_current_state(TASK_INTERRUPTIBLE);
63 schedule_timeout(HZ);
64
65 /* More silly tracepoints */
66 trace_foo_bar_with_fn("Look at me", cnt);
67 trace_foo_with_template_fn("Look at me too", cnt);
68}
69
70static int simple_thread_fn(void *arg)
71{
72 int cnt = 0;
73
74 while (!kthread_should_stop())
75 simple_thread_func_fn(cnt++);
76
77 return 0;
78}
79
80static DEFINE_MUTEX(thread_mutex);
81
82void foo_bar_reg(void)
83{
84 pr_info("Starting thread for foo_bar_fn\n");
85 /*
86 * We shouldn't be able to start a trace when the module is
87 * unloading (there's other locks to prevent that). But
88 * for consistency sake, we still take the thread_mutex.
89 */
90 mutex_lock(&thread_mutex);
91 simple_tsk_fn = kthread_run(simple_thread_fn, NULL, "event-sample-fn");
92 mutex_unlock(&thread_mutex);
93}
94
95void foo_bar_unreg(void)
96{
97 pr_info("Killing thread for foo_bar_fn\n");
98 /* protect against module unloading */
99 mutex_lock(&thread_mutex);
100 if (simple_tsk_fn)
101 kthread_stop(simple_tsk_fn);
102 simple_tsk_fn = NULL;
103 mutex_unlock(&thread_mutex);
104}
32 105
33static int __init trace_event_init(void) 106static int __init trace_event_init(void)
34{ 107{
@@ -42,6 +115,11 @@ static int __init trace_event_init(void)
42static void __exit trace_event_exit(void) 115static void __exit trace_event_exit(void)
43{ 116{
44 kthread_stop(simple_tsk); 117 kthread_stop(simple_tsk);
118 mutex_lock(&thread_mutex);
119 if (simple_tsk_fn)
120 kthread_stop(simple_tsk_fn);
121 simple_tsk_fn = NULL;
122 mutex_unlock(&thread_mutex);
45} 123}
46 124
47module_init(trace_event_init); 125module_init(trace_event_init);
diff --git a/samples/trace_events/trace-events-sample.h b/samples/trace_events/trace-events-sample.h
index 476429281389..a2c8b02b6359 100644
--- a/samples/trace_events/trace-events-sample.h
+++ b/samples/trace_events/trace-events-sample.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * If TRACE_SYSTEM is defined, that will be the directory created 2 * If TRACE_SYSTEM is defined, that will be the directory created
3 * in the ftrace directory under /sys/kernel/debug/tracing/events/<system> 3 * in the ftrace directory under /sys/kernel/tracing/events/<system>
4 * 4 *
5 * The define_trace.h below will also look for a file name of 5 * The define_trace.h below will also look for a file name of
6 * TRACE_SYSTEM.h where TRACE_SYSTEM is what is defined here. 6 * TRACE_SYSTEM.h where TRACE_SYSTEM is what is defined here.
@@ -54,45 +54,347 @@
54 * Here it is simply "foo, bar". 54 * Here it is simply "foo, bar".
55 * 55 *
56 * struct: This defines the way the data will be stored in the ring buffer. 56 * struct: This defines the way the data will be stored in the ring buffer.
57 * There are currently two types of elements. __field and __array. 57 * The items declared here become part of a special structure
58 * a __field is broken up into (type, name). Where type can be any 58 * called "__entry", which can be used in the fast_assign part of the
59 * primitive type (integer, long or pointer). __field_struct() can 59 * TRACE_EVENT macro.
60 * be any static complex data value (struct, union, but not an array). 60 *
61 * For an array. there are three fields. (type, name, size). The 61 * Here are the currently defined types you can use:
62 * type of elements in the array, the name of the field and the size 62 *
63 * of the array. 63 * __field : Is broken up into type and name. Where type can be any
64 * primitive type (integer, long or pointer).
65 *
66 * __field(int, foo)
67 *
68 * __entry->foo = 5;
69 *
70 * __field_struct : This can be any static complex data type (struct, union
71 * but not an array). Be careful using complex types, as each
72 * event is limited in size, and copying large amounts of data
73 * into the ring buffer can slow things down.
74 *
75 * __field_struct(struct bar, foo)
76 *
77 * __entry->bar.x = y;
78
79 * __array: There are three fields (type, name, size). The type is the
80 * type of elements in teh array, the name is the name of the array.
81 * size is the number of items in the array (not the total size).
82 *
83 * __array( char, foo, 10) is the same as saying: char foo[10];
84 *
85 * Assigning arrays can be done like any array:
86 *
87 * __entry->foo[0] = 'a';
88 *
89 * memcpy(__entry->foo, bar, 10);
90 *
91 * __dynamic_array: This is similar to array, but can vary is size from
92 * instance to instance of the tracepoint being called.