xref: /dpdk/doc/guides/prog_guide/trace_lib.rst (revision 9f8e1810f62bc6549fa7782e550f68130fc4ce8e)
1..  SPDX-License-Identifier: BSD-3-Clause
2    Copyright(C) 2020 Marvell International Ltd.
3
4Trace Library
5=============
6
7Overview
8--------
9
10*Tracing* is a technique used to understand what goes on in a running software
11system. The software used for tracing is called a *tracer*, which is
12conceptually similar to a tape recorder.
13When recording, specific instrumentation points placed in the software source
14code generate events that are saved on a giant tape: a trace file.
15The trace file then later can be opened in *trace viewers* to visualize and
16analyze the trace events with timestamps and multi-core views.
17Such a mechanism will be useful for resolving a wide range of problems such as
18multi-core synchronization issues, latency measurements, finding out the
19post analysis information like CPU idle time, etc that would otherwise be
20extremely challenging to get.
21
22Tracing is often compared to *logging*. However, tracers and loggers are two
23different tools, serving two different purposes.
24Tracers are designed to record much lower-level events that occur much more
25frequently than log messages, often in the range of thousands per second, with
26very little execution overhead.
27Logging is more appropriate for a very high-level analysis of less frequent
28events: user accesses, exceptional conditions (errors and warnings, for
29example), database transactions, instant messaging communications, and such.
30Simply put, logging is one of the many use cases that can be satisfied with
31tracing.
32
33DPDK tracing library features
34-----------------------------
35
36- A framework to add tracepoints in control and fast path APIs with minimum
37  impact on performance.
38  Typical trace overhead is ~20 cycles and instrumentation overhead is 1 cycle.
39- Enable and disable the tracepoints at runtime.
40- Save the trace buffer to the filesystem at any point in time.
41- Support ``overwrite`` and ``discard`` trace mode operations.
42- String-based tracepoint object lookup.
43- Enable and disable a set of tracepoints based on regular expression and/or
44  globbing.
45- Generate trace in ``Common Trace Format (CTF)``. ``CTF`` is an open-source
46  trace format and is compatible with ``LTTng``.
47  For detailed information, refer to
48  `Common Trace Format <https://diamon.org/ctf/>`_.
49
50How to add a tracepoint?
51------------------------
52
53This section steps you through the details of adding a simple tracepoint.
54
55.. _create_provider_header_file:
56
57Create the tracepoint provider header file
58~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59
60.. code-block:: c
61
62 #include <rte_trace_point.h>
63
64 RTE_TRACE_POINT(
65        app_trace_string,
66        RTE_TRACE_POINT_ARGS(const char *str),
67        rte_trace_point_emit_string(str);
68 )
69
70The above macro creates ``app_trace_string`` tracepoint.
71The user can choose any name for the tracepoint.
72However, when adding a tracepoint in the DPDK library, the
73``rte_<library_name>_trace_[<domain>_]<name>`` naming convention must be
74followed.
75The examples are ``rte_eal_trace_generic_str``, ``rte_mempool_trace_create``.
76
77The ``RTE_TRACE_POINT`` macro expands from above definition as the following
78function template:
79
80.. code-block:: c
81
82 static __rte_always_inline void
83 app_trace_string(const char *str)
84 {
85         /* Trace subsystem hooks */
86         ...
87         rte_trace_point_emit_string(str);
88 }
89
90The consumer of this tracepoint can invoke
91``app_trace_string(const char *str)`` to emit the trace event to the trace
92buffer.
93
94Register the tracepoint
95~~~~~~~~~~~~~~~~~~~~~~~
96
97.. code-block:: c
98
99 /* Select tracepoint register macros */
100 #define RTE_TRACE_POINT_REGISTER_SELECT
101
102 #include <my_tracepoint_provider.h>
103
104 RTE_TRACE_POINT_DEFINE(app_trace_string);
105
106 RTE_INIT(app_trace_init)
107 {
108       RTE_TRACE_POINT_REGISTER(app_trace_string, app.trace.string);
109 }
110
111The above code snippet registers the ``app_trace_string`` tracepoint to
112trace library. Here, the ``my_tracepoint_provider.h`` is the header file
113that the user created in the first step :ref:`create_provider_header_file`.
114
115The second argument for the ``RTE_TRACE_POINT_REGISTER`` is the name for the
116tracepoint. This string will be used for tracepoint lookup or regular
117expression and/or glob based tracepoint operations.
118There is no requirement for the tracepoint function and its name to be similar.
119However, it is recommended to have a similar name for a better naming
120convention.
121
122The user must register the tracepoint before the ``rte_eal_init`` invocation.
123The user can use the ``RTE_INIT`` construction scheme to achieve this.
124
125.. note::
126
127   The ``RTE_TRACE_POINT_REGISTER_SELECT`` must be defined before including the
128   header for the tracepoint registration to work properly.
129
130.. note::
131
132   The ``RTE_TRACE_POINT_DEFINE`` defines the placeholder for the
133   ``rte_trace_point_t`` tracepoint object. The user must export a
134   ``__<trace_function_name>`` symbol in the library ``.map`` file for this
135   tracepoint to be used out of the library, in shared builds.
136   For example, ``__app_trace_string`` will be the exported symbol in the
137   above example.
138
139Fast path tracepoint
140--------------------
141
142In order to avoid performance impact in fast path code, the library introduced
143``RTE_TRACE_POINT_FP``. When adding the tracepoint in fast path code,
144the user must use ``RTE_TRACE_POINT_FP`` instead of ``RTE_TRACE_POINT``.
145
146``RTE_TRACE_POINT_FP`` is compiled out by default and it can be enabled using
147``CONFIG_RTE_ENABLE_TRACE_FP`` configuration parameter.
148The ``enable_trace_fp`` option shall be used for the same for meson build.
149
150Event record mode
151-----------------
152
153Event record mode is an attribute of trace buffers. Trace library exposes the
154following modes:
155
156Overwrite
157   When the trace buffer is full, new trace events overwrites the existing
158   captured events in the trace buffer.
159Discard
160   When the trace buffer is full, new trace events will be discarded.
161
162The mode can be configured either using EAL command line parameter
163``--trace-mode`` on application boot up or use ``rte_trace_mode_set()`` API to
164configure at runtime.
165
166Trace file location
167-------------------
168
169On ``rte_trace_save()`` or ``rte_eal_cleanup()`` invocation, the library saves
170the trace buffers to the filesystem. By default, the trace files are stored in
171``$HOME/dpdk-traces/rte-yyyy-mm-dd-[AP]M-hh-mm-ss/``.
172It can be overridden by the ``--trace-dir=<directory path>`` EAL command line
173option.
174
175For more information, refer to :doc:`../linux_gsg/linux_eal_parameters` for
176trace EAL command line options.
177
178View and analyze the recorded events
179------------------------------------
180
181Once the trace directory is available, the user can view/inspect the recorded
182events.
183
184There are many tools you can use to read DPDK traces:
185
1861. ``babeltrace`` is a command-line utility that converts trace formats; it
187supports the format that DPDK trace library produces, CTF, as well as a
188basic text output that can be grep'ed.
189The babeltrace command is part of the Open Source Babeltrace project.
190
1912. ``Trace Compass`` is a graphical user interface for viewing and analyzing
192any type of logs or traces, including DPDK traces.
193
194Use the babeltrace command-line tool
195~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
196
197The simplest way to list all the recorded events of a trace is to pass its path
198to babeltrace with no options::
199
200    babeltrace </path-to-trace-events/rte-yyyy-mm-dd-[AP]M-hh-mm-ss/>
201
202``babeltrace`` finds all traces recursively within the given path and prints
203all their events, merging them in chronological order.
204
205You can pipe the output of the babeltrace into a tool like grep(1) for further
206filtering. Below example grep the events for ``ethdev`` only::
207
208    babeltrace /tmp/my-dpdk-trace | grep ethdev
209
210You can pipe the output of babeltrace into a tool like wc(1) to count the
211recorded events. Below example count the number of ``ethdev`` events::
212
213    babeltrace /tmp/my-dpdk-trace | grep ethdev | wc --lines
214
215Use the tracecompass GUI tool
216~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
217
218``Tracecompass`` is another tool to view/analyze the DPDK traces which gives
219a graphical view of events. Like ``babeltrace``, tracecompass also provides
220an interface to search for a particular event.
221To use ``tracecompass``, following are the minimum required steps:
222
223- Install ``tracecompass`` to the localhost. Variants are available for Linux,
224  Windows, and OS-X.
225- Launch ``tracecompass`` which will open a graphical window with trace
226  management interfaces.
227- Open a trace using ``File->Open Trace`` option and select metadata file which
228  is to be viewed/analyzed.
229
230For more details, refer
231`Trace Compass <https://www.eclipse.org/tracecompass/>`_.
232
233Quick start
234-----------
235
236This section steps you through the details of generating trace and viewing it.
237
238- Start the dpdk-test::
239
240    echo "quit" | ./build/app/test/dpdk-test --no-huge --trace=.*
241
242- View the traces with babeltrace viewer::
243
244    babeltrace $HOME/dpdk-traces/rte-yyyy-mm-dd-[AP]M-hh-mm-ss/
245
246Implementation details
247----------------------
248
249As DPDK trace library is designed to generate traces that uses ``Common Trace
250Format (CTF)``. ``CTF`` specification consists of the following units to create
251a trace.
252
253- ``Stream`` Sequence of packets.
254- ``Packet`` Header and one or more events.
255- ``Event`` Header and payload.
256
257For detailed information, refer to
258`Common Trace Format <https://diamon.org/ctf/>`_.
259
260The implementation details broadly divided into the following areas:
261
262Trace metadata creation
263~~~~~~~~~~~~~~~~~~~~~~~
264
265Based on the ``CTF`` specification, one of a CTF trace's streams is mandatory:
266the metadata stream. It contains exactly what you would expect: data about the
267trace itself. The metadata stream contains a textual description of the binary
268layouts of all the other streams.
269
270This description is written using the Trace Stream Description Language (TSDL),
271a declarative language that exists only in the realm of CTF.
272The purpose of the metadata stream is to make CTF readers know how to parse a
273trace's binary streams of events without CTF specifying any fixed layout.
274The only stream layout known in advance is, in fact, the metadata stream's one.
275
276The internal ``trace_metadata_create()`` function generates the metadata.
277
278Trace memory
279~~~~~~~~~~~~
280
281The trace memory will be allocated through an internal function
282``__rte_trace_mem_per_thread_alloc()``. The trace memory will be allocated
283per thread to enable lock less trace-emit function.
284The memory for the trace memory for DPDK lcores will be allocated on
285``rte_eal_init()`` if the trace is enabled through a EAL option.
286For non DPDK threads, on the first trace emission, the memory will be
287allocated.
288
289Trace memory layout
290~~~~~~~~~~~~~~~~~~~
291
292.. _table_trace_mem_layout:
293
294.. table:: Trace memory layout.
295
296  +-------------------+
297  |   packet.header   |
298  +-------------------+
299  |   packet.context  |
300  +-------------------+
301  |   trace 0 header  |
302  +-------------------+
303  |   trace 0 payload |
304  +-------------------+
305  |   trace 1 header  |
306  +-------------------+
307  |   trace 1 payload |
308  +-------------------+
309  |   trace N header  |
310  +-------------------+
311  |   trace N payload |
312  +-------------------+
313
314packet.header
315^^^^^^^^^^^^^
316
317.. _table_packet_header:
318
319.. table:: Packet header layout.
320
321  +-------------------+
322  |   uint32_t magic  |
323  +-------------------+
324  |   rte_uuid_t uuid |
325  +-------------------+
326
327packet.context
328^^^^^^^^^^^^^^
329
330.. _table_packet_context:
331
332.. table:: Packet context layout.
333
334  +----------------------+
335  |  uint32_t thread_id  |
336  +----------------------+
337  | char thread_name[32] |
338  +----------------------+
339
340trace.header
341^^^^^^^^^^^^
342
343.. _table_trace_header:
344
345.. table:: Trace header layout.
346
347  +----------------------+
348  | event_id  [63:48]    |
349  +----------------------+
350  | timestamp [47:0]     |
351  +----------------------+
352
353The trace header is 64 bits, it consists of 48 bits of timestamp and 16 bits
354event ID.
355
356The ``packet.header`` and ``packet.context`` will be written in the slow path
357at the time of trace memory creation. The ``trace.header`` and trace payload
358will be emitted when the tracepoint function is invoked.
359