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