58979e99e219fe40c10448f087d176591a6a08b0
[lttng-docs.git] / contents / using-lttng / instrumenting / instrumenting-linux-kernel / instrumenting-linux-kernel-itself / mainline-trace-event.md
1 ---
2 id: mainline-trace-event
3 ---
4
5 The first step is to define tracepoints using the mainline Linux
6 `TRACE_EVENT()` macro and insert tracepoints where you want them.
7 Your tracepoint definitions reside in a header file in
8 `include/trace/events`. If you're adding tracepoints to an existing
9 subsystem, edit its appropriate header file.
10
11 As an example, the following header file (let's call it
12 `include/trace/events/hello.h`) defines one tracepoint using
13 `TRACE_EVENT()`:
14
15 ~~~ c
16 /* subsystem name is "hello" */
17 #undef TRACE_SYSTEM
18 #define TRACE_SYSTEM hello
19
20 #if !defined(_TRACE_HELLO_H) || defined(TRACE_HEADER_MULTI_READ)
21 #define _TRACE_HELLO_H
22
23 #include <linux/tracepoint.h>
24
25 TRACE_EVENT(
26 /* "hello" is the subsystem name, "world" is the event name */
27 hello_world,
28
29 /* tracepoint function prototype */
30 TP_PROTO(int foo, const char* bar),
31
32 /* arguments for this tracepoint */
33 TP_ARGS(foo, bar),
34
35 /* LTTng doesn't need those */
36 TP_STRUCT__entry(),
37 TP_fast_assign(),
38 TP_printk("", 0)
39 );
40
41 #endif
42
43 /* this part must be outside protection */
44 #include <trace/define_trace.h>
45 ~~~
46
47 Notice that we don't use any of the last three arguments: they
48 are left empty here because LTTng doesn't need them. You would only fill
49 `TP_STRUCT__entry()`, `TP_fast_assign()` and `TP_printk()` if you were
50 to also use this tracepoint for ftrace/perf.
51
52 Once this is done, you may place calls to `trace_hello_world()`
53 wherever you want in the Linux source code. As an example, let us place
54 such a tracepoint in the `usb_probe_device()` static function
55 (`drivers/usb/core/driver.c`):
56
57 ~~~ c
58 /* called from driver core with dev locked */
59 static int usb_probe_device(struct device *dev)
60 {
61 struct usb_device_driver *udriver = to_usb_device_driver(dev->driver);
62 struct usb_device *udev = to_usb_device(dev);
63 int error = 0;
64
65 trace_hello_world(udev->devnum, udev->product);
66
67 /* ... */
68 }
69 ~~~
70
71 This tracepoint should fire every time a USB device is plugged in.
72
73 At the top of `driver.c`, we need to include our actual tracepoint
74 definition and, in this case (one place per subsystem), define
75 `CREATE_TRACE_POINTS`, which creates our tracepoint:
76
77 ~~~ c
78 /* ... */
79
80 #include "usb.h"
81
82 #define CREATE_TRACE_POINTS
83 #include <trace/events/hello.h>
84
85 /* ... */
86 ~~~
87
88 Build your custom Linux kernel. In order to use LTTng, make sure the
89 following kernel configuration options are enabled:
90
91 * `CONFIG_MODULES` (loadable module support)
92 * `CONFIG_KALLSYMS` (load all symbols for debugging/kksymoops)
93 * `CONFIG_HIGH_RES_TIMERS` (high resolution timer support)
94 * `CONFIG_TRACEPOINTS` (kernel tracepoint instrumentation)
95
96 Boot the custom kernel. The directory
97 `/sys/kernel/debug/tracing/events/hello` should exist if everything
98 went right, with a `hello_world` subdirectory.
This page took 0.031664 seconds and 3 git commands to generate.