xref: /dpdk/doc/guides/prog_guide/trace_lib.rst (revision 443b949e17953a1094f80532d600a1ee540f2ba4)
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_tracepoint_header_file:
56
57Create the tracepoint 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 #include <rte_trace_point_register.h>
100
101 #include <my_tracepoint.h>
102
103 RTE_TRACE_POINT_REGISTER(app_trace_string, app.trace.string)
104
105The above code snippet registers the ``app_trace_string`` tracepoint to
106trace library. Here, the ``my_tracepoint.h`` is the header file
107that the user created in the first step :ref:`create_tracepoint_header_file`.
108
109The second argument for the ``RTE_TRACE_POINT_REGISTER`` is the name for the
110tracepoint. This string will be used for tracepoint lookup or regular
111expression and/or glob based tracepoint operations.
112There is no requirement for the tracepoint function and its name to be similar.
113However, it is recommended to have a similar name for a better naming
114convention.
115
116.. note::
117
118   The ``rte_trace_point_register.h`` header must be included before any
119   inclusion of the ``rte_trace_point.h`` header.
120
121.. note::
122
123   The ``RTE_TRACE_POINT_REGISTER`` defines the placeholder for the
124   ``rte_trace_point_t`` tracepoint object.
125   For generic tracepoint or for tracepoint used in public header files,
126   the user must export a ``__<trace_function_name>`` symbol
127   in the library ``.map`` file for this tracepoint
128   to be used out of the library, in shared builds.
129   For example, ``__app_trace_string`` will be the exported symbol in the
130   above example.
131
132Fast path tracepoint
133--------------------
134
135In order to avoid performance impact in fast path code, the library introduced
136``RTE_TRACE_POINT_FP``. When adding the tracepoint in fast path code,
137the user must use ``RTE_TRACE_POINT_FP`` instead of ``RTE_TRACE_POINT``.
138
139``RTE_TRACE_POINT_FP`` is compiled out by default and it can be enabled using
140the ``enable_trace_fp`` option for meson build.
141
142Event record mode
143-----------------
144
145Event record mode is an attribute of trace buffers. Trace library exposes the
146following modes:
147
148Overwrite
149   When the trace buffer is full, new trace events overwrites the existing
150   captured events in the trace buffer.
151Discard
152   When the trace buffer is full, new trace events will be discarded.
153
154The mode can be configured either using EAL command line parameter
155``--trace-mode`` on application boot up or use ``rte_trace_mode_set()`` API to
156configure at runtime.
157
158Trace file location
159-------------------
160
161On ``rte_trace_save()`` or ``rte_eal_cleanup()`` invocation, the library saves
162the trace buffers to the filesystem. By default, the trace files are stored in
163``$HOME/dpdk-traces/rte-yyyy-mm-dd-[AP]M-hh-mm-ss/``.
164It can be overridden by the ``--trace-dir=<directory path>`` EAL command line
165option.
166
167For more information, refer to :doc:`../linux_gsg/linux_eal_parameters` for
168trace EAL command line options.
169
170View and analyze the recorded events
171------------------------------------
172
173Once the trace directory is available, the user can view/inspect the recorded
174events.
175
176There are many tools you can use to read DPDK traces:
177
178#. ``babeltrace`` is a command-line utility that converts trace formats; it
179   supports the format that DPDK trace library produces, CTF, as well as a
180   basic text output that can be grep'ed.
181   The babeltrace command is part of the Open Source Babeltrace project.
182
183#. ``Trace Compass`` is a graphical user interface for viewing and analyzing
184   any type of logs or traces, including DPDK traces.
185
186Use the babeltrace command-line tool
187~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
188
189The simplest way to list all the recorded events of a trace is to pass its path
190to babeltrace with no options::
191
192    babeltrace </path-to-trace-events/rte-yyyy-mm-dd-[AP]M-hh-mm-ss/>
193
194``babeltrace`` finds all traces recursively within the given path and prints
195all their events, merging them in chronological order.
196
197You can pipe the output of the babeltrace into a tool like grep(1) for further
198filtering. Below example grep the events for ``ethdev`` only::
199
200    babeltrace /tmp/my-dpdk-trace | grep ethdev
201
202You can pipe the output of babeltrace into a tool like wc(1) to count the
203recorded events. Below example count the number of ``ethdev`` events::
204
205    babeltrace /tmp/my-dpdk-trace | grep ethdev | wc --lines
206
207Use the tracecompass GUI tool
208~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
209
210``Tracecompass`` is another tool to view/analyze the DPDK traces which gives
211a graphical view of events. Like ``babeltrace``, tracecompass also provides
212an interface to search for a particular event.
213To use ``tracecompass``, following are the minimum required steps:
214
215- Install ``tracecompass`` to the localhost. Variants are available for Linux,
216  Windows, and OS-X.
217- Launch ``tracecompass`` which will open a graphical window with trace
218  management interfaces.
219- Open a trace using ``File->Open Trace`` option and select metadata file which
220  is to be viewed/analyzed.
221
222For more details, refer
223`Trace Compass <https://www.eclipse.org/tracecompass/>`_.
224
225Quick start
226-----------
227
228This section steps you through the details of generating trace and viewing it.
229
230- Start the dpdk-test::
231
232    echo "quit" | ./build/app/test/dpdk-test --no-huge --trace=.*
233
234- View the traces with babeltrace viewer::
235
236    babeltrace $HOME/dpdk-traces/rte-yyyy-mm-dd-[AP]M-hh-mm-ss/
237
238Implementation details
239----------------------
240
241As DPDK trace library is designed to generate traces that uses ``Common Trace
242Format (CTF)``. ``CTF`` specification consists of the following units to create
243a trace.
244
245- ``Stream`` Sequence of packets.
246- ``Packet`` Header and one or more events.
247- ``Event`` Header and payload.
248
249For detailed information, refer to
250`Common Trace Format <https://diamon.org/ctf/>`_.
251
252The implementation details broadly divided into the following areas:
253
254Trace metadata creation
255~~~~~~~~~~~~~~~~~~~~~~~
256
257Based on the ``CTF`` specification, one of a CTF trace's streams is mandatory:
258the metadata stream. It contains exactly what you would expect: data about the
259trace itself. The metadata stream contains a textual description of the binary
260layouts of all the other streams.
261
262This description is written using the Trace Stream Description Language (TSDL),
263a declarative language that exists only in the realm of CTF.
264The purpose of the metadata stream is to make CTF readers know how to parse a
265trace's binary streams of events without CTF specifying any fixed layout.
266The only stream layout known in advance is, in fact, the metadata stream's one.
267
268The internal ``trace_metadata_create()`` function generates the metadata.
269
270Trace memory
271~~~~~~~~~~~~
272
273The trace memory will be allocated through an internal function
274``__rte_trace_mem_per_thread_alloc()``. The trace memory will be allocated
275per thread to enable lock less trace-emit function.
276
277For non lcore threads, the trace memory is allocated on the first trace
278emission.
279
280For lcore threads, if trace points are enabled through a EAL option, the trace
281memory is allocated when the threads are known of DPDK
282(``rte_eal_init`` for EAL lcores, ``rte_thread_register`` for non-EAL lcores).
283Otherwise, when trace points are enabled later in the life of the application,
284the behavior is the same as non lcore threads and the trace memory is allocated
285on the first trace emission.
286
287Trace memory layout
288~~~~~~~~~~~~~~~~~~~
289
290.. _table_trace_mem_layout:
291
292.. table:: Trace memory layout.
293
294  +-------------------+
295  |   packet.header   |
296  +-------------------+
297  |   packet.context  |
298  +-------------------+
299  |   trace 0 header  |
300  +-------------------+
301  |   trace 0 payload |
302  +-------------------+
303  |   trace 1 header  |
304  +-------------------+
305  |   trace 1 payload |
306  +-------------------+
307  |   trace N header  |
308  +-------------------+
309  |   trace N payload |
310  +-------------------+
311
312packet.header
313^^^^^^^^^^^^^
314
315.. _table_packet_header:
316
317.. table:: Packet header layout.
318
319  +-------------------+
320  |   uint32_t magic  |
321  +-------------------+
322  |   rte_uuid_t uuid |
323  +-------------------+
324
325packet.context
326^^^^^^^^^^^^^^
327
328.. _table_packet_context:
329
330.. table:: Packet context layout.
331
332  +----------------------+
333  |  uint32_t thread_id  |
334  +----------------------+
335  | char thread_name[32] |
336  +----------------------+
337
338trace.header
339^^^^^^^^^^^^
340
341.. _table_trace_header:
342
343.. table:: Trace header layout.
344
345  +----------------------+
346  | event_id  [63:48]    |
347  +----------------------+
348  | timestamp [47:0]     |
349  +----------------------+
350
351The trace header is 64 bits, it consists of 48 bits of timestamp and 16 bits
352event ID.
353
354The ``packet.header`` and ``packet.context`` will be written in the slow path
355at the time of trace memory creation. The ``trace.header`` and trace payload
356will be emitted when the tracepoint function is invoked.
357
358Limitations
359-----------
360
361- The ``rte_trace_point_emit_blob()`` function can capture a maximum blob
362  of length ``RTE_TRACE_BLOB_LEN_MAX`` bytes.
363  The application can call ``rte_trace_point_emit_blob()`` multiple times
364  with length less than or equal to ``RTE_TRACE_BLOB_LEN_MAX``,
365  if it needs to capture more than ``RTE_TRACE_BLOB_LEN_MAX`` bytes.
366- If the length passed to the ``rte_trace_point_emit_blob()``
367  is less than ``RTE_TRACE_BLOB_LEN_MAX``,
368  then the trailing ``(RTE_TRACE_BLOB_LEN_MAX - len)`` bytes in the trace
369  are set to zero.
370