DPDK-dev Archive on lore.kernel.org
 help / color / Atom feed
* [dpdk-dev]  [PATCH v1 00/32] DPDK Trace support
@ 2020-03-18 19:02 jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 01/32] eal: introduce API for getting thread name jerinj
                   ` (32 more replies)
  0 siblings, 33 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

It is the v1 version of the DPDK trace support based on the following RFC

https://www.mail-archive.com/dev@dpdk.org/msg154457.html

This patch set contains 
~~~~~~~~~~~~~~~~~~~~~~~~

# The native implementation of common trace format(CTF)[1] based tracer
# Public API to create the trace points.
# Add tracepoints to eal, ethdev, mempool, eventdev and cryptodev 
library for tracing support
# A unit test case
# Performance test case to measure the trace overhead. (See eal/trace:
# add trace performance test cases, patch)
# Programmers guide for Trace support(See doc: add trace library guide,
# patch)

# Tested OS:
~~~~~~~~~~~
- Linux
- FreeBSD

# Tested open source CTF trace viewers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Babeltrace
- Tracecompass

# Trace overhead comparison with LTTng
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

trace overhead data on x86:[2]
# 236 cycles with LTTng(>100ns)
# 18 cycles(7ns) with Native DPDK CTF emitter.(See eal/trace: add trace
# performance test cases patch)

trace overhead data on arm64:
#  312  cycles to  1100 cycles with LTTng based on the class of arm64
#  CPU.
#  11 cycles to 13 cycles with Native DPDK CTF emitter based on the
class of arm64 CPU.

18 cycles(on x86) vs 11 cycles(on arm64) is due to rdtsc() overhead in
x86. It seems  rdtsc takes around 15cycles in x86.


Items that needs to be sort it out 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Checkpatch script reports errors for macros which emit events.

	Library exports set of macros(rte_trace_ctf_*) to emit events
for various datatypes.
	Checkpatch scripts reports error for these macros, to be part of
EXPERIMENTAL section,
	even symbols are updated in EXPERIMENTAL section in
rte_eal_version.map file.
	
# Makefile and meson.build are updated to allow experimental APIs.

	As multiple EXPERIMENTAL symbols, exported by trace library, are
used in various
	drivers, lib, app and examples. So to fix compilation
warning/error, Makefile and
	meson.build are updated for all required components to support
EXPERIMENTAL APIs.
	It results same code changes at multiple components as well as
increases source
	code line changes in patchset too.
	Suggestions are welcome to resolve this issue with lesser code
changes
	
More details:
~~~~~~~~~~~~~

# The Native DPDK CTF trace support does not have any dependency on
third-party library.
The generated output file is compatible with LTTng as both are using
CTF trace format.

The performance gain comes from:
1) exploit dpdk worker thread usage model to avoid atomics and use per
core variables
2) use hugepage,
3) avoid a lot function pointers in fast-path etc
4) avoid unaligned store for arm64 etc

Features:
~~~~~~~~~
- APIs and Features are similar to rte_log dynamic framework
API(expect log prints on stdout vs it dumps on trace file)
- No specific limit on the events. A string-based event like rte_log
for pattern matching
- Dynamic enable/disable support.
- Instructmention overhead is ~1 cycle. i.e cost of adding the code
wth out using trace feature.
- Timestamp support for all the events using DPDK rte_rtdsc
- No dependency on another library. Clean room native implementation of
  CTF.

Functional test case:
a) echo "trace_autotest" | sudo ./build/app/test/dpdk-test  -c 0x3
--trace-level=8

The above command emits the following trace events
<code>
        uint8_t i;

        rte_trace_lib_eal_generic_void();
        rte_trace_lib_eal_generic_u64(0x10000000000000);
        rte_trace_lib_eal_generic_u32(0x10000000);
        rte_trace_lib_eal_generic_u16(0xffee);
        rte_trace_lib_eal_generic_u8(0xc);
        rte_trace_lib_eal_generic_i64(-1234);
        rte_trace_lib_eal_generic_i32(-1234567);
        rte_trace_lib_eal_generic_i16(12);
        rte_trace_lib_eal_generic_i8(-3);
        rte_trace_lib_eal_generic_string("my string");
        rte_trace_lib_eal_generic_function(__func__);

        for (i = 0; i < 128; i++)
                rte_trace_lib_eal_generic_u8(i);
</code>

Install babeltrace package in Linux and point the generated trace file
to babel trace. By default trace file created under
<user>/dpdk-traces/time_stamp/

example:
# babeltrace /root/dpdk-traces/rte-2020-02-15-PM-02-56-51 | more

[13:27:36.138468807] (+?.?????????) lib.eal.generic.void: { cpu_id =
0, name = "dpdk-test" }, { }
[13:27:36.138468851] (+0.000000044) lib.eal.generic.u64: { cpu_id = 0,
name = "dpdk-test" }, { in = 4503599627370496 }
[13:27:36.138468860] (+0.000000009) lib.eal.generic.u32: { cpu_id = 0,
name = "dpdk-test" }, { in = 268435456 }
[13:27:36.138468934] (+0.000000074) lib.eal.generic.u16: { cpu_id = 0,
name = "dpdk-test" }, { in = 65518 }
[13:27:36.138468949] (+0.000000015) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 12 }
[13:27:36.138468956] (+0.000000007) lib.eal.generic.i64: { cpu_id = 0,
name = "dpdk-test" }, { in = -1234 }
[13:27:36.138468963] (+0.000000007) lib.eal.generic.i32: { cpu_id = 0,
name = "dpdk-test" }, { in = -1234567 }
[13:27:36.138469024] (+0.000000061) lib.eal.generic.i16: { cpu_id = 0,
name = "dpdk-test" }, { in = 12 }
[13:27:36.138469044] (+0.000000020) lib.eal.generic.i8: { cpu_id = 0,
name = "dpdk-test" }, { in = -3 }
[13:27:36.138469051] (+0.000000007) lib.eal.generic.string: { cpu_id =
0, name = "dpdk-test" }, { str = "my string" }
[13:27:36.138469203] (+0.000000152) lib.eal.generic.func: { cpu_id =
0, name = "dpdk-test" }, { func = "test_trace_points" }
[13:27:36.138469239] (+0.000000036) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 0 }
[13:27:36.138469246] (+0.000000007) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 1 }
[13:27:36.138469252] (+0.000000006) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 2 }
[13:27:36.138469262] (+0.000000010) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 3 }
[13:27:36.138469269] (+0.000000007) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 4 }
[13:27:36.138469276] (+0.000000007) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 5 }

# There is a  GUI based trace viewer available in Windows, Linux and
# Mac.
It is called as tracecompass.(https://www.eclipse.org/tracecompass/)

The example screenshot and Histogram of above DPDK trace using
Tracecompass.

https://github.com/jerinjacobk/share/blob/master/dpdk_trace.JPG



File walk through:
~~~~~~~~~~~~~~~~~~

lib/librte_eal/common/include/rte_trace.h - Public API for Trace
provider and Trace control
lib/librte_eal/common/eal_common_trace.c - main trace implementation
lib/librte_eal/common/eal_common_trace_ctf.c - CTF metadata spec
implementation
lib/librte_eal/common/eal_common_trace_utils.c - command line utils
and filesystem operations.
lib/librte_eal/common/eal_common_trace_points.c -  trace points for EAL
library
lib/librte_eal/common/include/rte_trace_eal.h - EAL tracepoint public
API.
lib/librte_eal/common/eal_trace.h - Private trace header file.


[1] https://diamon.org/ctf/

[2] The above test is ported to LTTng for finding the LTTng trace
overhead. It available at
https://github.com/jerinjacobk/lttng-overhead
https://github.com/jerinjacobk/lttng-overhead/blob/master/README

Jerin Jacob (21):
  eal: introduce API for getting thread name
  eal: define the public API for trace support
  eal/trace: implement trace register API
  eal/trace: implement trace operation APIs
  eal/trace: add internal trace init and fini interface
  eal/trace: get bootup timestamp for trace
  eal/trace: create CTF TDSL metadata in memory
  eal/trace: implement trace memory allocation
  eal/trace: implement debug dump function
  eal/trace: implement trace save
  eal/trace: implement registration payload
  eal/trace: implement provider payload
  eal/trace: hook internal trace APIs to Linux
  eal/trace: hook internal trace APIs to FreeBSD
  eal/trace: add generic tracepoints
  eal/trace: add alarm tracepoints
  eal/trace: add memory tracepoints
  eal/trace: add memzone tracepoints
  eal/trace: add thread tracepoints
  eal/trace: add interrupt tracepoints
  eal/trace: add trace performance test cases

Sunil Kumar Kori (11):
  eal/trace: handle CTF keyword collision
  eal/trace: add trace level configuration parameter
  eal/trace: add trace dir configuration parameter
  eal/trace: add trace bufsize configuration parameter
  eal/trace: add trace mode configuration parameter
  eal/trace: add unit test cases
  ethdev: add tracepoints
  eventdev: add tracepoints
  cryptodev: add tracepoints
  mempool: add tracepoints
  doc: add trace library guide

 MAINTAINERS                                   |  15 +
 app/pdump/Makefile                            |   1 +
 app/pdump/meson.build                         |   1 +
 app/proc-info/Makefile                        |   1 +
 app/proc-info/meson.build                     |   1 +
 app/test-acl/Makefile                         |   1 +
 app/test-acl/meson.build                      |   1 +
 app/test-cmdline/Makefile                     |   1 +
 app/test-cmdline/meson.build                  |   1 +
 app/test-eventdev/Makefile                    |   1 +
 app/test-eventdev/meson.build                 |   1 +
 app/test-pipeline/Makefile                    |   1 +
 app/test-pipeline/meson.build                 |   1 +
 app/test/Makefile                             |   4 +-
 app/test/meson.build                          |   3 +
 app/test/test_trace.c                         | 618 ++++++++++++++++++
 app/test/test_trace.h                         |  52 ++
 app/test/test_trace_perf.c                    | 179 +++++
 app/test/test_trace_register.c                |  46 ++
 config/common_base                            |   1 +
 config/rte_config.h                           |   1 +
 doc/api/doxy-api-index.md                     |   3 +-
 doc/guides/linux_gsg/eal_args.include.rst     |  55 ++
 doc/guides/prog_guide/index.rst               |   1 +
 doc/guides/prog_guide/trace_lib.rst           | 264 ++++++++
 doc/guides/rel_notes/release_20_05.rst        |   4 +
 drivers/common/cpt/Makefile                   |   1 +
 drivers/crypto/ccp/Makefile                   |   1 +
 drivers/crypto/ccp/meson.build                |   2 +
 drivers/crypto/mvsam/Makefile                 |   1 +
 drivers/crypto/mvsam/meson.build              |   1 +
 drivers/crypto/null/Makefile                  |   1 +
 drivers/crypto/null/meson.build               |   1 +
 drivers/crypto/scheduler/Makefile             |   1 +
 drivers/crypto/scheduler/meson.build          |   1 +
 drivers/crypto/virtio/Makefile                |   1 +
 drivers/crypto/virtio/meson.build             |   1 +
 drivers/event/octeontx/Makefile               |   1 +
 drivers/event/octeontx/meson.build            |   1 +
 drivers/event/skeleton/Makefile               |   1 +
 drivers/event/skeleton/meson.build            |   1 +
 drivers/event/sw/Makefile                     |   1 +
 drivers/event/sw/meson.build                  |   1 +
 drivers/mempool/ring/Makefile                 |   1 +
 drivers/mempool/ring/meson.build              |   1 +
 drivers/net/af_packet/Makefile                |   1 +
 drivers/net/af_packet/meson.build             |   1 +
 drivers/net/af_xdp/Makefile                   |   1 +
 drivers/net/af_xdp/meson.build                |   1 +
 drivers/net/ark/Makefile                      |   1 +
 drivers/net/ark/meson.build                   |   1 +
 drivers/net/bnxt/Makefile                     |   1 +
 drivers/net/bnxt/meson.build                  |   1 +
 drivers/net/cxgbe/Makefile                    |   1 +
 drivers/net/cxgbe/meson.build                 |   1 +
 drivers/net/enetc/Makefile                    |   1 +
 drivers/net/enetc/meson.build                 |   1 +
 drivers/net/hinic/Makefile                    |   1 +
 drivers/net/hinic/base/meson.build            |   3 +-
 drivers/net/hinic/meson.build                 |   1 +
 drivers/net/ionic/ionic_dev.c                 |   1 +
 drivers/net/ionic/ionic_dev.h                 |   2 +
 drivers/net/ionic/ionic_mac_api.c             |   1 +
 drivers/net/ionic/ionic_main.c                |   1 +
 drivers/net/ionic/ionic_osdep.h               |   6 -
 drivers/net/ionic/ionic_rx_filter.c           |   1 +
 drivers/net/kni/Makefile                      |   1 +
 drivers/net/kni/meson.build                   |   1 +
 drivers/net/liquidio/Makefile                 |   1 +
 drivers/net/liquidio/meson.build              |   1 +
 drivers/net/mvneta/Makefile                   |   1 +
 drivers/net/mvneta/meson.build                |   1 +
 drivers/net/mvpp2/Makefile                    |   1 +
 drivers/net/mvpp2/meson.build                 |   1 +
 drivers/net/nfb/Makefile                      |   1 +
 drivers/net/nfb/meson.build                   |   1 +
 drivers/net/null/Makefile                     |   1 +
 drivers/net/null/meson.build                  |   1 +
 drivers/net/octeontx/Makefile                 |   1 +
 drivers/net/octeontx2/Makefile                |   1 +
 drivers/net/octeontx2/meson.build             |   1 +
 drivers/net/pcap/Makefile                     |   1 +
 drivers/net/pcap/meson.build                  |   1 +
 drivers/net/ring/Makefile                     |   1 +
 drivers/net/ring/meson.build                  |   1 +
 drivers/net/szedata2/Makefile                 |   1 +
 drivers/net/szedata2/meson.build              |   1 +
 drivers/net/thunderx/base/meson.build         |   1 +
 drivers/net/vhost/Makefile                    |   1 +
 drivers/net/vhost/meson.build                 |   1 +
 drivers/raw/ioat/Makefile                     |   1 +
 drivers/raw/ioat/meson.build                  |   1 +
 drivers/raw/octeontx2_dma/Makefile            |   1 +
 drivers/raw/octeontx2_dma/meson.build         |   1 +
 drivers/raw/octeontx2_ep/Makefile             |   1 +
 drivers/raw/octeontx2_ep/meson.build          |   1 +
 drivers/raw/skeleton/Makefile                 |   1 +
 drivers/raw/skeleton/meson.build              |   1 +
 examples/cmdline/Makefile                     |   1 +
 examples/cmdline/meson.build                  |   1 +
 examples/distributor/Makefile                 |   1 +
 examples/distributor/meson.build              |   1 +
 examples/ethtool/ethtool-app/Makefile         |   1 +
 examples/flow_filtering/Makefile              |   1 +
 examples/flow_filtering/meson.build           |   1 +
 examples/helloworld/Makefile                  |   1 +
 examples/helloworld/meson.build               |   1 +
 examples/ioat/Makefile                        |   1 +
 examples/ioat/meson.build                     |   1 +
 examples/ip_reassembly/Makefile               |   1 +
 examples/ip_reassembly/meson.build            |   1 +
 examples/ipv4_multicast/Makefile              |   1 +
 examples/ipv4_multicast/meson.build           |   1 +
 examples/l2fwd-cat/Makefile                   |   1 +
 examples/l2fwd-cat/meson.build                |   1 +
 examples/l2fwd-event/Makefile                 |   1 +
 examples/l2fwd-event/meson.build              |   1 +
 examples/l2fwd-jobstats/Makefile              |   1 +
 examples/l2fwd-jobstats/meson.build           |   1 +
 examples/l2fwd-keepalive/Makefile             |   1 +
 examples/l2fwd-keepalive/ka-agent/Makefile    |   1 +
 examples/l2fwd-keepalive/meson.build          |   1 +
 examples/l3fwd-acl/Makefile                   |   1 +
 examples/l3fwd-acl/meson.build                |   1 +
 examples/l3fwd/Makefile                       |   1 +
 examples/l3fwd/meson.build                    |   1 +
 examples/link_status_interrupt/Makefile       |   1 +
 examples/link_status_interrupt/meson.build    |   1 +
 .../client_server_mp/mp_client/Makefile       |   1 +
 .../client_server_mp/mp_client/meson.build    |   1 +
 .../client_server_mp/mp_server/meson.build    |   1 +
 examples/multi_process/hotplug_mp/Makefile    |   1 +
 examples/multi_process/hotplug_mp/meson.build |   1 +
 examples/multi_process/simple_mp/Makefile     |   1 +
 examples/multi_process/simple_mp/meson.build  |   1 +
 examples/multi_process/symmetric_mp/Makefile  |   1 +
 .../multi_process/symmetric_mp/meson.build    |   1 +
 examples/packet_ordering/Makefile             |   1 +
 examples/packet_ordering/meson.build          |   1 +
 .../performance-thread/l3fwd-thread/Makefile  |   1 +
 .../l3fwd-thread/meson.build                  |   1 +
 .../performance-thread/pthread_shim/Makefile  |   1 +
 .../pthread_shim/meson.build                  |   1 +
 examples/ptpclient/Makefile                   |   1 +
 examples/ptpclient/meson.build                |   1 +
 examples/qos_meter/Makefile                   |   1 +
 examples/qos_meter/meson.build                |   1 +
 examples/qos_sched/Makefile                   |   1 +
 examples/qos_sched/meson.build                |   1 +
 examples/server_node_efd/node/Makefile        |   1 +
 examples/server_node_efd/node/meson.build     |   1 +
 examples/server_node_efd/server/Makefile      |   1 +
 examples/server_node_efd/server/meson.build   |   1 +
 examples/service_cores/Makefile               |   1 +
 examples/service_cores/meson.build            |   1 +
 examples/skeleton/Makefile                    |   1 +
 examples/skeleton/meson.build                 |   1 +
 examples/timer/Makefile                       |   1 +
 examples/timer/meson.build                    |   1 +
 examples/vm_power_manager/Makefile            |   1 +
 examples/vm_power_manager/meson.build         |   1 +
 examples/vmdq/Makefile                        |   1 +
 examples/vmdq/meson.build                     |   1 +
 examples/vmdq_dcb/Makefile                    |   1 +
 examples/vmdq_dcb/meson.build                 |   1 +
 lib/librte_bitratestats/Makefile              |   1 +
 lib/librte_bitratestats/meson.build           |   1 +
 lib/librte_cryptodev/Makefile                 |   4 +-
 lib/librte_cryptodev/cryptodev_trace_points.c |  70 ++
 lib/librte_cryptodev/meson.build              |   7 +-
 lib/librte_cryptodev/rte_cryptodev.c          |  18 +
 lib/librte_cryptodev/rte_cryptodev.h          |   6 +
 .../rte_cryptodev_version.map                 |  18 +
 lib/librte_cryptodev/rte_trace_cryptodev.h    | 133 ++++
 lib/librte_cryptodev/rte_trace_cryptodev_fp.h |  34 +
 lib/librte_distributor/Makefile               |   1 +
 lib/librte_distributor/meson.build            |   1 +
 lib/librte_eal/common/Makefile                |   1 +
 lib/librte_eal/common/eal_common_log.c        |   9 +-
 lib/librte_eal/common/eal_common_memzone.c    |   9 +
 lib/librte_eal/common/eal_common_options.c    |  68 +-
 lib/librte_eal/common/eal_common_thread.c     |   3 +-
 lib/librte_eal/common/eal_common_trace.c      | 616 +++++++++++++++++
 lib/librte_eal/common/eal_common_trace_ctf.c  | 488 ++++++++++++++
 .../common/eal_common_trace_points.c          | 115 ++++
 .../common/eal_common_trace_utils.c           | 518 +++++++++++++++
 lib/librte_eal/common/eal_options.h           |   8 +
 lib/librte_eal/common/eal_private.h           |  11 +
 lib/librte_eal/common/eal_trace.h             | 122 ++++
 lib/librte_eal/common/include/rte_lcore.h     |  17 +
 lib/librte_eal/common/include/rte_trace.h     | 587 +++++++++++++++++
 lib/librte_eal/common/include/rte_trace_eal.h | 247 +++++++
 .../common/include/rte_trace_provider.h       | 130 ++++
 .../common/include/rte_trace_register.h       |  70 ++
 lib/librte_eal/common/meson.build             |   8 +
 lib/librte_eal/common/rte_malloc.c            |  60 +-
 lib/librte_eal/freebsd/eal/Makefile           |   4 +
 lib/librte_eal/freebsd/eal/eal.c              |  10 +
 lib/librte_eal/freebsd/eal/eal_alarm.c        |   3 +
 lib/librte_eal/freebsd/eal/eal_interrupts.c   |  52 +-
 lib/librte_eal/freebsd/eal/eal_thread.c       |  21 +-
 lib/librte_eal/linux/eal/Makefile             |   4 +
 lib/librte_eal/linux/eal/eal.c                |   9 +
 lib/librte_eal/linux/eal/eal_alarm.c          |   4 +
 lib/librte_eal/linux/eal/eal_interrupts.c     |  84 ++-
 lib/librte_eal/linux/eal/eal_thread.c         |  27 +-
 lib/librte_eal/rte_eal_version.map            |  61 ++
 lib/librte_ethdev/Makefile                    |   3 +
 lib/librte_ethdev/ethdev_trace_points.c       |  43 ++
 lib/librte_ethdev/meson.build                 |   5 +-
 lib/librte_ethdev/rte_ethdev.c                |  12 +
 lib/librte_ethdev/rte_ethdev.h                |   5 +
 lib/librte_ethdev/rte_ethdev_version.map      |  10 +
 lib/librte_ethdev/rte_trace_ethdev.h          |  90 +++
 lib/librte_ethdev/rte_trace_ethdev_fp.h       |  40 ++
 lib/librte_eventdev/Makefile                  |   3 +
 lib/librte_eventdev/eventdev_trace_points.c   | 173 +++++
 lib/librte_eventdev/meson.build               |   3 +
 .../rte_event_crypto_adapter.c                |  10 +
 .../rte_event_eth_rx_adapter.c                |  11 +
 .../rte_event_eth_tx_adapter.c                |  13 +-
 .../rte_event_eth_tx_adapter.h                |   2 +
 lib/librte_eventdev/rte_event_timer_adapter.c |   8 +-
 lib/librte_eventdev/rte_event_timer_adapter.h |   8 +
 lib/librte_eventdev/rte_eventdev.c            |   9 +
 lib/librte_eventdev/rte_eventdev.h            |   5 +-
 lib/librte_eventdev/rte_eventdev_version.map  |  42 ++
 lib/librte_eventdev/rte_trace_eventdev.h      | 278 ++++++++
 lib/librte_eventdev/rte_trace_eventdev_fp.h   |  75 +++
 lib/librte_gro/Makefile                       |   1 +
 lib/librte_gro/meson.build                    |   1 +
 lib/librte_gso/Makefile                       |   1 +
 lib/librte_gso/meson.build                    |   1 +
 lib/librte_ip_frag/Makefile                   |   1 +
 lib/librte_ip_frag/meson.build                |   1 +
 lib/librte_kni/Makefile                       |   1 +
 lib/librte_kni/meson.build                    |   1 +
 lib/librte_latencystats/Makefile              |   1 +
 lib/librte_latencystats/meson.build           |   1 +
 lib/librte_mempool/Makefile                   |   3 +
 lib/librte_mempool/mempool_trace_points.c     | 108 +++
 lib/librte_mempool/meson.build                |   7 +-
 lib/librte_mempool/rte_mempool.c              |  16 +
 lib/librte_mempool/rte_mempool.h              |  13 +
 lib/librte_mempool/rte_mempool_ops.c          |   7 +
 lib/librte_mempool/rte_mempool_version.map    |  26 +
 lib/librte_mempool/rte_trace_mempool.h        | 148 +++++
 lib/librte_mempool/rte_trace_mempool_fp.h     | 102 +++
 lib/librte_port/Makefile                      |   1 +
 lib/librte_port/meson.build                   |   1 +
 lib/librte_reorder/Makefile                   |   1 +
 lib/librte_reorder/meson.build                |   1 +
 lib/librte_sched/Makefile                     |   1 +
 lib/librte_sched/meson.build                  |   1 +
 lib/librte_security/Makefile                  |   1 +
 lib/librte_security/meson.build               |   1 +
 lib/librte_table/Makefile                     |   1 +
 lib/librte_table/meson.build                  |   1 +
 258 files changed, 6276 insertions(+), 88 deletions(-)
 create mode 100644 app/test/test_trace.c
 create mode 100644 app/test/test_trace.h
 create mode 100644 app/test/test_trace_perf.c
 create mode 100644 app/test/test_trace_register.c
 create mode 100644 doc/guides/prog_guide/trace_lib.rst
 create mode 100644 lib/librte_cryptodev/cryptodev_trace_points.c
 create mode 100644 lib/librte_cryptodev/rte_trace_cryptodev.h
 create mode 100644 lib/librte_cryptodev/rte_trace_cryptodev_fp.h
 create mode 100644 lib/librte_eal/common/eal_common_trace.c
 create mode 100644 lib/librte_eal/common/eal_common_trace_ctf.c
 create mode 100644 lib/librte_eal/common/eal_common_trace_points.c
 create mode 100644 lib/librte_eal/common/eal_common_trace_utils.c
 create mode 100644 lib/librte_eal/common/eal_trace.h
 create mode 100644 lib/librte_eal/common/include/rte_trace.h
 create mode 100644 lib/librte_eal/common/include/rte_trace_eal.h
 create mode 100644 lib/librte_eal/common/include/rte_trace_provider.h
 create mode 100644 lib/librte_eal/common/include/rte_trace_register.h
 create mode 100644 lib/librte_ethdev/ethdev_trace_points.c
 create mode 100644 lib/librte_ethdev/rte_trace_ethdev.h
 create mode 100644 lib/librte_ethdev/rte_trace_ethdev_fp.h
 create mode 100644 lib/librte_eventdev/eventdev_trace_points.c
 create mode 100644 lib/librte_eventdev/rte_trace_eventdev.h
 create mode 100644 lib/librte_eventdev/rte_trace_eventdev_fp.h
 create mode 100644 lib/librte_mempool/mempool_trace_points.c
 create mode 100644 lib/librte_mempool/rte_trace_mempool.h
 create mode 100644 lib/librte_mempool/rte_trace_mempool_fp.h

-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 01/32] eal: introduce API for getting thread name
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 02/32] eal: define the public API for trace support jerinj
                   ` (31 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom, skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Introduce rte_thread_getname() API to get the thread name
and implement it for Linux and FreeBSD.

FreeBSD does not support getting the thread name.

One of the consumers of this API will be the trace subsystem where
it used as an informative purpose.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/include/rte_lcore.h | 17 +++++++++++++++++
 lib/librte_eal/freebsd/eal/eal_thread.c   |  9 +++++++++
 lib/librte_eal/linux/eal/eal_thread.c     | 15 +++++++++++++++
 lib/librte_eal/rte_eal_version.map        |  3 +++
 4 files changed, 44 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_lcore.h b/lib/librte_eal/common/include/rte_lcore.h
index 476b8ef3a..339046bc8 100644
--- a/lib/librte_eal/common/include/rte_lcore.h
+++ b/lib/librte_eal/common/include/rte_lcore.h
@@ -240,6 +240,23 @@ void rte_thread_get_affinity(rte_cpuset_t *cpusetp);
  */
 int rte_thread_setname(pthread_t id, const char *name);
 
+/**
+ * Get thread name.
+ *
+ * @note It fails with glibc < 2.12.
+ *
+ * @param id
+ *   Thread id.
+ * @param name
+ *   Thread name to set.
+ * @param len
+ *   Thread name buffer length.
+ * @return
+ *   On success, return 0; otherwise return a negative value.
+ */
+__rte_experimental
+int rte_thread_getname(pthread_t id, char *name, size_t len);
+
 /**
  * Create a control thread.
  *
diff --git a/lib/librte_eal/freebsd/eal/eal_thread.c b/lib/librte_eal/freebsd/eal/eal_thread.c
index 309b58726..ae7b57672 100644
--- a/lib/librte_eal/freebsd/eal/eal_thread.c
+++ b/lib/librte_eal/freebsd/eal/eal_thread.c
@@ -175,3 +175,12 @@ int rte_thread_setname(pthread_t id, const char *name)
 	pthread_set_name_np(id, name);
 	return 0;
 }
+
+int rte_thread_getname(pthread_t id, char *name, size_t len)
+{
+	RTE_SET_USED(id);
+	RTE_SET_USED(name);
+	RTE_SET_USED(len);
+
+	return -ENOTSUP;
+}
diff --git a/lib/librte_eal/linux/eal/eal_thread.c b/lib/librte_eal/linux/eal/eal_thread.c
index 379773b68..3f82b286c 100644
--- a/lib/librte_eal/linux/eal/eal_thread.c
+++ b/lib/librte_eal/linux/eal/eal_thread.c
@@ -186,3 +186,18 @@ int rte_thread_setname(pthread_t id, const char *name)
 	RTE_SET_USED(name);
 	return -ret;
 }
+
+int rte_thread_getname(pthread_t id, char *name, size_t len)
+{
+	int ret = ENOSYS;
+#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
+#if __GLIBC_PREREQ(2, 12)
+	ret = pthread_getname_np(id, name, len);
+#endif
+#endif
+	RTE_SET_USED(id);
+	RTE_SET_USED(name);
+	RTE_SET_USED(len);
+	return -ret;
+
+}
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 6cf507068..cadfa6465 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -335,4 +335,7 @@ EXPERIMENTAL {
 
 	# added in 20.02
 	rte_thread_is_intr;
+
+	# added in 20.05
+	rte_thread_getname;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 02/32] eal: define the public API for trace support
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 01/32] eal: introduce API for getting thread name jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 20:58   ` Mattias Rönnblom
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 03/32] eal/trace: implement trace register API jerinj
                   ` (30 subsequent siblings)
  32 siblings, 1 reply; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Thomas Monjalon, Bruce Richardson, John McNamara,
	Marko Kovacevic, Jerin Jacob, Sunil Kumar Kori
  Cc: dev, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

Define the public API for trace support.
This patch also adds support for the build infrastructure and
update the MAINTAINERS file for the trace subsystem.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 MAINTAINERS                               |   6 +
 config/common_base                        |   1 +
 config/rte_config.h                       |   1 +
 doc/api/doxy-api-index.md                 |   3 +-
 lib/librte_eal/common/Makefile            |   1 +
 lib/librte_eal/common/eal_common_trace.c  |   6 +
 lib/librte_eal/common/include/rte_trace.h | 525 ++++++++++++++++++++++
 lib/librte_eal/common/meson.build         |   2 +
 lib/librte_eal/freebsd/eal/Makefile       |   1 +
 lib/librte_eal/linux/eal/Makefile         |   1 +
 10 files changed, 546 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/common/eal_common_trace.c
 create mode 100644 lib/librte_eal/common/include/rte_trace.h

diff --git a/MAINTAINERS b/MAINTAINERS
index c3785554f..63d85c7da 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -196,6 +196,12 @@ F: app/test/test_string_fns.c
 F: app/test/test_tailq.c
 F: app/test/test_version.c
 
+Trace
+M: Jerin Jacob <jerinj@marvell.com>
+M: Sunil Kumar Kori <skori@marvell.com>
+F: lib/librte_eal/common/include/rte_trace*.h
+F: lib/librte_eal/common/eal_common_trace*.c
+
 Memory Allocation
 M: Anatoly Burakov <anatoly.burakov@intel.com>
 F: lib/librte_eal/common/include/rte_fbarray.h
diff --git a/config/common_base b/config/common_base
index 7ca2f28b1..efc195af2 100644
--- a/config/common_base
+++ b/config/common_base
@@ -99,6 +99,7 @@ CONFIG_RTE_MAX_MEMZONE=2560
 CONFIG_RTE_MAX_TAILQ=32
 CONFIG_RTE_ENABLE_ASSERT=n
 CONFIG_RTE_LOG_DP_LEVEL=RTE_LOG_INFO
+CONFIG_RTE_ENABLE_TRACE_DP=n
 CONFIG_RTE_LOG_HISTORY=256
 CONFIG_RTE_BACKTRACE=y
 CONFIG_RTE_LIBEAL_USE_HPET=n
diff --git a/config/rte_config.h b/config/rte_config.h
index d30786bc0..6b250288c 100644
--- a/config/rte_config.h
+++ b/config/rte_config.h
@@ -42,6 +42,7 @@
 #define RTE_MAX_MEMZONE 2560
 #define RTE_MAX_TAILQ 32
 #define RTE_LOG_DP_LEVEL RTE_LOG_INFO
+#define RTE_ENABLE_TRACE_DP 0
 #define RTE_BACKTRACE 1
 #define RTE_MAX_VFIO_CONTAINERS 64
 
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index dff496be0..190f0ccc2 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -174,7 +174,8 @@ The public API headers are grouped by topics:
   [hexdump]            (@ref rte_hexdump.h),
   [debug]              (@ref rte_debug.h),
   [log]                (@ref rte_log.h),
-  [errno]              (@ref rte_errno.h)
+  [errno]              (@ref rte_errno.h),
+  [trace]              (@ref rte_trace.h)
 
 - **misc**:
   [EAL config]         (@ref rte_eal.h),
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index c2c6d92cd..9384d6f6e 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -9,6 +9,7 @@ INC += rte_debug.h rte_eal.h rte_eal_interrupts.h
 INC += rte_errno.h rte_launch.h rte_lcore.h
 INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
+INC += rte_trace.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h
diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
new file mode 100644
index 000000000..e18ba1c95
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#include <rte_trace.h>
+
diff --git a/lib/librte_eal/common/include/rte_trace.h b/lib/librte_eal/common/include/rte_trace.h
new file mode 100644
index 000000000..d008b64f1
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_trace.h
@@ -0,0 +1,525 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_H_
+#define _RTE_TRACE_H_
+
+/**
+ * @file
+ *
+ * RTE Trace API
+ *
+ * This file provides the trace API to RTE applications.
+ *
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <rte_common.h>
+#include <rte_compat.h>
+
+/** The trace object. The trace APIs are based on this opaque object. */
+typedef uint64_t *rte_trace_t;
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Enumerate trace mode operation.
+ */
+enum rte_trace_mode_e {
+	/**
+	 * In this mode, When no space left in trace buffer, the subsequent
+	 * events overwrite the old events in the trace buffer.
+	 */
+	RTE_TRACE_MODE_OVERWRITE,
+	/**
+	 * In this mode, When no space left on trace buffer, the subsequent
+	 * events shall not be recorded in the trace buffer.
+	 */
+	RTE_TRACE_MODE_DISCARD,
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Test if global trace is enabled.
+ *
+ * @return
+ *    true if global trace is enabled, false otherwise.
+ */
+__rte_experimental
+bool rte_trace_global_is_enabled(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Test if global trace is disabled.
+ *
+ * @return
+ *    true if global trace is disabled, false otherwise.
+ */
+__rte_experimental
+bool rte_trace_global_is_disabled(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Test if a given trace is invalid.
+ * @param trace
+ *    The trace object.
+ * @return
+ *    true if global trace is invalid, false otherwise.
+ */
+__rte_experimental
+bool rte_trace_is_id_invalid(rte_trace_t trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Set the global trace level.
+ *
+ * After this call, trace with a level lower or equal than the level
+ * passed as argument will be captured in the trace buffer.
+ *
+ * @param level
+ *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ */
+__rte_experimental
+void rte_trace_global_level_set(uint32_t level);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Get the global trace level.
+ *
+ * @return
+ *   The current global trace level.
+ */
+__rte_experimental
+uint32_t rte_trace_global_level_get(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Set the global trace mode.
+ *
+ * After this call, All tracepoints will be switched to new mode.
+ *
+ * @param mode
+ *   Trace mode.
+ */
+__rte_experimental
+void rte_trace_global_mode_set(enum rte_trace_mode_e mode);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Get the global trace mode.
+ *
+ * @return
+ *   The current global trace mode.
+ */
+__rte_experimental
+enum rte_trace_mode_e rte_trace_global_mode_get(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Enable recording of the given tracepoint in the trace buffer.
+ *
+ * @param trace
+ *   The tracepoint object to enable.
+ * @return
+ *   - 0: Success.
+ *   - (-ERANGE): Trace object is not registered.
+ *   - (-EACCES): Trace object level is less than the global trace level.
+ */
+__rte_experimental
+int rte_trace_enable(rte_trace_t trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Disable recording of the given tracepoint in the trace buffer.
+ *
+ * @param trace
+ *   The tracepoint object to disable.
+ * @return
+ *   - 0: Success.
+ *   - (-ERANGE): Trace object is not registered.
+ */
+__rte_experimental
+int rte_trace_disable(rte_trace_t trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Test if given trace is enabled.
+ *
+ * @param trace
+ *    The trace object.
+ * @return
+ *    true if trace is enabled, false otherwise.
+ */
+__rte_experimental
+bool rte_trace_is_enabled(rte_trace_t trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Test if given trace is disabled.
+ *
+ * @param trace
+ *    The trace object.
+ * @return
+ *    true if trace is disabled, false otherwise.
+ */
+__rte_experimental
+bool rte_trace_is_disabled(rte_trace_t trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Set the trace level for the given tracepoint.
+ *
+ * After this call, if passed trace level lower or equal than the global trace
+ * level and this trace is enabled then trace will be captured in the
+ * trace buffer.
+ *
+ * @param trace
+ *    The trace object.
+ * @param level
+ *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ * @return
+ *   - 0: Success.
+ *   - (-EINVAL): Trace object is not registered or invalid trace level.
+ */
+__rte_experimental
+int rte_trace_level_set(rte_trace_t trace, uint32_t level);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Get the trace level for the given tracepoint.
+ *
+ * @param trace
+ *    The trace object.
+ * @return
+ *   - A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ *   - 0: Trace object is not registered.
+ */
+__rte_experimental
+uint32_t rte_trace_level_get(rte_trace_t trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Set the trace mode for the given tracepoint.
+ *
+ * @param trace
+ *    The trace object.
+ * @param mode
+ *   Trace mode.
+ * @return
+ *   - 0: Success.
+ *   - (-EINVAL): Trace object is not registered or invalid trace level.
+ */
+__rte_experimental
+int rte_trace_mode_set(rte_trace_t trace, enum rte_trace_mode_e mode);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Get the trace mode for the given tracepoint.
+ *
+ * @param trace
+ *    The trace object.
+ * @return
+ *   - Zero or positive: Mode encoded as enum rte_trace_mode_e.
+ *   - (-EINVAL): Trace object is not registered.
+ */
+__rte_experimental
+int rte_trace_mode_get(rte_trace_t trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Enable/Disable a set of tracepoints based on shell pattern.
+ *
+ * @param pattern
+ *   The match pattern identifying the tracepoint.
+ * @param enable
+ *    true to enable tracepoint, false to disable the tracepoint, upon match.
+ * @param[out] found
+ *    NULL value allowed, if not NULL, true if match found, false otherwise.
+ * @return
+ *   - 0: Success.
+ *   - (-ERANGE): Trace object is not registered.
+ */
+__rte_experimental
+int rte_trace_pattern(const char *pattern, bool enable, bool *found);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Enable/Disable a set of tracepoints based on regular expression.
+ *
+ * @param regex
+ *   A regular expression identifying the tracepoint.
+ * @param enable
+ *    true to enable tracepoint, false to disable the tracepoint, upon match.
+ * @param[out] found
+ *    NULL value allowed, if not NULL, true if match found, false otherwise.
+ * @return
+ *   - 0: Success.
+ *   - (-ERANGE): Trace object is not registered.
+ *   - (-EINVAL): Invalid regular expression rule.
+ */
+__rte_experimental
+int rte_trace_regexp(const char *regex, bool enable, bool *found);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Save the trace buffer to the trace directory.
+ *
+ * By default, trace directory will be created at HOME directory and this can be
+ * overridden by --trace-dir EAL parameter.
+ *
+ * @return
+ *   - 0: Success.
+ *   - <0 : Failure.
+ */
+__rte_experimental
+int rte_trace_save(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Search a trace object from its name.
+ *
+ * @param name
+ *   The name of the tracepoint.
+ * @return
+ *   The tracepoint object or NULL if not found.
+ */
+__rte_experimental
+rte_trace_t rte_trace_from_name(const char *name);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Dump the trace metadata to a file.
+ *
+ * @param f
+ *   A pointer to a file for output
+ * @return
+ *   - 0: Success.
+ *   - <0 : Failure.
+ */
+__rte_experimental
+int rte_trace_metadata_dump(FILE *f);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ * Dump the trace subsystem status to a file.
+ *
+ * @param f
+ *   A pointer to a file for output
+ */
+__rte_experimental
+void rte_trace_dump(FILE *f);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Test if the trace datapath compile-time option is enabled.
+ *
+ * @return
+ *   A positive value if trace datapath enabled, value zero otherwise.
+ */
+static __rte_always_inline int
+rte_trace_is_dp_enabled(void)
+{
+#ifdef RTE_ENABLE_TRACE_DP
+	return RTE_ENABLE_TRACE_DP;
+#else
+	return 0;
+#endif
+}
+
+/** Macro to define the tracepoint. */
+#define RTE_TRACE_POINT_DEFINE(tp)\
+uint64_t __attribute__((section("__rte_trace_point"))) __##tp
+
+/**
+ * Macro to define the tracepoint arguments in RTE_TRACE_POINT macro.
+
+ * @see RTE_TRACE_POINT RTE_TRACE_POINT_DP
+ */
+#define RTE_TRACE_POINT_ARGS
+
+/** @internal Helper Macro to support RTE_TRACE_POINT and RTE_TRACE_POINT_DP */
+#define __RTE_TRACE_POINT(_mode, _tp, _args, ...)\
+extern uint64_t __##_tp;\
+static __rte_always_inline void \
+_tp _args \
+{\
+	__rte_trace_emit_header_##_mode(&__##_tp);\
+	__VA_ARGS__\
+}
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Create a tracepoint definition.
+ *
+ * A tracepoint definition defines, for a given tracepoint:
+ * - Its input arguments. They are the C function style parameters to define
+ * the arguments of tracepoint function. These input arguments embedded using
+ * RTE_TRACE_POINT_ARGS macro.
+ * - Its output event fields. They are the sources of event fields that form
+ * the payload of any event that the execution of the tracepoint macro emits
+ * for this particular tracepoint. The application uses rte_trace_ctf_* macros
+ * to emit the output event fields.
+ *
+ * @param tp
+ *   Tracepoint object. Before using the tracepoint, an application needs to
+ * define the tracepoint using RTE_TRACE_POINT_DEFINE() macro.
+ * @param args
+ *   C function style input arguments to define the arguments to tracepoint
+ * function.
+ * @param ...
+ *   Define the payload of trace function. The payload will be formed using
+ * rte_trace_ctf_* macros, Use ";" delimiter between two payloads.
+ *
+ * @see RTE_TRACE_POINT_ARGS, RTE_TRACE_POINT_DEFINE, rte_trace_ctf_*
+ */
+#define RTE_TRACE_POINT(tp, args, ...)\
+	__RTE_TRACE_POINT(generic, tp, args, __VA_ARGS__)
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Create a tracepoint definition for the data path.
+ *
+ * Similar to RTE_TRACE_POINT(), except that it is removed at compilation time
+ * using RTE_ENABLE_TRACE_DP configuration parameter.
+ *
+ * @param tp
+ *   Tracepoint object. Before using the tracepoint, an application needs to
+ * define the tracepoint using RTE_TRACE_POINT_DEFINE() macro.
+ * @param args
+ *   C function style input arguments to define the arguments to tracepoint
+ * function.
+ * @param ...
+ *   Define the payload of trace function. The payload will be formed using
+ * rte_trace_ctf_* macros, Use ";" delimiter between two payloads.
+ *
+ * @see rte_trace_is_dp_enabled, RTE_TRACE_POINT()
+ */
+#define RTE_TRACE_POINT_DP(tp, args, ...)\
+	__RTE_TRACE_POINT(dp, tp, args, __VA_ARGS__)
+
+#ifdef __DOXYGEN__
+
+/**
+ * Macro to select rte_trace_ctf_* definition for trace register function.
+ *
+ * rte_trace_ctf_* emits different definitions for trace function.
+ * Application must define RTE_TRACE_POINT_REGISTER_SELECT before including
+ * rte_trace.h in the C file where RTE_TRACE_POINT_REGISTER() used.
+ *
+ * @see RTE_TRACE_POINT_REGISTER()
+ */
+#define RTE_TRACE_POINT_REGISTER_SELECT
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Register a dynamic tracepoint.
+ *
+ * @param trace
+ *   The tracepoint object created using RTE_TRACE_POINT_DEFINE().
+ * @param name
+ *   The name of the tracepoint object.
+ * @param level
+ *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ * @return
+ *   - 0: Successfully registered the tracepoint.
+ *   - <0: Failure to register the tracepoint.
+ *
+ * @see RTE_TRACE_POINT_REGISTER_SELECT
+ */
+#define RTE_TRACE_POINT_REGISTER(trace, name, level)
+
+/** Tracepoint function payload for uint64_t datatype */
+#define rte_trace_ctf_u64(val)
+/** Tracepoint function payload for int64_t datatype */
+#define rte_trace_ctf_i64(val)
+/** Tracepoint function payload for uint32_t datatype */
+#define rte_trace_ctf_u32(val)
+/** Tracepoint function payload for int32_t datatype */
+#define rte_trace_ctf_i32(val)
+/** Tracepoint function payload for uint16_t datatype */
+#define rte_trace_ctf_u16(val)
+/** Tracepoint function payload for int16_t datatype */
+#define rte_trace_ctf_i16(val)
+/** Tracepoint function payload for uint8_t datatype */
+#define rte_trace_ctf_u8(val)
+/** Tracepoint function payload for int8_t datatype */
+#define rte_trace_ctf_i8(val)
+/** Tracepoint function payload for int datatype */
+#define rte_trace_ctf_int(val)
+/** Tracepoint function payload for long datatype */
+#define rte_trace_ctf_long(val)
+/** Tracepoint function payload for float datatype */
+#define rte_trace_ctf_float(val)
+/** Tracepoint function payload for double datatype */
+#define rte_trace_ctf_double(val)
+/** Tracepoint function payload for pointer datatype */
+#define rte_trace_ctf_ptr(val)
+/** Tracepoint function payload for string datatype */
+#define rte_trace_ctf_string(val)
+
+#endif /* __DOXYGEN__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TRACE_H_ */
diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
index 2b97715a2..30fb9b85f 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -28,6 +28,7 @@ common_sources = files(
 	'eal_common_tailqs.c',
 	'eal_common_thread.c',
 	'eal_common_timer.c',
+	'eal_common_trace.c',
 	'eal_common_uuid.c',
 	'hotplug_mp.c',
 	'malloc_elem.c',
@@ -84,6 +85,7 @@ common_headers = files(
 	'include/rte_service_component.h',
 	'include/rte_string_fns.h',
 	'include/rte_tailq.h',
+	'include/rte_trace.h',
 	'include/rte_time.h',
 	'include/rte_uuid.h',
 	'include/rte_version.h',
diff --git a/lib/librte_eal/freebsd/eal/Makefile b/lib/librte_eal/freebsd/eal/Makefile
index b160b5790..b2fcc4212 100644
--- a/lib/librte_eal/freebsd/eal/Makefile
+++ b/lib/librte_eal/freebsd/eal/Makefile
@@ -60,6 +60,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += malloc_elem.c
diff --git a/lib/librte_eal/linux/eal/Makefile b/lib/librte_eal/linux/eal/Makefile
index e70cf104a..95470d3bb 100644
--- a/lib/librte_eal/linux/eal/Makefile
+++ b/lib/librte_eal/linux/eal/Makefile
@@ -68,6 +68,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += malloc_elem.c
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 03/32] eal/trace: implement trace register API
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 01/32] eal: introduce API for getting thread name jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 02/32] eal: define the public API for trace support jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-19 10:02   ` Mattias Rönnblom
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 04/32] eal/trace: implement trace operation APIs jerinj
                   ` (29 subsequent siblings)
  32 siblings, 1 reply; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Thomas Monjalon, Jerin Jacob, Sunil Kumar Kori
  Cc: dev, bruce.richardson, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

The consumers of trace API defines the tracepoint and registers
to eal. Internally these tracepoints will be stored in STAILQ
for future use. This patch implements the tracepoint
registration function.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 MAINTAINERS                                   |   1 +
 lib/librte_eal/common/Makefile                |   2 +-
 lib/librte_eal/common/eal_common_trace.c      | 107 +++++++++++++++++-
 lib/librte_eal/common/eal_trace.h             |  36 ++++++
 lib/librte_eal/common/include/rte_trace.h     |  29 +++++
 .../common/include/rte_trace_provider.h       |  24 ++++
 .../common/include/rte_trace_register.h       |  20 ++++
 lib/librte_eal/common/meson.build             |   2 +
 lib/librte_eal/rte_eal_version.map            |   1 +
 9 files changed, 220 insertions(+), 2 deletions(-)
 create mode 100644 lib/librte_eal/common/eal_trace.h
 create mode 100644 lib/librte_eal/common/include/rte_trace_provider.h
 create mode 100644 lib/librte_eal/common/include/rte_trace_register.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 63d85c7da..452fd2c4f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -201,6 +201,7 @@ M: Jerin Jacob <jerinj@marvell.com>
 M: Sunil Kumar Kori <skori@marvell.com>
 F: lib/librte_eal/common/include/rte_trace*.h
 F: lib/librte_eal/common/eal_common_trace*.c
+F: lib/librte_eal/common/eal_trace.h
 
 Memory Allocation
 M: Anatoly Burakov <anatoly.burakov@intel.com>
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 9384d6f6e..8f2f25c1d 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -9,7 +9,7 @@ INC += rte_debug.h rte_eal.h rte_eal_interrupts.h
 INC += rte_errno.h rte_launch.h rte_lcore.h
 INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
-INC += rte_trace.h
+INC += rte_trace.h rte_trace_provider.h rte_trace_register.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h
diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index e18ba1c95..ddde04de5 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -2,5 +2,110 @@
  * Copyright(C) 2020 Marvell International Ltd.
  */
 
-#include <rte_trace.h>
+#include <inttypes.h>
+#include <sys/queue.h>
 
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_lcore.h>
+#include <rte_per_lcore.h>
+#include <rte_string_fns.h>
+
+#include "eal_trace.h"
+
+RTE_DEFINE_PER_LCORE(volatile int, trace_point_sz);
+RTE_DEFINE_PER_LCORE(char, ctf_field[TRACE_CTF_FIELD_SIZE]);
+RTE_DEFINE_PER_LCORE(int, ctf_count);
+
+static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
+static struct trace trace;
+
+int
+__rte_trace_point_register(rte_trace_t handle, const char *name, uint32_t level,
+			 void (*fn)(void))
+{
+	char *field = RTE_PER_LCORE(ctf_field);
+	struct trace_point *tp;
+	uint16_t sz;
+
+	/* Sanity checks of arguments */
+	if (name == NULL || fn == NULL || handle == NULL) {
+		trace_err("invalid arguments");
+		rte_errno = EINVAL; goto fail;
+	}
+
+	/* Sanity check of level */
+	if (level > RTE_LOG_DEBUG || level > UINT8_MAX) {
+		trace_err("invalid log level=%d", level);
+		rte_errno = EINVAL; goto fail;
+
+	}
+
+	/* Check the size of the trace point object */
+	RTE_PER_LCORE(trace_point_sz) = 0;
+	RTE_PER_LCORE(ctf_count) = 0;
+	fn();
+	if (RTE_PER_LCORE(trace_point_sz) == 0) {
+		trace_err("missing rte_trace_emit_header() in register fn");
+		rte_errno = EBADF; goto fail;
+	}
+
+	/* Is size overflowed */
+	if (RTE_PER_LCORE(trace_point_sz) > UINT16_MAX) {
+		trace_err("trace point size overflowed");
+		rte_errno = ENOSPC; goto fail;
+	}
+
+	/* Are we running out of space to store trace points? */
+	if (trace.nb_trace_points > UINT16_MAX) {
+		trace_err("trace point exceeds the max count");
+		rte_errno = ENOSPC; goto fail;
+	}
+
+	/* Get the size of the trace point */
+	sz = RTE_PER_LCORE(trace_point_sz);
+	tp = calloc(1, sizeof(struct trace_point));
+	if (tp == NULL) {
+		trace_err("fail to allocate trace point memory");
+		rte_errno = ENOMEM; goto fail;
+	}
+
+	/* Initialize the trace point */
+	if (rte_strscpy(tp->name, name, TRACE_POINT_NAME_SIZE) < 0) {
+		trace_err("name is too long");
+		rte_errno = E2BIG;
+		goto free;
+	}
+
+	/* Copy the field data for future use */
+	if (rte_strscpy(tp->ctf_field, field, TRACE_CTF_FIELD_SIZE) < 0) {
+		trace_err("CTF field size is too long");
+		rte_errno = E2BIG;
+		goto free;
+	}
+
+	/* Clear field memory for the next event */
+	memset(field, 0, TRACE_CTF_FIELD_SIZE);
+
+	/* Form the trace handle */
+	*handle = sz;
+	*handle |= trace.nb_trace_points << __RTE_TRACE_FIELD_ID_SHIFT;
+	*handle |= (uint64_t)level << __RTE_TRACE_FIELD_LEVEL_SHIFT;
+
+	trace.nb_trace_points++;
+	tp->handle = handle;
+
+	/* Add the trace point at tail */
+	STAILQ_INSERT_TAIL(&tp_list, tp, next);
+	__atomic_thread_fence(__ATOMIC_RELEASE);
+
+	/* All Good !!! */
+	return 0;
+free:
+	free(tp);
+fail:
+	if (trace.register_errno == 0)
+		trace.register_errno = rte_errno;
+
+	return -rte_errno;
+}
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
new file mode 100644
index 000000000..9aef536a0
--- /dev/null
+++ b/lib/librte_eal/common/eal_trace.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef __EAL_TRACE_H
+#define __EAL_TRACE_H
+
+#include <rte_trace.h>
+
+#define trace_err(fmt, args...)\
+	RTE_LOG(ERR, EAL, "%s():%u " fmt "\n",\
+		__func__, __LINE__, ## args)
+
+#define trace_crit(fmt, args...)\
+	RTE_LOG(CRIT, EAL, "%s():%u " fmt "\n",\
+		__func__, __LINE__, ## args)
+
+#define TRACE_CTF_FIELD_SIZE 384
+#define TRACE_POINT_NAME_SIZE 64
+
+struct trace_point {
+	STAILQ_ENTRY(trace_point) next;
+	rte_trace_t handle;
+	char name[TRACE_POINT_NAME_SIZE];
+	char ctf_field[TRACE_CTF_FIELD_SIZE];
+};
+
+struct trace {
+	int register_errno;
+	uint32_t nb_trace_points;
+};
+
+/* Trace point list functions */
+STAILQ_HEAD(trace_point_head, trace_point);
+
+#endif /* __EAL_TRACE_H */
diff --git a/lib/librte_eal/common/include/rte_trace.h b/lib/librte_eal/common/include/rte_trace.h
index d008b64f1..da70dfdbb 100644
--- a/lib/librte_eal/common/include/rte_trace.h
+++ b/lib/librte_eal/common/include/rte_trace.h
@@ -518,6 +518,35 @@ _tp _args \
 
 #endif /* __DOXYGEN__ */
 
+/**
+ * @internal @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Helper function to register a dynamic tracepoint.
+ * Use RTE_TRACE_POINT_REGISTER() macro for tracepoint registration.
+ *
+ * @param trace
+ *   The tracepoint object created using RTE_TRACE_POINT_DEFINE().
+ * @param name
+ *   The name of the tracepoint object.
+ * @param level
+ *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ * @param f
+ *   Trace registration function.
+ * @return
+ *   - 0: Successfully registered the tracepoint.
+ *   - <0: Failure to register the tracepoint.
+ */
+__rte_experimental
+int __rte_trace_point_register(rte_trace_t trace, const char *name,
+			     uint32_t level, void (*fn)(void));
+
+#ifdef RTE_TRACE_POINT_REGISTER_SELECT
+#include <rte_trace_register.h>
+#else
+#include <rte_trace_provider.h>
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/common/include/rte_trace_provider.h b/lib/librte_eal/common/include/rte_trace_provider.h
new file mode 100644
index 000000000..b4da87ba1
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_trace_provider.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_H_
+#error do not include this file directly, use <rte_trace.h> instead
+#endif
+
+#ifndef _RTE_TRACE_PROVIDER_H_
+#define _RTE_TRACE_PROVIDER_H_
+
+#define __RTE_TRACE_EVENT_HEADER_ID_SHIFT (48)
+
+#define __RTE_TRACE_FIELD_ENABLE_MASK (1ULL << 63)
+#define __RTE_TRACE_FIELD_ENABLE_DISCARD (1ULL << 62)
+#define __RTE_TRACE_FIELD_SIZE_SHIFT 0
+#define __RTE_TRACE_FIELD_SIZE_MASK (0xffffULL << __RTE_TRACE_FIELD_SIZE_SHIFT)
+#define __RTE_TRACE_FIELD_ID_SHIFT (16)
+#define __RTE_TRACE_FIELD_ID_MASK (0xffffULL << __RTE_TRACE_FIELD_ID_SHIFT)
+#define __RTE_TRACE_FIELD_LEVEL_SHIFT (32)
+#define __RTE_TRACE_FIELD_LEVEL_MASK (0xffULL << __RTE_TRACE_FIELD_LEVEL_SHIFT)
+
+
+#endif /* _RTE_TRACE_PROVIDER_H_ */
diff --git a/lib/librte_eal/common/include/rte_trace_register.h b/lib/librte_eal/common/include/rte_trace_register.h
new file mode 100644
index 000000000..e9940b414
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_trace_register.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_H_
+#error do not include this file directly, use <rte_trace.h> instead
+#endif
+
+#ifndef _RTE_TRACE_REGISTER_H_
+#define _RTE_TRACE_REGISTER_H_
+
+#include <rte_per_lcore.h>
+
+RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz);
+
+#define RTE_TRACE_POINT_REGISTER(trace, name, level)\
+	__rte_trace_point_register(&__##trace, RTE_STR(name),\
+			RTE_LOG_ ## level, (void (*)(void)) trace)
+
+#endif /* _RTE_TRACE_REGISTER_H_ */
diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
index 30fb9b85f..88c14ebe5 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -86,6 +86,8 @@ common_headers = files(
 	'include/rte_string_fns.h',
 	'include/rte_tailq.h',
 	'include/rte_trace.h',
+	'include/rte_trace_provider.h',
+	'include/rte_trace_register.h',
 	'include/rte_time.h',
 	'include/rte_uuid.h',
 	'include/rte_version.h',
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index cadfa6465..d97d14845 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -338,4 +338,5 @@ EXPERIMENTAL {
 
 	# added in 20.05
 	rte_thread_getname;
+	__rte_trace_point_register;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 04/32] eal/trace: implement trace operation APIs
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (2 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 03/32] eal/trace: implement trace register API jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-19 10:16   ` Mattias Rönnblom
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 05/32] eal/trace: add internal trace init and fini interface jerinj
                   ` (28 subsequent siblings)
  32 siblings, 1 reply; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

This patch implements the following public trace APIs.

- rte_trace_global_is_enabled()
- rte_trace_global_is_disabled()
- rte_trace_is_id_invalid()
- rte_trace_global_level_set()
- rte_trace_global_level_get()
- rte_trace_global_mode_set()
- rte_trace_global_mode_get()
- rte_trace_enable()
- rte_trace_disable()
- rte_trace_is_enabled()
- rte_trace_is_disabled()
- rte_trace_level_set()
- rte_trace_level_get()
- rte_trace_mode_set()
- rte_trace_mode_get()
- rte_trace_pattern()
- rte_trace_regexp()
- rte_trace_from_name()

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c | 249 +++++++++++++++++++++++
 lib/librte_eal/common/eal_trace.h        |  11 +
 lib/librte_eal/rte_eal_version.map       |  18 ++
 3 files changed, 278 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index ddde04de5..f8855e09b 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -3,7 +3,9 @@
  */
 
 #include <inttypes.h>
+#include <fnmatch.h>
 #include <sys/queue.h>
+#include <regex.h>
 
 #include <rte_common.h>
 #include <rte_errno.h>
@@ -20,6 +22,253 @@ RTE_DEFINE_PER_LCORE(int, ctf_count);
 static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
 static struct trace trace;
 
+bool
+rte_trace_global_is_enabled(void)
+{
+	return trace.global_status;
+}
+
+bool
+rte_trace_global_is_disabled(void)
+{
+	return !trace.global_status;
+}
+
+void
+rte_trace_global_level_set(uint32_t level)
+{
+	struct trace_point *tp;
+
+	trace.level = level;
+
+	if (rte_trace_global_is_disabled())
+		return;
+
+	STAILQ_FOREACH(tp, &tp_list, next) {
+		if (level >= rte_trace_level_get(tp->handle))
+			rte_trace_enable(tp->handle);
+		else
+			rte_trace_disable(tp->handle);
+	}
+}
+
+uint32_t
+rte_trace_global_level_get(void)
+{
+	return trace.level;
+}
+
+void
+rte_trace_global_mode_set(enum rte_trace_mode_e mode)
+{
+	struct trace_point *tp;
+
+	if (rte_trace_global_is_disabled())
+		return;
+
+	STAILQ_FOREACH(tp, &tp_list, next)
+		rte_trace_mode_set(tp->handle, mode);
+
+	trace.mode = mode;
+}
+
+enum
+rte_trace_mode_e rte_trace_global_mode_get(void)
+{
+	return trace.mode;
+}
+
+bool
+rte_trace_is_id_invalid(rte_trace_t t)
+{
+	if (trace_id_get(t) >= trace.nb_trace_points)
+		return true;
+
+	return false;
+}
+
+bool
+rte_trace_is_enabled(rte_trace_t trace)
+{
+	uint64_t val;
+
+	if (rte_trace_is_id_invalid(trace))
+		return false;
+
+	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
+	return !!(val & __RTE_TRACE_FIELD_ENABLE_MASK);
+}
+
+bool
+rte_trace_is_disabled(rte_trace_t trace)
+{
+	uint64_t val;
+
+	if (rte_trace_is_id_invalid(trace))
+		return true;
+
+	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
+	return !!!(val & __RTE_TRACE_FIELD_ENABLE_MASK);
+}
+
+int
+rte_trace_enable(rte_trace_t trace)
+{
+	if (rte_trace_is_id_invalid(trace))
+		return -ERANGE;
+
+	if (rte_trace_level_get(trace) > rte_trace_global_level_get())
+		return -EACCES;
+
+	__atomic_or_fetch(trace, __RTE_TRACE_FIELD_ENABLE_MASK,
+			  __ATOMIC_RELEASE);
+	return 0;
+}
+
+int
+rte_trace_disable(rte_trace_t trace)
+{
+	if (rte_trace_is_id_invalid(trace))
+		return -ERANGE;
+
+	__atomic_and_fetch(trace, ~__RTE_TRACE_FIELD_ENABLE_MASK,
+			   __ATOMIC_RELEASE);
+	return 0;
+}
+
+uint32_t
+rte_trace_level_get(rte_trace_t trace)
+{
+	uint64_t val;
+
+	if (rte_trace_is_id_invalid(trace))
+		return 0;
+
+	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
+	val &= __RTE_TRACE_FIELD_LEVEL_MASK;
+	val = val >> __RTE_TRACE_FIELD_LEVEL_SHIFT;
+
+	return val;
+}
+
+int
+rte_trace_level_set(rte_trace_t trace, uint32_t level)
+{
+	uint64_t val;
+
+	if (rte_trace_is_id_invalid(trace) || level > RTE_LOG_DEBUG)
+		return -EINVAL;
+
+	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
+	val &= ~__RTE_TRACE_FIELD_LEVEL_MASK;
+	val |= (uint64_t)level << __RTE_TRACE_FIELD_LEVEL_SHIFT;
+	__atomic_store_n(trace, val, __ATOMIC_RELEASE);
+
+	if (level <= rte_trace_global_level_get())
+		rte_trace_enable(trace);
+	else
+		rte_trace_disable(trace);
+
+	return 0;
+}
+
+int
+rte_trace_mode_get(rte_trace_t trace)
+{
+	uint64_t val;
+
+	if (rte_trace_is_id_invalid(trace))
+		return -EINVAL;
+
+	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
+
+	return !!(val & __RTE_TRACE_FIELD_ENABLE_DISCARD);
+}
+
+int
+rte_trace_mode_set(rte_trace_t trace, enum rte_trace_mode_e mode)
+{
+	if (rte_trace_is_id_invalid(trace) || mode >  RTE_TRACE_MODE_DISCARD)
+		return -EINVAL;
+
+	if (mode == RTE_TRACE_MODE_OVERWRITE)
+		__atomic_and_fetch(trace, ~__RTE_TRACE_FIELD_ENABLE_DISCARD,
+				   __ATOMIC_RELEASE);
+	else
+		__atomic_or_fetch(trace, __RTE_TRACE_FIELD_ENABLE_DISCARD,
+				   __ATOMIC_RELEASE);
+
+	return 0;
+}
+
+int
+rte_trace_pattern(const char *pattern, bool enable, bool *found)
+{
+	struct trace_point *tp;
+	int rc;
+
+	if (found)
+		*found = false;
+
+	STAILQ_FOREACH(tp, &tp_list, next) {
+		if (fnmatch(pattern, tp->name, 0) == 0) {
+			if (found)
+				*found = true;
+			if (enable)
+				rc = rte_trace_enable(tp->handle);
+			else
+				rc = rte_trace_disable(tp->handle);
+		}
+		if (rc < 0)
+			return rc;
+	}
+	return 0;
+}
+
+int
+rte_trace_regexp(const char *regex, bool enable, bool *found)
+{
+	struct trace_point *tp;
+	regex_t r;
+	int rc;
+
+	if (regcomp(&r, regex, 0) != 0)
+		return -EINVAL;
+
+	if (found)
+		*found = false;
+
+	STAILQ_FOREACH(tp, &tp_list, next) {
+		if (regexec(&r, tp->name, 0, NULL, 0) == 0) {
+			if (found)
+				*found = true;
+			if (enable)
+				rc = rte_trace_enable(tp->handle);
+			else
+				rc = rte_trace_disable(tp->handle);
+		}
+		if (rc < 0)
+			return rc;
+	}
+	regfree(&r);
+	return 0;
+}
+
+rte_trace_t
+rte_trace_from_name(const char *name)
+{
+	struct trace_point *tp;
+
+	if (name == NULL)
+		return NULL;
+
+	STAILQ_FOREACH(tp, &tp_list, next)
+		if (strncmp(tp->name, name, TRACE_POINT_NAME_SIZE) == 0)
+			return tp->handle;
+
+	return NULL;
+}
+
 int
 __rte_trace_point_register(rte_trace_t handle, const char *name, uint32_t level,
 			 void (*fn)(void))
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index 9aef536a0..9f90a5d17 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -27,9 +27,20 @@ struct trace_point {
 
 struct trace {
 	int register_errno;
+	bool global_status;
+	enum rte_trace_mode_e mode;
+	uint32_t level;
 	uint32_t nb_trace_points;
 };
 
+/* Helper functions */
+static inline uint16_t
+trace_id_get(rte_trace_t trace)
+{
+	return (*trace & __RTE_TRACE_FIELD_ID_MASK) >>
+		__RTE_TRACE_FIELD_ID_SHIFT;
+}
+
 /* Trace point list functions */
 STAILQ_HEAD(trace_point_head, trace_point);
 
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index d97d14845..841ebc5f9 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -339,4 +339,22 @@ EXPERIMENTAL {
 	# added in 20.05
 	rte_thread_getname;
 	__rte_trace_point_register;
+	rte_trace_global_is_enabled;
+	rte_trace_global_is_disabled;
+	rte_trace_is_id_invalid;
+	rte_trace_global_level_set;
+	rte_trace_global_level_get;
+	rte_trace_global_mode_set;
+	rte_trace_global_mode_get;
+	rte_trace_enable;
+	rte_trace_disable;
+	rte_trace_is_enabled;
+	rte_trace_is_disabled;
+	rte_trace_level_set;
+	rte_trace_level_get;
+	rte_trace_mode_set;
+	rte_trace_mode_get;
+	rte_trace_pattern;
+	rte_trace_regexp;
+	rte_trace_from_name;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 05/32] eal/trace: add internal trace init and fini interface
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (3 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 04/32] eal/trace: implement trace operation APIs jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-19 10:35   ` Mattias Rönnblom
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 06/32] eal/trace: get bootup timestamp for trace jerinj
                   ` (27 subsequent siblings)
  32 siblings, 1 reply; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori, Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

Define eal_trace_init() and eal_trace_fini() EAL interface
functions that rte_eal_init() and rte_eal_cleanup() function can be
use to initialize and finalize the trace subsystem.
eal_trace_init() function will add the following
functionality if trace is enabled through EAL command line param.

- Test for trace registration failure.
- Test for duplicate trace name registration
- Generate UUID ver 4.
- Create a trace directory

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c      |  54 ++++++
 .../common/eal_common_trace_utils.c           | 173 ++++++++++++++++++
 lib/librte_eal/common/eal_trace.h             |  21 +++
 lib/librte_eal/common/meson.build             |   1 +
 lib/librte_eal/freebsd/eal/Makefile           |   1 +
 lib/librte_eal/linux/eal/Makefile             |   1 +
 6 files changed, 251 insertions(+)
 create mode 100644 lib/librte_eal/common/eal_common_trace_utils.c

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index f8855e09b..abb221cf3 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -22,6 +22,60 @@ RTE_DEFINE_PER_LCORE(int, ctf_count);
 static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
 static struct trace trace;
 
+struct trace*
+trace_obj_get(void)
+{
+	return &trace;
+}
+
+struct trace_point_head *
+trace_list_head_get(void)
+{
+	return &tp_list;
+}
+
+int
+eal_trace_init(void)
+{
+	/* One of the Trace registration failed */
+	if (trace.register_errno) {
+		rte_errno = trace.register_errno;
+		goto fail;
+	}
+
+	if (rte_trace_global_is_disabled())
+		return 0;
+
+	rte_spinlock_init(&trace.lock);
+
+	/* Is duplicate trace name registered */
+	if (trace_has_duplicate_entry())
+		goto fail;
+
+	/* Generate UUID ver 4 with total size of events and number of events */
+	trace_uuid_generate();
+
+	/* Create trace directory */
+	if (trace_mkdir())
+		goto fail;
+
+
+	rte_trace_global_mode_set(trace.mode);
+
+	return 0;
+
+fail:
+	trace_err("failed to initialize trace [%s]", rte_strerror(rte_errno));
+	return -rte_errno;
+}
+
+void
+eal_trace_fini(void)
+{
+	if (rte_trace_global_is_disabled())
+		return;
+}
+
 bool
 rte_trace_global_is_enabled(void)
 {
diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
new file mode 100644
index 000000000..f7d59774c
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -0,0 +1,173 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#include <fnmatch.h>
+#include <pwd.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_string_fns.h>
+
+#include "eal_filesystem.h"
+#include "eal_trace.h"
+
+static bool
+trace_entry_compare(const char *name)
+{
+	struct trace_point_head *tp_list = trace_list_head_get();
+	struct trace_point *tp;
+	int count = 0;
+
+	STAILQ_FOREACH(tp, tp_list, next) {
+		if (strncmp(tp->name, name, TRACE_POINT_NAME_SIZE) == 0)
+			count++;
+		if (count > 1) {
+			trace_err("found duplicate entry %s", name);
+			rte_errno = EEXIST;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+bool
+trace_has_duplicate_entry(void)
+{
+	struct trace_point_head *tp_list = trace_list_head_get();
+	struct trace_point *tp;
+
+	/* Is duplicate trace name registered */
+	STAILQ_FOREACH(tp, tp_list, next)
+		if (trace_entry_compare(tp->name))
+			return true;
+
+	return false;
+}
+
+void
+trace_uuid_generate(void)
+{
+	struct trace_point_head *tp_list = trace_list_head_get();
+	struct trace *trace = trace_obj_get();
+	struct trace_point *tp;
+	uint64_t sz_total = 0;
+
+	/* Go over the registered trace points to get total size of events */
+	STAILQ_FOREACH(tp, tp_list, next) {
+		const uint16_t sz = *tp->handle & __RTE_TRACE_FIELD_SIZE_MASK;
+		sz_total += sz;
+	}
+
+	rte_uuid_t uuid = RTE_UUID_INIT(sz_total, trace->nb_trace_points,
+		0x4370, 0x8f50, 0x222ddd514176ULL);
+	rte_uuid_copy(trace->uuid, uuid);
+}
+
+static int
+trace_session_name_generate(char *trace_dir)
+{
+	struct tm *tm_result;
+	time_t tm;
+	int rc;
+
+	tm = time(NULL);
+	if ((int)tm == -1)
+		goto fail;
+
+	tm_result = localtime(&tm);
+	if (tm_result == NULL)
+		goto fail;
+
+	rc = rte_strscpy(trace_dir,
+			 eal_get_hugefile_prefix(), TRACE_PREFIX_LEN);
+	if (rc == -E2BIG)
+		rc = TRACE_PREFIX_LEN;
+	trace_dir[rc++] = '-';
+
+	rc = strftime(trace_dir + rc, TRACE_DIR_STR_LEN - rc,
+			"%Y-%m-%d-%p-%I-%M-%S", tm_result);
+	if (rc == 0)
+		goto fail;
+
+	return rc;
+fail:
+	rte_errno = errno;
+	return -rte_errno;
+}
+
+static int
+trace_dir_default_path_get(char *dir_path)
+{
+	struct trace *trace = trace_obj_get();
+	uint32_t size = sizeof(trace->dir);
+	struct passwd *pwd;
+	char *home_dir;
+
+	/* First check for shell environment variable */
+	home_dir = getenv("HOME");
+	if (home_dir == NULL) {
+		/* Fallback to password file entry */
+		pwd = getpwuid(getuid());
+		if (pwd == NULL)
+			return -EINVAL;
+
+		home_dir = pwd->pw_dir;
+	}
+
+	/* Append dpdk-traces to directory */
+	if (snprintf(dir_path, size, "%s/dpdk-traces/", home_dir) < 0)
+		return -ENAMETOOLONG;
+
+	return 0;
+}
+
+int
+trace_mkdir(void)
+{
+	struct trace *trace = trace_obj_get();
+	char session[TRACE_DIR_STR_LEN];
+	char *dir_path;
+	int rc;
+
+	if (!trace->dir_offset) {
+		dir_path = (char *)calloc(1, sizeof(trace->dir));
+		if (dir_path == NULL) {
+			trace_err("fail to allocate memory\n");
+			return -ENOMEM;
+		}
+
+		rc = trace_dir_default_path_get(dir_path);
+		if (rc < 0) {
+			trace_err("fail to get default path\n");
+			free(dir_path);
+			return rc;
+		}
+
+	}
+
+	/* Create the path if it t exist, no "mkdir -p" available here */
+	rc = mkdir(trace->dir, 0700);
+	if (rc < 0 && errno != EEXIST) {
+		trace_err("mkdir %s failed [%s]", trace->dir, strerror(errno));
+		rte_errno = errno;
+		return -rte_errno;
+	}
+
+	rc = trace_session_name_generate(session);
+	if (rc < 0)
+		return rc;
+
+	rc = mkdir(trace->dir, 0700);
+	if (rc < 0) {
+		trace_err("mkdir %s failed [%s]", trace->dir, strerror(errno));
+		rte_errno = errno;
+		return -rte_errno;
+	}
+
+	RTE_LOG(INFO, EAL, "Trace dir: %s\n", trace->dir);
+	return 0;
+}
+
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index 9f90a5d17..10c2f03ac 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -5,7 +5,9 @@
 #ifndef __EAL_TRACE_H
 #define __EAL_TRACE_H
 
+#include <rte_spinlock.h>
 #include <rte_trace.h>
+#include <rte_uuid.h>
 
 #define trace_err(fmt, args...)\
 	RTE_LOG(ERR, EAL, "%s():%u " fmt "\n",\
@@ -15,6 +17,8 @@
 	RTE_LOG(CRIT, EAL, "%s():%u " fmt "\n",\
 		__func__, __LINE__, ## args)
 
+#define TRACE_PREFIX_LEN 12
+#define TRACE_DIR_STR_LEN (sizeof("YYYY-mm-dd-AM-HH-MM-SS") + TRACE_PREFIX_LEN)
 #define TRACE_CTF_FIELD_SIZE 384
 #define TRACE_POINT_NAME_SIZE 64
 
@@ -26,11 +30,15 @@ struct trace_point {
 };
 
 struct trace {
+	char dir[PATH_MAX];
+	int dir_offset;
 	int register_errno;
 	bool global_status;
 	enum rte_trace_mode_e mode;
+	rte_uuid_t uuid;
 	uint32_t level;
 	uint32_t nb_trace_points;
+	rte_spinlock_t lock;
 };
 
 /* Helper functions */
@@ -41,7 +49,20 @@ trace_id_get(rte_trace_t trace)
 		__RTE_TRACE_FIELD_ID_SHIFT;
 }
 
+/* Trace object functions */
+struct trace *trace_obj_get(void);
+
 /* Trace point list functions */
 STAILQ_HEAD(trace_point_head, trace_point);
+struct trace_point_head *trace_list_head_get(void);
+
+/* Util functions */
+bool trace_has_duplicate_entry(void);
+void trace_uuid_generate(void);
+int trace_mkdir(void);
+
+/* EAL interface */
+int eal_trace_init(void);
+void eal_trace_fini(void);
 
 #endif /* __EAL_TRACE_H */
diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
index 88c14ebe5..716a255d2 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -29,6 +29,7 @@ common_sources = files(
 	'eal_common_thread.c',
 	'eal_common_timer.c',
 	'eal_common_trace.c',
+	'eal_common_trace_utils.c',
 	'eal_common_uuid.c',
 	'hotplug_mp.c',
 	'malloc_elem.c',
diff --git a/lib/librte_eal/freebsd/eal/Makefile b/lib/librte_eal/freebsd/eal/Makefile
index b2fcc4212..8c444da02 100644
--- a/lib/librte_eal/freebsd/eal/Makefile
+++ b/lib/librte_eal/freebsd/eal/Makefile
@@ -61,6 +61,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_utils.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += malloc_elem.c
diff --git a/lib/librte_eal/linux/eal/Makefile b/lib/librte_eal/linux/eal/Makefile
index 95470d3bb..bd9993e58 100644
--- a/lib/librte_eal/linux/eal/Makefile
+++ b/lib/librte_eal/linux/eal/Makefile
@@ -69,6 +69,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_utils.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += malloc_elem.c
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 06/32] eal/trace: get bootup timestamp for trace
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (4 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 05/32] eal/trace: add internal trace init and fini interface jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-19 10:43   ` Mattias Rönnblom
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 07/32] eal/trace: create CTF TDSL metadata in memory jerinj
                   ` (26 subsequent siblings)
  32 siblings, 1 reply; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

Find epoch_sec, epoch_nsec and uptime_ticks time information
on eal_trace_init()/bootup to derive the time in the trace.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c      |  3 +++
 .../common/eal_common_trace_utils.c           | 22 +++++++++++++++++++
 lib/librte_eal/common/eal_trace.h             |  5 +++++
 3 files changed, 30 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index abb221cf3..51c4dd550 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -59,6 +59,9 @@ eal_trace_init(void)
 	if (trace_mkdir())
 		goto fail;
 
+	/* Save current epoch timestamp for future use */
+	if (trace_epoch_time_save())
+		goto fail;
 
 	rte_trace_global_mode_set(trace.mode);
 
diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
index f7d59774c..340ab62e4 100644
--- a/lib/librte_eal/common/eal_common_trace_utils.c
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -98,6 +98,28 @@ trace_session_name_generate(char *trace_dir)
 	return -rte_errno;
 }
 
+int
+trace_epoch_time_save(void)
+{
+	struct trace *trace = trace_obj_get();
+	struct timespec epoch = { 0, 0 };
+	uint64_t avg, start, end;
+
+	start = rte_get_tsc_cycles();
+	if (clock_gettime(CLOCK_REALTIME, &epoch) < 0) {
+		trace_err("failed to get the epoch time");
+		return -1;
+	}
+	end = rte_get_tsc_cycles();
+	avg = (start + end) >> 1;
+
+	trace->epoch_sec = (uint64_t) epoch.tv_sec;
+	trace->epoch_nsec = (uint64_t) epoch.tv_nsec;
+	trace->uptime_ticks = avg;
+
+	return 0;
+}
+
 static int
 trace_dir_default_path_get(char *dir_path)
 {
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index 10c2f03ac..9807613d2 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -5,6 +5,7 @@
 #ifndef __EAL_TRACE_H
 #define __EAL_TRACE_H
 
+#include <rte_cycles.h>
 #include <rte_spinlock.h>
 #include <rte_trace.h>
 #include <rte_uuid.h>
@@ -38,6 +39,9 @@ struct trace {
 	rte_uuid_t uuid;
 	uint32_t level;
 	uint32_t nb_trace_points;
+	uint64_t epoch_sec;
+	uint64_t epoch_nsec;
+	uint64_t uptime_ticks;
 	rte_spinlock_t lock;
 };
 
@@ -60,6 +64,7 @@ struct trace_point_head *trace_list_head_get(void);
 bool trace_has_duplicate_entry(void);
 void trace_uuid_generate(void);
 int trace_mkdir(void);
+int trace_epoch_time_save(void);
 
 /* EAL interface */
 int eal_trace_init(void);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 07/32] eal/trace: create CTF TDSL metadata in memory
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (5 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 06/32] eal/trace: get bootup timestamp for trace jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 08/32] eal/trace: handle CTF keyword collision jerinj
                   ` (25 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori, Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

Common trace format(CTF) defines the metadata[1][2] for trace events,
This patch creates the metadata for the DPDK events in memory and
latter this will be saved to trace directory on rte_trace_save()
invocation.

[1] https://diamon.org/ctf/#specification
[2] https://diamon.org/ctf/#examples

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c     |  11 +-
 lib/librte_eal/common/eal_common_trace_ctf.c | 302 +++++++++++++++++++
 lib/librte_eal/common/eal_trace.h            |   7 +
 lib/librte_eal/common/meson.build            |   1 +
 lib/librte_eal/freebsd/eal/Makefile          |   1 +
 lib/librte_eal/linux/eal/Makefile            |   1 +
 6 files changed, 321 insertions(+), 2 deletions(-)
 create mode 100644 lib/librte_eal/common/eal_common_trace_ctf.c

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index 51c4dd550..fe9e363f7 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -55,18 +55,24 @@ eal_trace_init(void)
 	/* Generate UUID ver 4 with total size of events and number of events */
 	trace_uuid_generate();
 
+	/* Generate CTF TDSL metadata */
+	if (trace_metadata_create())
+		goto fail;
+
 	/* Create trace directory */
 	if (trace_mkdir())
-		goto fail;
+		goto free_meta;
 
 	/* Save current epoch timestamp for future use */
 	if (trace_epoch_time_save())
-		goto fail;
+		goto free_meta;
 
 	rte_trace_global_mode_set(trace.mode);
 
 	return 0;
 
+free_meta:
+	trace_metadata_destroy();
 fail:
 	trace_err("failed to initialize trace [%s]", rte_strerror(rte_errno));
 	return -rte_errno;
@@ -77,6 +83,7 @@ eal_trace_fini(void)
 {
 	if (rte_trace_global_is_disabled())
 		return;
+	trace_metadata_destroy();
 }
 
 bool
diff --git a/lib/librte_eal/common/eal_common_trace_ctf.c b/lib/librte_eal/common/eal_common_trace_ctf.c
new file mode 100644
index 000000000..5ad44cc8d
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_trace_ctf.c
@@ -0,0 +1,302 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#include <inttypes.h>
+#include <time.h>
+
+#include <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_time.h>
+#include <rte_trace.h>
+#include <rte_version.h>
+
+#include "eal_trace.h"
+
+__rte_format_printf(2, 0)
+static int
+metadata_printf(char **str, const char *fmt, ...)
+{
+	va_list ap;
+	int rc;
+
+	*str = NULL;
+	va_start(ap, fmt);
+	rc = vasprintf(str, fmt, ap);
+	va_end(ap);
+
+	return rc;
+}
+
+static int
+meta_copy(char **meta, int *offset, char *str, int rc)
+{
+	int count = *offset;
+	char *ptr = *meta;
+
+	if (rc < 0)
+		return rc;
+
+	ptr = realloc(ptr, count + rc);
+	if (ptr == NULL)
+		goto free_str;
+
+	memcpy(RTE_PTR_ADD(ptr, count), str, rc);
+	count += rc;
+	free(str);
+
+	*meta = ptr;
+	*offset = count;
+
+	return rc;
+
+free_str:
+	if (str)
+		free(str);
+	return -ENOMEM;
+}
+
+static int
+meta_data_type_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"/* CTF 1.8 */\n"
+		"typealias integer {size = 8; base = x;}:= uint8_t;\n"
+		"typealias integer {size = 16; base = x;} := uint16_t;\n"
+		"typealias integer {size = 32; base = x;} := uint32_t;\n"
+		"typealias integer {size = 64; base = x;} := uint64_t;\n"
+		"typealias integer {size = 8; signed = true;}  := int8_t;\n"
+		"typealias integer {size = 16; signed = true;} := int16_t;\n"
+		"typealias integer {size = 32; signed = true;} := int32_t;\n"
+		"typealias integer {size = 64; signed = true;} := int64_t;\n"
+#ifdef RTE_ARCH_64
+		"typealias integer {size = 64; base = x;} := uintptr_t;\n"
+#else
+		"typealias integer {size = 32; base = x;} := uintptr_t;\n"
+#endif
+#ifdef RTE_ARCH_64
+		"typealias integer {size = 64; base = x;} := long;\n"
+#else
+		"typealias integer {size = 32; base = x;} := long;\n"
+#endif
+		"typealias integer {size = 8; signed = false; encoding = ASCII; } := string_bounded_t;\n\n"
+		"typealias floating_point {\n"
+		"    exp_dig = 8;\n"
+		"    mant_dig = 24;\n"
+		"} := float;\n\n"
+		"typealias floating_point {\n"
+		"    exp_dig = 11;\n"
+		"    mant_dig = 53;\n"
+		"} := double;\n\n");
+
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+is_be(void)
+{
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+	return 1;
+#else
+	return 0;
+#endif
+}
+
+static int
+meta_header_emit(char **meta, int *offset)
+{
+	struct trace *trace = trace_obj_get();
+	char uustr[RTE_UUID_STRLEN];
+	char *str = NULL;
+	int rc;
+
+	rte_uuid_unparse(trace->uuid, uustr, RTE_UUID_STRLEN);
+	rc = metadata_printf(&str,
+		"trace {\n"
+		"    major = 1;\n"
+		"    minor = 8;\n"
+		"    uuid = \"%s\";\n"
+		"    byte_order = %s;\n"
+		"    packet.header := struct {\n"
+		"	    uint32_t magic;\n"
+		"	    uint8_t  uuid[16];\n"
+		"    };\n"
+		"};\n\n", uustr, is_be() ? "be" : "le");
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_env_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"env {\n"
+		"    dpdk_version = \"%s\";\n"
+		"    tracer_name = \"dpdk\";\n"
+		"};\n\n", rte_version());
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_clock_pass1_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"clock {\n"
+		"    name = \"dpdk\";\n"
+		"    freq = ");
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_clock_pass2_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"%20"PRIu64";\n"
+		"    offset_s =", 0);
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_clock_pass3_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"%20"PRIu64";\n"
+		"    offset =", 0);
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_clock_pass4_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"%20"PRIu64";\n};\n\n"
+		"typealias integer {\n"
+		"    size = 48; align = 1; signed = false;\n"
+		"    map = clock.dpdk.value;\n"
+		"} := uint48_clock_dpdk_t;\n\n", 0);
+
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_stream_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"stream {\n"
+		"    packet.context := struct {\n"
+		"         uint32_t cpu_id;\n"
+		"         string_bounded_t name[32];\n"
+		"    };\n"
+		"    event.header := struct {\n"
+		"          uint48_clock_dpdk_t timestamp;\n"
+		"          uint16_t id;\n"
+		"    } align(64);\n"
+		"};\n\n");
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_event_emit(char **meta, int *offset, struct trace_point *tp)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"event {\n"
+		"    id = %d;\n"
+		"    name = \"%s\";\n"
+		"    fields := struct {\n"
+		"        %s\n"
+		"    };\n"
+		"};\n\n", trace_id_get(tp->handle), tp->name, tp->ctf_field);
+	return meta_copy(meta, offset, str, rc);
+}
+
+int
+trace_metadata_create(void)
+{
+	struct trace_point_head *tp_list = trace_list_head_get();
+	struct trace *trace = trace_obj_get();
+	struct trace_point *tp;
+	int rc, offset = 0;
+	char *meta = NULL;
+
+	rc = meta_data_type_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+
+	rc = meta_header_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+
+	rc = meta_env_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+
+	rc = meta_clock_pass1_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+	trace->ctf_meta_offset_freq = offset;
+
+	rc = meta_clock_pass2_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+	trace->ctf_meta_offset_freq_off_s = offset;
+
+	rc = meta_clock_pass3_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+	trace->ctf_meta_offset_freq_off = offset;
+
+	rc = meta_clock_pass4_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+
+	rc = meta_stream_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+
+	STAILQ_FOREACH(tp, tp_list, next)
+		if (meta_event_emit(&meta, &offset, tp) < 0)
+			goto fail;
+
+	trace->ctf_meta = meta;
+	return 0;
+
+fail:
+	if (meta)
+		free(meta);
+	return -EBADF;
+}
+
+void
+trace_metadata_destroy(void)
+{
+	struct trace *trace = trace_obj_get();
+
+	if (trace->ctf_meta) {
+		free(trace->ctf_meta);
+		trace->ctf_meta = NULL;
+	}
+}
+
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index 9807613d2..b6aa660bd 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -42,6 +42,11 @@ struct trace {
 	uint64_t epoch_sec;
 	uint64_t epoch_nsec;
 	uint64_t uptime_ticks;
+	char *ctf_meta;
+	uint32_t ctf_meta_offset_freq;
+	uint32_t ctf_meta_offset_freq_off_s;
+	uint32_t ctf_meta_offset_freq_off;
+	uint16_t ctf_fixup_done;
 	rte_spinlock_t lock;
 };
 
@@ -63,6 +68,8 @@ struct trace_point_head *trace_list_head_get(void);
 /* Util functions */
 bool trace_has_duplicate_entry(void);
 void trace_uuid_generate(void);
+int trace_metadata_create(void);
+void trace_metadata_destroy(void);
 int trace_mkdir(void);
 int trace_epoch_time_save(void);
 
diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
index 716a255d2..4ccdf1eee 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -29,6 +29,7 @@ common_sources = files(
 	'eal_common_thread.c',
 	'eal_common_timer.c',
 	'eal_common_trace.c',
+	'eal_common_trace_ctf.c',
 	'eal_common_trace_utils.c',
 	'eal_common_uuid.c',
 	'hotplug_mp.c',
diff --git a/lib/librte_eal/freebsd/eal/Makefile b/lib/librte_eal/freebsd/eal/Makefile
index 8c444da02..546d79514 100644
--- a/lib/librte_eal/freebsd/eal/Makefile
+++ b/lib/librte_eal/freebsd/eal/Makefile
@@ -61,6 +61,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_ctf.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_utils.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c
diff --git a/lib/librte_eal/linux/eal/Makefile b/lib/librte_eal/linux/eal/Makefile
index bd9993e58..1980e9fc5 100644
--- a/lib/librte_eal/linux/eal/Makefile
+++ b/lib/librte_eal/linux/eal/Makefile
@@ -69,6 +69,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_ctf.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_utils.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 08/32] eal/trace: handle CTF keyword collision
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (6 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 07/32] eal/trace: create CTF TDSL metadata in memory jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 09/32] eal/trace: implement trace memory allocation jerinj
                   ` (24 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Sunil Kumar Kori <skori@marvell.com>

Some of the keyword like align, event, "." and "->" etc will be
used in CTF metadata syntax. This patch support for handling
those keywords with DPDK events name.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 lib/librte_eal/common/eal_common_trace_ctf.c | 119 +++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace_ctf.c b/lib/librte_eal/common/eal_common_trace_ctf.c
index 5ad44cc8d..c4f00bf22 100644
--- a/lib/librte_eal/common/eal_common_trace_ctf.c
+++ b/lib/librte_eal/common/eal_common_trace_ctf.c
@@ -215,12 +215,131 @@ meta_stream_emit(char **meta, int *offset)
 	return meta_copy(meta, offset, str, rc);
 }
 
+static void
+string_fixed_replace(char *input, const char *search, const char *replace)
+{
+	char *found;
+	size_t len;
+
+	found = strstr(input, search);
+	if (found == NULL)
+		return;
+
+	if (strlen(found) != strlen(search))
+		return;
+
+	len = strlen(replace);
+	memcpy(found, replace, len);
+	found[len] = '\0';
+}
+
+static void
+ctf_fixup_align(char *str)
+{
+	string_fixed_replace(str, "align", "_align");
+}
+
+static void
+ctf_fixup_arrow_deref(char *str)
+{
+	const char *replace = "_";
+	const char *search = "->";
+	char *found;
+	size_t len;
+
+	found = strstr(str, search);
+	if (found == NULL)
+		return;
+
+	do {
+		memcpy(found, replace, strlen(replace));
+		len = strlen(found + 2);
+		memcpy(found + 1, found + 2, len);
+		found[len + 1] = '\0';
+		found = strstr(str, search);
+	} while (found != NULL);
+}
+
+static void
+ctf_fixup_dot_deref(char *str)
+{
+	const char *replace = "_";
+	const char *search = ".";
+	char *found;
+	size_t len;
+
+	found = strstr(str, search);
+	if (found == NULL)
+		return;
+
+	len = strlen(replace);
+	do {
+		memcpy(found, replace, len);
+		found = strstr(str, search);
+	} while (found != NULL);
+}
+
+static void
+ctf_fixup_event(char *str)
+{
+	string_fixed_replace(str, "event", "_event");
+}
+
+static int
+ctf_fixup_keyword(char *str)
+{
+	char dup_str[TRACE_CTF_FIELD_SIZE];
+	char input[TRACE_CTF_FIELD_SIZE];
+	const char *delim = ";";
+	char *from;
+	int len;
+
+	if (str == NULL)
+		return 0;
+
+	len = strlen(str);
+	if (len >= TRACE_CTF_FIELD_SIZE) {
+		trace_err("ctf_field reached its maximum limit");
+		return -EMSGSIZE;
+	}
+
+	/* Create duplicate string */
+	strcpy(dup_str, str);
+
+	len = 0;
+	from = strtok(dup_str, delim);
+	while (from != NULL) {
+		strcpy(input, from);
+		ctf_fixup_align(input);
+		ctf_fixup_dot_deref(input);
+		ctf_fixup_arrow_deref(input);
+		ctf_fixup_event(input);
+
+		strcpy(&input[strlen(input)], delim);
+		if ((len + strlen(input)) >= TRACE_CTF_FIELD_SIZE) {
+			trace_err("ctf_field reached its maximum limit");
+			return -EMSGSIZE;
+		}
+
+		strcpy(str + len, input);
+		len += strlen(input);
+		from = strtok(NULL, delim);
+	}
+
+	return 0;
+}
+
 static int
 meta_event_emit(char **meta, int *offset, struct trace_point *tp)
 {
 	char *str = NULL;
 	int rc;
 
+	/* Fixup ctf field string in case it using reserved ctf keywords */
+	rc = ctf_fixup_keyword(tp->ctf_field);
+	if (rc)
+		return rc;
+
 	rc = metadata_printf(&str,
 		"event {\n"
 		"    id = %d;\n"
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 09/32] eal/trace: implement trace memory allocation
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (7 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 08/32] eal/trace: handle CTF keyword collision jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 10/32] eal/trace: implement debug dump function jerinj
                   ` (23 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

Trace memory will be allocated per thread to enable lockless trace
events updates to the memory. The allocator will first attempt to
allocate from hugepage, if not available from hugepage then
fallback to malloc memory.

Later in the patches series, This API will be hooked to DPDK fastpath
and control plane thread creation API. It is possible for non
DPDK thread to use trace events, in that case, trace memory
will be allocated on the first event emission.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c      | 97 +++++++++++++++++++
 .../common/eal_common_trace_utils.c           | 20 ++++
 lib/librte_eal/common/eal_trace.h             | 29 ++++++
 lib/librte_eal/common/include/rte_trace.h     | 13 +++
 .../common/include/rte_trace_provider.h       | 19 ++++
 lib/librte_eal/rte_eal_version.map            |  2 +
 6 files changed, 180 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index fe9e363f7..3a158b2ce 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -16,6 +16,7 @@
 #include "eal_trace.h"
 
 RTE_DEFINE_PER_LCORE(volatile int, trace_point_sz);
+RTE_DEFINE_PER_LCORE(void *, trace_mem);
 RTE_DEFINE_PER_LCORE(char, ctf_field[TRACE_CTF_FIELD_SIZE]);
 RTE_DEFINE_PER_LCORE(int, ctf_count);
 
@@ -37,6 +38,9 @@ trace_list_head_get(void)
 int
 eal_trace_init(void)
 {
+	/* Trace memory should start with 8B aligned for natural alignment */
+	RTE_BUILD_BUG_ON((offsetof(struct __rte_trace_header, mem) % 8) != 0);
+
 	/* One of the Trace registration failed */
 	if (trace.register_errno) {
 		rte_errno = trace.register_errno;
@@ -83,6 +87,7 @@ eal_trace_fini(void)
 {
 	if (rte_trace_global_is_disabled())
 		return;
+	trace_mem_per_thread_free();
 	trace_metadata_destroy();
 }
 
@@ -333,6 +338,98 @@ rte_trace_from_name(const char *name)
 	return NULL;
 }
 
+static inline size_t
+list_sz(uint32_t index)
+{
+	return sizeof(struct thread_mem_meta) * (index + 1);
+}
+
+void
+__rte_trace_mem_per_thread_alloc(void)
+{
+	struct trace *trace = trace_obj_get();
+	struct __rte_trace_header *header;
+	uint32_t count;
+
+	if (rte_trace_global_is_disabled())
+		return;
+
+	if (RTE_PER_LCORE(trace_mem))
+		return;
+
+	rte_spinlock_lock(&trace->lock);
+
+	count = trace->nb_trace_mem_list;
+
+	/* Allocate room for storing the thread trace mem meta */
+	trace->lcore_meta = realloc(trace->lcore_meta, list_sz(count));
+
+	/* Provide dummy space for fastpath to consume */
+	if (trace->lcore_meta == NULL) {
+		trace_crit("trace mem meta memory realloc failed");
+		header = NULL; goto fail;
+	}
+
+	/* First attempt from huge page */
+	header = rte_malloc(NULL, trace_mem_sz(trace->buff_len), 8);
+	if (header) {
+		trace->lcore_meta[count].area = TRACE_AREA_HUGEPAGE;
+		goto found;
+	}
+
+	/* Second attempt from heap */
+	header = malloc(trace_mem_sz(trace->buff_len));
+	if (header == NULL) {
+		trace_crit("trace mem malloc attempt failed");
+		header = NULL; goto fail;
+
+	}
+
+	/* Second attempt from heap is success */
+	trace->lcore_meta[count].area = TRACE_AREA_HEAP;
+
+	/* Initialize the trace header */
+found:
+	header->offset = 0;
+	header->len = trace->buff_len;
+	header->stream_header.magic = TRACE_CTF_MAGIC;
+	rte_uuid_copy(header->stream_header.uuid, trace->uuid);
+	header->stream_header.lcore_id = rte_lcore_id();
+
+	/* Store the thread name */
+	char *name = header->stream_header.thread_name;
+	memset(name, 0, __RTE_TRACE_EMIT_STRING_LEN_MAX);
+	rte_thread_getname(pthread_self(), name,
+			   __RTE_TRACE_EMIT_STRING_LEN_MAX);
+
+	trace->lcore_meta[count].mem = header;
+	trace->nb_trace_mem_list++;
+fail:
+	RTE_PER_LCORE(trace_mem) = header;
+	rte_spinlock_unlock(&trace->lock);
+}
+
+void
+trace_mem_per_thread_free(void)
+{
+	struct trace *trace = trace_obj_get();
+	uint32_t count;
+	void *mem;
+
+	if (rte_trace_global_is_disabled())
+		return;
+
+	rte_spinlock_lock(&trace->lock);
+	for (count = 0; count < trace->nb_trace_mem_list; count++) {
+		mem = trace->lcore_meta[count].mem;
+		if (trace->lcore_meta[count].area == TRACE_AREA_HUGEPAGE)
+			rte_free(mem);
+		else if (trace->lcore_meta[count].area == TRACE_AREA_HEAP)
+			free(mem);
+	}
+	rte_spinlock_unlock(&trace->lock);
+}
+
 int
 __rte_trace_point_register(rte_trace_t handle, const char *name, uint32_t level,
 			 void (*fn)(void))
diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
index 340ab62e4..dbeb36668 100644
--- a/lib/librte_eal/common/eal_common_trace_utils.c
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -14,6 +14,26 @@
 #include "eal_filesystem.h"
 #include "eal_trace.h"
 
+const char *
+trace_mode_to_string(enum rte_trace_mode_e mode)
+{
+	switch (mode) {
+	case RTE_TRACE_MODE_OVERWRITE: return "overwrite";
+	case RTE_TRACE_MODE_DISCARD: return "discard";
+	default: return "unknown";
+	}
+}
+
+const char *
+trace_area_to_string(enum trace_area_e area)
+{
+	switch (area) {
+	case TRACE_AREA_HEAP: return "heap";
+	case TRACE_AREA_HUGEPAGE: return "hugepage";
+	default: return "unknown";
+	}
+}
+
 static bool
 trace_entry_compare(const char *name)
 {
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index b6aa660bd..c2d00bbb8 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -6,10 +6,15 @@
 #define __EAL_TRACE_H
 
 #include <rte_cycles.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
 #include <rte_spinlock.h>
 #include <rte_trace.h>
 #include <rte_uuid.h>
 
+#include "eal_private.h"
+#include "eal_thread.h"
+
 #define trace_err(fmt, args...)\
 	RTE_LOG(ERR, EAL, "%s():%u " fmt "\n",\
 		__func__, __LINE__, ## args)
@@ -22,6 +27,8 @@
 #define TRACE_DIR_STR_LEN (sizeof("YYYY-mm-dd-AM-HH-MM-SS") + TRACE_PREFIX_LEN)
 #define TRACE_CTF_FIELD_SIZE 384
 #define TRACE_POINT_NAME_SIZE 64
+#define TRACE_CTF_MAGIC 0xC1FC1FC1
+
 
 struct trace_point {
 	STAILQ_ENTRY(trace_point) next;
@@ -30,6 +37,16 @@ struct trace_point {
 	char ctf_field[TRACE_CTF_FIELD_SIZE];
 };
 
+enum trace_area_e {
+	TRACE_AREA_HEAP,
+	TRACE_AREA_HUGEPAGE,
+};
+
+struct thread_mem_meta {
+	void *mem;
+	enum trace_area_e area;
+};
+
 struct trace {
 	char dir[PATH_MAX];
 	int dir_offset;
@@ -37,8 +54,11 @@ struct trace {
 	bool global_status;
 	enum rte_trace_mode_e mode;
 	rte_uuid_t uuid;
+	uint32_t buff_len;
 	uint32_t level;
 	uint32_t nb_trace_points;
+	uint32_t nb_trace_mem_list;
+	struct thread_mem_meta *lcore_meta;
 	uint64_t epoch_sec;
 	uint64_t epoch_nsec;
 	uint64_t uptime_ticks;
@@ -58,6 +78,12 @@ trace_id_get(rte_trace_t trace)
 		__RTE_TRACE_FIELD_ID_SHIFT;
 }
 
+static inline size_t
+trace_mem_sz(uint32_t len)
+{
+	return len + sizeof(struct __rte_trace_header);
+}
+
 /* Trace object functions */
 struct trace *trace_obj_get(void);
 
@@ -66,12 +92,15 @@ STAILQ_HEAD(trace_point_head, trace_point);
 struct trace_point_head *trace_list_head_get(void);
 
 /* Util functions */
+const char *trace_mode_to_string(enum rte_trace_mode_e mode);
+const char *trace_area_to_string(enum trace_area_e area);
 bool trace_has_duplicate_entry(void);
 void trace_uuid_generate(void);
 int trace_metadata_create(void);
 void trace_metadata_destroy(void);
 int trace_mkdir(void);
 int trace_epoch_time_save(void);
+void trace_mem_per_thread_free(void);
 
 /* EAL interface */
 int eal_trace_init(void);
diff --git a/lib/librte_eal/common/include/rte_trace.h b/lib/librte_eal/common/include/rte_trace.h
index da70dfdbb..358b1b7ca 100644
--- a/lib/librte_eal/common/include/rte_trace.h
+++ b/lib/librte_eal/common/include/rte_trace.h
@@ -518,6 +518,19 @@ _tp _args \
 
 #endif /* __DOXYGEN__ */
 
+/** @internal Macro to define maximum emit length of string datatype. */
+#define __RTE_TRACE_EMIT_STRING_LEN_MAX 32
+
+/**
+ * @internal @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Allocate trace memory buffer per thread.
+ *
+ */
+__rte_experimental
+void __rte_trace_mem_per_thread_alloc(void);
+
 /**
  * @internal @warning
  * @b EXPERIMENTAL: this API may change without prior notice
diff --git a/lib/librte_eal/common/include/rte_trace_provider.h b/lib/librte_eal/common/include/rte_trace_provider.h
index b4da87ba1..2257de85b 100644
--- a/lib/librte_eal/common/include/rte_trace_provider.h
+++ b/lib/librte_eal/common/include/rte_trace_provider.h
@@ -9,6 +9,10 @@
 #ifndef _RTE_TRACE_PROVIDER_H_
 #define _RTE_TRACE_PROVIDER_H_
 
+#include <rte_per_lcore.h>
+#include <rte_string_fns.h>
+#include <rte_uuid.h>
+
 #define __RTE_TRACE_EVENT_HEADER_ID_SHIFT (48)
 
 #define __RTE_TRACE_FIELD_ENABLE_MASK (1ULL << 63)
@@ -20,5 +24,20 @@
 #define __RTE_TRACE_FIELD_LEVEL_SHIFT (32)
 #define __RTE_TRACE_FIELD_LEVEL_MASK (0xffULL << __RTE_TRACE_FIELD_LEVEL_SHIFT)
 
+struct __rte_trace_stream_header {
+	uint32_t magic;
+	rte_uuid_t uuid;
+	uint32_t lcore_id;
+	char thread_name[__RTE_TRACE_EMIT_STRING_LEN_MAX];
+} __rte_packed;
+
+struct __rte_trace_header {
+	uint32_t offset;
+	uint32_t len;
+	struct __rte_trace_stream_header stream_header;
+	uint8_t mem[];
+};
+
+RTE_DECLARE_PER_LCORE(void *, trace_mem);
 
 #endif /* _RTE_TRACE_PROVIDER_H_ */
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 841ebc5f9..8999faeb7 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -338,7 +338,9 @@ EXPERIMENTAL {
 
 	# added in 20.05
 	rte_thread_getname;
+	__rte_trace_mem_per_thread_alloc;
 	__rte_trace_point_register;
+	per_lcore_trace_mem;
 	rte_trace_global_is_enabled;
 	rte_trace_global_is_disabled;
 	rte_trace_is_id_invalid;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 10/32] eal/trace: implement debug dump function
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (8 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 09/32] eal/trace: implement trace memory allocation jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-23 10:56   ` Morten Brørup
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 11/32] eal/trace: implement trace save jerinj
                   ` (22 subsequent siblings)
  32 siblings, 1 reply; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

Implement rte_trace_metadata_dump() and rte_trace_dump()
functions. Former one used to dump the CTF metadata file and
the latter one to dump all the registered events and its status.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 lib/librte_eal/common/eal_common_log.c       |  9 +--
 lib/librte_eal/common/eal_common_trace.c     | 63 ++++++++++++++++++
 lib/librte_eal/common/eal_common_trace_ctf.c | 67 ++++++++++++++++++++
 lib/librte_eal/common/eal_private.h          |  3 +
 lib/librte_eal/rte_eal_version.map           |  2 +
 5 files changed, 140 insertions(+), 4 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
index c0efd5214..d8f7feb32 100644
--- a/lib/librte_eal/common/eal_common_log.c
+++ b/lib/librte_eal/common/eal_common_log.c
@@ -372,8 +372,8 @@ RTE_INIT_PRIO(rte_log_init, LOG)
 	rte_logs.dynamic_types_len = RTE_LOGTYPE_FIRST_EXT_ID;
 }
 
-static const char *
-loglevel_to_string(uint32_t level)
+const char *
+eal_loglevel_to_string(uint32_t level)
 {
 	switch (level) {
 	case 0: return "disabled";
@@ -396,14 +396,15 @@ rte_log_dump(FILE *f)
 	size_t i;
 
 	fprintf(f, "global log level is %s\n",
-		loglevel_to_string(rte_log_get_global_level()));
+		eal_loglevel_to_string(rte_log_get_global_level()));
 
 	for (i = 0; i < rte_logs.dynamic_types_len; i++) {
 		if (rte_logs.dynamic_types[i].name == NULL)
 			continue;
 		fprintf(f, "id %zu: %s, level is %s\n",
 			i, rte_logs.dynamic_types[i].name,
-			loglevel_to_string(rte_logs.dynamic_types[i].loglevel));
+			eal_loglevel_to_string(
+					rte_logs.dynamic_types[i].loglevel));
 	}
 }
 
diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index 3a158b2ce..6cb724080 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -338,6 +338,69 @@ rte_trace_from_name(const char *name)
 	return NULL;
 }
 
+static void
+trace_point_dump(FILE *f, struct trace_point *tp)
+{
+	rte_trace_t handle = tp->handle;
+	uint32_t level;
+
+	level = rte_trace_level_get(handle);
+	fprintf(f, "\tid %d, %s, size is %d, level is %s, mode is %s, %s\n",
+		trace_id_get(handle), tp->name,
+		(uint16_t)(*handle & __RTE_TRACE_FIELD_SIZE_MASK),
+		eal_loglevel_to_string(level),
+		trace_mode_to_string(rte_trace_mode_get(handle)),
+		rte_trace_is_enabled(handle) ? "enabled" : "disabled");
+}
+
+static void
+trace_lcore_mem_dump(FILE *f)
+{
+	struct trace *trace = trace_obj_get();
+	struct __rte_trace_header *header;
+	uint32_t count;
+
+	if (trace->nb_trace_mem_list == 0)
+		return;
+
+	rte_spinlock_lock(&trace->lock);
+	fprintf(f, "nb_trace_mem_list = %d\n", trace->nb_trace_mem_list);
+	fprintf(f, "\nTrace mem info\n--------------\n");
+	for (count = 0; count < trace->nb_trace_mem_list; count++) {
+		header = trace->lcore_meta[count].mem;
+		fprintf(f, "\tid %d, mem=%p, area=%s, lcore_id=%d, name=%s\n",
+		count, header,
+		trace_area_to_string(trace->lcore_meta[count].area),
+		header->stream_header.lcore_id,
+		header->stream_header.thread_name);
+	}
+	rte_spinlock_unlock(&trace->lock);
+}
+
+void
+rte_trace_dump(FILE *f)
+{
+	struct trace_point_head *tp_list = trace_list_head_get();
+	struct trace *trace = trace_obj_get();
+	struct trace_point *tp;
+
+	fprintf(f, "\nGlobal info\n-----------\n");
+	fprintf(f, "status = %s\n",
+		rte_trace_global_is_enabled() ? "enabled" : "disabled");
+	fprintf(f, "log level = %s\n",
+		eal_loglevel_to_string(rte_trace_global_level_get()));
+	fprintf(f, "mode = %s\n",
+		trace_mode_to_string(rte_trace_global_mode_get()));
+	fprintf(f, "dir = %s\n", trace->dir);
+	fprintf(f, "buffer len = %d\n", trace->buff_len);
+	fprintf(f, "number of trace points = %d\n", trace->nb_trace_points);
+
+	trace_lcore_mem_dump(f);
+	fprintf(f, "\nTrace point info\n----------------\n");
+	STAILQ_FOREACH(tp, tp_list, next)
+		trace_point_dump(f, tp);
+}
+
 static inline size_t
 list_sz(uint32_t index)
 {
diff --git a/lib/librte_eal/common/eal_common_trace_ctf.c b/lib/librte_eal/common/eal_common_trace_ctf.c
index c4f00bf22..0dde8fe14 100644
--- a/lib/librte_eal/common/eal_common_trace_ctf.c
+++ b/lib/librte_eal/common/eal_common_trace_ctf.c
@@ -419,3 +419,70 @@ trace_metadata_destroy(void)
 	}
 }
 
+static void
+meta_fix_freq(struct trace *trace, char *meta)
+{
+	char *str;
+	int rc;
+
+	str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq);
+	rc = sprintf(str, "%20"PRIu64"", rte_get_timer_hz());
+	str[rc] = ';';
+}
+
+static void
+meta_fix_freq_offset(struct trace *trace, char *meta)
+{
+	uint64_t uptime_tickes_floor, uptime_ticks, freq, uptime_sec;
+	uint64_t offset, offset_s;
+	char *str;
+	int rc;
+
+	uptime_ticks = trace->uptime_ticks &
+			((1ULL << __RTE_TRACE_EVENT_HEADER_ID_SHIFT) - 1);
+	freq = rte_get_tsc_hz();
+	uptime_tickes_floor = RTE_ALIGN_MUL_FLOOR(uptime_ticks, freq);
+
+	uptime_sec = uptime_tickes_floor / freq;
+	offset_s = trace->epoch_sec - uptime_sec;
+
+	offset = uptime_ticks - uptime_tickes_floor;
+	offset += trace->epoch_nsec * (freq / NSEC_PER_SEC);
+
+	str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq_off_s);
+	rc = sprintf(str, "%20"PRIu64"", offset_s);
+	str[rc] = ';';
+	str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq_off);
+	rc = sprintf(str, "%20"PRIu64"", offset);
+	str[rc] = ';';
+}
+
+static void
+meta_fixup(struct trace *trace, char *meta)
+{
+	meta_fix_freq(trace, meta);
+	meta_fix_freq_offset(trace, meta);
+}
+
+int
+rte_trace_metadata_dump(FILE *f)
+{
+	struct trace *trace = trace_obj_get();
+	char *ctf_meta = trace->ctf_meta;
+	int rc;
+
+	if (rte_trace_global_is_disabled())
+		return 0;
+
+	if (ctf_meta == NULL)
+		return -EINVAL;
+
+	if (!__atomic_load_n(&trace->ctf_fixup_done, __ATOMIC_SEQ_CST) &&
+				rte_get_timer_hz()) {
+		meta_fixup(trace, ctf_meta);
+		__atomic_store_n(&trace->ctf_fixup_done, 1, __ATOMIC_SEQ_CST);
+	}
+
+	rc = fprintf(f, "%s", ctf_meta);
+	return rc < 0 ? rc : 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index ddcfbe2e4..81694616b 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -443,4 +443,7 @@ rte_option_usage(void);
 uint64_t
 eal_get_baseaddr(void);
 
+const char *
+eal_loglevel_to_string(uint32_t level);
+
 #endif /* _EAL_PRIVATE_H_ */
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 8999faeb7..cae358608 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -359,4 +359,6 @@ EXPERIMENTAL {
 	rte_trace_pattern;
 	rte_trace_regexp;
 	rte_trace_from_name;
+	rte_trace_metadata_dump;
+	rte_trace_dump;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 11/32] eal/trace: implement trace save
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (9 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 10/32] eal/trace: implement debug dump function jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-19 19:07   ` Mattias Rönnblom
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 12/32] eal/trace: implement registration payload jerinj
                   ` (21 subsequent siblings)
  32 siblings, 1 reply; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

Implement rte_trace_save(), which will save the metadata
file and trace memory snapshot to the trace directory.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 .../common/eal_common_trace_utils.c           | 75 +++++++++++++++++++
 lib/librte_eal/rte_eal_version.map            |  1 +
 2 files changed, 76 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
index dbeb36668..230e4ac95 100644
--- a/lib/librte_eal/common/eal_common_trace_utils.c
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -213,3 +213,78 @@ trace_mkdir(void)
 	return 0;
 }
 
+static int
+trace_meta_save(struct trace *trace)
+{
+	char file_name[PATH_MAX];
+	FILE *f;
+	int rc;
+
+	rc = snprintf(file_name, PATH_MAX, "%s/metadata", trace->dir);
+	if (rc < 0)
+		return rc;
+
+	f = fopen(file_name, "w");
+	if (f == NULL)
+		return -errno;
+
+	rc = rte_trace_metadata_dump(f);
+
+	fclose(f);
+	return rc;
+}
+
+
+static inline int
+trace_file_sz(struct __rte_trace_header *hdr)
+{
+	return sizeof(struct __rte_trace_stream_header) + hdr->offset;
+}
+
+static int
+trace_mem_save(struct trace *trace, struct __rte_trace_header *hdr,
+	       uint32_t cnt)
+{
+	char file_name[PATH_MAX];
+	FILE *f;
+	int rc;
+
+	rc = snprintf(file_name, PATH_MAX, "%s/channel0_%d", trace->dir, cnt);
+	if (rc < 0)
+		return rc;
+
+	f = fopen(file_name, "w");
+	if (f == NULL)
+		return -errno;
+
+	rc = fwrite(&hdr->stream_header, trace_file_sz(hdr), 1, f);
+	fclose(f);
+
+	return rc == 1 ?  0 : -EACCES;
+}
+
+int
+rte_trace_save(void)
+{
+	struct trace *trace = trace_obj_get();
+	struct __rte_trace_header *header;
+	uint32_t count;
+	int rc = 0;
+
+	if (trace->nb_trace_mem_list == 0)
+		return rc;
+
+	rc = trace_meta_save(trace);
+	if (rc)
+		return rc;
+
+	rte_spinlock_lock(&trace->lock);
+	for (count = 0; count < trace->nb_trace_mem_list; count++) {
+		header = trace->lcore_meta[count].mem;
+		rc =  trace_mem_save(trace, header, count);
+		if (rc)
+			break;
+	}
+	rte_spinlock_unlock(&trace->lock);
+	return rc;
+}
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index cae358608..f56d1867e 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -358,6 +358,7 @@ EXPERIMENTAL {
 	rte_trace_mode_get;
 	rte_trace_pattern;
 	rte_trace_regexp;
+	rte_trace_save;
 	rte_trace_from_name;
 	rte_trace_metadata_dump;
 	rte_trace_dump;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 12/32] eal/trace: implement registration payload
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (10 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 11/32] eal/trace: implement trace save jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-19 19:15   ` Mattias Rönnblom
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 13/32] eal/trace: implement provider payload jerinj
                   ` (20 subsequent siblings)
  32 siblings, 1 reply; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

The trace function payloads such as rte_trace_ctf_* have
dual functions. The first to emit the payload for the registration
function and the second one to act as trace memory emitters.

When it used as registration payload, it will do the following to
fulfill the registration job.
- Find out the size of the event
- Generate metadata field string using __rte_trace_emit_ctf_field().

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c      | 19 +++++++
 lib/librte_eal/common/include/rte_trace.h     | 20 ++++++++
 .../common/include/rte_trace_register.h       | 50 +++++++++++++++++++
 lib/librte_eal/rte_eal_version.map            |  2 +
 4 files changed, 91 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index 6cb724080..94d3da0d3 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -493,6 +493,25 @@ trace_mem_per_thread_free(void)
 	rte_spinlock_unlock(&trace->lock);
 }
 
+void
+__rte_trace_emit_ctf_field(size_t sz, const char *in, const char *datatype)
+{
+	char *field = RTE_PER_LCORE(ctf_field);
+	int count = RTE_PER_LCORE(ctf_count);
+	int rc;
+
+	RTE_PER_LCORE(trace_point_sz) += sz;
+	rc = snprintf(RTE_PTR_ADD(field, count),
+		      RTE_MAX(0, TRACE_CTF_FIELD_SIZE - 1 - count),
+		      "%s %s;", datatype, in);
+	if (rc <= 0) {
+		RTE_PER_LCORE(trace_point_sz) = 0;
+		trace_crit("CTF field is too long");
+		return;
+	}
+	RTE_PER_LCORE(ctf_count) += rc;
+}
+
 int
 __rte_trace_point_register(rte_trace_t handle, const char *name, uint32_t level,
 			 void (*fn)(void))
diff --git a/lib/librte_eal/common/include/rte_trace.h b/lib/librte_eal/common/include/rte_trace.h
index 358b1b7ca..c24fe8d66 100644
--- a/lib/librte_eal/common/include/rte_trace.h
+++ b/lib/librte_eal/common/include/rte_trace.h
@@ -520,6 +520,8 @@ _tp _args \
 
 /** @internal Macro to define maximum emit length of string datatype. */
 #define __RTE_TRACE_EMIT_STRING_LEN_MAX 32
+/** @internal Macro to define event header size. */
+#define __RTE_TRACE_EVENT_HEADER_SZ sizeof(uint64_t)
 
 /**
  * @internal @warning
@@ -553,6 +555,24 @@ void __rte_trace_mem_per_thread_alloc(void);
 __rte_experimental
 int __rte_trace_point_register(rte_trace_t trace, const char *name,
 			     uint32_t level, void (*fn)(void));
+/**
+ * @internal @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Helper function to emit ctf field.
+ *
+ * @param sz
+ *   The tracepoint size.
+ * @param field
+ *   The name of the trace event.
+ * @param type
+ *   The datatype of the trace event as string.
+ * @return
+ *   - 0: Success.
+ *   - <0: Failure.
+ */
+__rte_experimental
+void __rte_trace_emit_ctf_field(size_t sz, const char *field, const char *type);
 
 #ifdef RTE_TRACE_POINT_REGISTER_SELECT
 #include <rte_trace_register.h>
diff --git a/lib/librte_eal/common/include/rte_trace_register.h b/lib/librte_eal/common/include/rte_trace_register.h
index e9940b414..93d6396df 100644
--- a/lib/librte_eal/common/include/rte_trace_register.h
+++ b/lib/librte_eal/common/include/rte_trace_register.h
@@ -10,6 +10,7 @@
 #define _RTE_TRACE_REGISTER_H_
 
 #include <rte_per_lcore.h>
+#include <rte_log.h>
 
 RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz);
 
@@ -17,4 +18,53 @@ RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz);
 	__rte_trace_point_register(&__##trace, RTE_STR(name),\
 			RTE_LOG_ ## level, (void (*)(void)) trace)
 
+#define __rte_trace_emit_header_generic(t)\
+	RTE_PER_LCORE(trace_point_sz) = __RTE_TRACE_EVENT_HEADER_SZ
+
+#define __rte_trace_emit_header_dp(t) __rte_trace_emit_header_generic(t)
+
+#define rte_trace_ctf_u64(in)\
+	RTE_BUILD_BUG_ON(sizeof(uint64_t) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(uint64_t), RTE_STR(in), "uint64_t")
+#define rte_trace_ctf_i64(in)\
+	RTE_BUILD_BUG_ON(sizeof(int64_t) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(int64_t), RTE_STR(in), "int64_t")
+#define rte_trace_ctf_u32(in)\
+	RTE_BUILD_BUG_ON(sizeof(uint32_t) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(uint32_t), RTE_STR(in), "uint32_t")
+#define rte_trace_ctf_i32(in)\
+	RTE_BUILD_BUG_ON(sizeof(int32_t) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(int32_t), RTE_STR(in), "int32_t")
+#define rte_trace_ctf_u16(in)\
+	RTE_BUILD_BUG_ON(sizeof(uint16_t) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(uint16_t), RTE_STR(in), "uint16_t")
+#define rte_trace_ctf_i16(in)\
+	RTE_BUILD_BUG_ON(sizeof(int16_t) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(int16_t), RTE_STR(in), "int16_t")
+#define rte_trace_ctf_u8(in)\
+	RTE_BUILD_BUG_ON(sizeof(uint8_t) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(uint8_t), RTE_STR(in), "uint8_t")
+#define rte_trace_ctf_i8(in)\
+	RTE_BUILD_BUG_ON(sizeof(int8_t) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(int8_t), RTE_STR(in), "int8_t")
+#define rte_trace_ctf_int(in)\
+	RTE_BUILD_BUG_ON(sizeof(int) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(int), RTE_STR(in), "int32_t")
+#define rte_trace_ctf_long(in)\
+	RTE_BUILD_BUG_ON(sizeof(long) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(long), RTE_STR(in), "long")
+#define rte_trace_ctf_float(in)\
+	RTE_BUILD_BUG_ON(sizeof(float) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(float), RTE_STR(in), "float")
+#define rte_trace_ctf_double(in)\
+	RTE_BUILD_BUG_ON(sizeof(double) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(double), RTE_STR(in), "double")
+#define rte_trace_ctf_ptr(in)\
+	RTE_BUILD_BUG_ON(sizeof(void *) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(void *), RTE_STR(in), "uintptr_t")
+#define rte_trace_ctf_string(in)\
+	RTE_SET_USED(in);\
+	__rte_trace_emit_ctf_field(__RTE_TRACE_EMIT_STRING_LEN_MAX,\
+				   RTE_STR(in)"[32]", "string_bounded_t")
+
 #endif /* _RTE_TRACE_REGISTER_H_ */
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index f56d1867e..0c787302f 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -339,7 +339,9 @@ EXPERIMENTAL {
 	# added in 20.05
 	rte_thread_getname;
 	__rte_trace_mem_per_thread_alloc;
+	__rte_trace_emit_ctf_field;
 	__rte_trace_point_register;
+	per_lcore_trace_point_sz;
 	per_lcore_trace_mem;
 	rte_trace_global_is_enabled;
 	rte_trace_global_is_disabled;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 13/32] eal/trace: implement provider payload
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (11 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 12/32] eal/trace: implement registration payload jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-19 19:27   ` Mattias Rönnblom
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 14/32] eal/trace: hook internal trace APIs to Linux jerinj
                   ` (19 subsequent siblings)
  32 siblings, 1 reply; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

The trace function payloads such as rte_trace_ctf_* have
dual functions. The first to emit the payload for the registration
function and the second one to act as trace mem emitters aka
provider payload.

When it used as provider payload, those function copy the trace
field to trace memory based on the tracing mode.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 .../common/include/rte_trace_provider.h       | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_trace_provider.h b/lib/librte_eal/common/include/rte_trace_provider.h
index 2257de85b..66e9d2456 100644
--- a/lib/librte_eal/common/include/rte_trace_provider.h
+++ b/lib/librte_eal/common/include/rte_trace_provider.h
@@ -9,6 +9,9 @@
 #ifndef _RTE_TRACE_PROVIDER_H_
 #define _RTE_TRACE_PROVIDER_H_
 
+#include <rte_branch_prediction.h>
+#include <rte_cycles.h>
+#include <rte_log.h>
 #include <rte_per_lcore.h>
 #include <rte_string_fns.h>
 #include <rte_uuid.h>
@@ -40,4 +43,88 @@ struct __rte_trace_header {
 
 RTE_DECLARE_PER_LCORE(void *, trace_mem);
 
+static __rte_always_inline void*
+__rte_trace_mem_get(uint64_t in)
+{
+	struct __rte_trace_header *trace = RTE_PER_LCORE(trace_mem);
+	const uint16_t sz = in & __RTE_TRACE_FIELD_SIZE_MASK;
+
+	/* Trace memory is not initialized for this thread */
+	if (unlikely(trace == NULL)) {
+		__rte_trace_mem_per_thread_alloc();
+		trace = RTE_PER_LCORE(trace_mem);
+		if (unlikely(trace == NULL))
+			return NULL;
+	}
+	/* Check the wrap around case */
+	uint32_t offset = trace->offset;
+	if (unlikely((offset + sz) >= trace->len)) {
+		/* Disable the trace event if it in DISCARD mode */
+		if (unlikely(in & __RTE_TRACE_FIELD_ENABLE_DISCARD))
+			return NULL;
+
+		offset = 0;
+	}
+	/* Align to event header size */
+	offset = RTE_ALIGN_CEIL(offset, __RTE_TRACE_EVENT_HEADER_SZ);
+	void *mem = RTE_PTR_ADD(&trace->mem[0], offset);
+	offset += sz;
+	trace->offset = offset;
+
+	return mem;
+}
+
+static __rte_always_inline void*
+__rte_trace_emit_ev_header(void *mem, uint64_t in)
+{
+	uint64_t val;
+
+	/* Event header [63:0] = id [63:48] | timestamp [47:0] */
+	val = rte_get_tsc_cycles() &
+		~(0xffffULL << __RTE_TRACE_EVENT_HEADER_ID_SHIFT);
+	val |= ((in & __RTE_TRACE_FIELD_ID_MASK) <<
+	      (__RTE_TRACE_EVENT_HEADER_ID_SHIFT - __RTE_TRACE_FIELD_ID_SHIFT));
+
+	*(uint64_t *)mem = val;
+	return RTE_PTR_ADD(mem, __RTE_TRACE_EVENT_HEADER_SZ);
+}
+
+#define __rte_trace_emit_header_generic(t)\
+	const uint64_t val = __atomic_load_n(t, __ATOMIC_ACQUIRE);\
+	if (likely(!(val & __RTE_TRACE_FIELD_ENABLE_MASK)))\
+		return;\
+	void *mem = __rte_trace_mem_get(val);\
+	if (unlikely(mem == NULL)) \
+		return;\
+	mem = __rte_trace_emit_ev_header(mem, val)
+
+#define __rte_trace_emit_header_dp(t)\
+	if (!rte_trace_is_dp_enabled())\
+		return;\
+	__rte_trace_emit_header_generic(t);
+
+#define __rte_trace_emit_datatype(in)\
+	memcpy(mem, &(in), sizeof(in));\
+	mem = RTE_PTR_ADD(mem, sizeof(in))
+
+#define rte_trace_ctf_u64(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_i64(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_u32(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_i32(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_u16(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_i16(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_u8(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_i8(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_int(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_long(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_float(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_ptr(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_double(in) __rte_trace_emit_datatype(in)
+
+#define rte_trace_ctf_string(in)\
+	if (unlikely(in == NULL))\
+		return;\
+	rte_strscpy(mem, in, __RTE_TRACE_EMIT_STRING_LEN_MAX);\
+	mem = RTE_PTR_ADD(mem, __RTE_TRACE_EMIT_STRING_LEN_MAX)
+
 #endif /* _RTE_TRACE_PROVIDER_H_ */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 14/32] eal/trace: hook internal trace APIs to Linux
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (12 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 13/32] eal/trace: implement provider payload jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 15/32] eal/trace: hook internal trace APIs to FreeBSD jerinj
                   ` (18 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Connect the internal trace interface API to Linux EAL.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/eal_common_thread.c | 3 ++-
 lib/librte_eal/linux/eal/eal.c            | 9 +++++++++
 lib/librte_eal/linux/eal/eal_thread.c     | 3 +++
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c
index 78581753c..e1e61669e 100644
--- a/lib/librte_eal/common/eal_common_thread.c
+++ b/lib/librte_eal/common/eal_common_thread.c
@@ -15,6 +15,7 @@
 #include <rte_lcore.h>
 #include <rte_memory.h>
 #include <rte_log.h>
+#include <rte_trace.h>
 
 #include "eal_internal_cfg.h"
 #include "eal_private.h"
@@ -161,7 +162,7 @@ static void *rte_thread_init(void *arg)
 		pthread_barrier_destroy(&params->configured);
 		free(params);
 	}
-
+	__rte_trace_mem_per_thread_alloc();
 	return start_routine(routine_arg);
 }
 
diff --git a/lib/librte_eal/linux/eal/eal.c b/lib/librte_eal/linux/eal/eal.c
index 9530ee55f..ee777b0cd 100644
--- a/lib/librte_eal/linux/eal/eal.c
+++ b/lib/librte_eal/linux/eal/eal.c
@@ -58,6 +58,7 @@
 #include "eal_filesystem.h"
 #include "eal_hugepages.h"
 #include "eal_memcfg.h"
+#include "eal_trace.h"
 #include "eal_options.h"
 #include "eal_vfio.h"
 #include "hotplug_mp.h"
@@ -1012,6 +1013,12 @@ rte_eal_init(int argc, char **argv)
 		return -1;
 	}
 
+	if (eal_trace_init() < 0) {
+		rte_eal_init_alert("Cannot init trace");
+		rte_errno = EFAULT;
+		return -1;
+	}
+
 	if (eal_option_device_parse()) {
 		rte_errno = ENODEV;
 		rte_atomic32_clear(&run_once);
@@ -1327,6 +1334,8 @@ rte_eal_cleanup(void)
 		rte_memseg_walk(mark_freeable, NULL);
 	rte_service_finalize();
 	rte_mp_channel_cleanup();
+	rte_trace_save();
+	eal_trace_fini();
 	eal_cleanup_config(&internal_config);
 	return 0;
 }
diff --git a/lib/librte_eal/linux/eal/eal_thread.c b/lib/librte_eal/linux/eal/eal_thread.c
index 3f82b286c..45f4dce44 100644
--- a/lib/librte_eal/linux/eal/eal_thread.c
+++ b/lib/librte_eal/linux/eal/eal_thread.c
@@ -20,6 +20,7 @@
 #include <rte_per_lcore.h>
 #include <rte_eal.h>
 #include <rte_lcore.h>
+#include <rte_trace.h>
 
 #include "eal_private.h"
 #include "eal_thread.h"
@@ -124,6 +125,8 @@ eal_thread_loop(__attribute__((unused)) void *arg)
 	RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%zx;cpuset=[%s%s])\n",
 		lcore_id, (uintptr_t)thread_id, cpuset, ret == 0 ? "" : "...");
 
+	__rte_trace_mem_per_thread_alloc();
+
 	/* read on our pipe to get commands */
 	while (1) {
 		void *fct_arg;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 15/32] eal/trace: hook internal trace APIs to FreeBSD
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (13 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 14/32] eal/trace: hook internal trace APIs to Linux jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 16/32] eal/trace: add generic tracepoints jerinj
                   ` (17 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom, skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Connect the internal trace interface API to FreeBSD EAL.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/freebsd/eal/eal.c        | 10 ++++++++++
 lib/librte_eal/freebsd/eal/eal_thread.c |  3 +++
 2 files changed, 13 insertions(+)

diff --git a/lib/librte_eal/freebsd/eal/eal.c b/lib/librte_eal/freebsd/eal/eal.c
index 6ae37e7e6..c453e11f2 100644
--- a/lib/librte_eal/freebsd/eal/eal.c
+++ b/lib/librte_eal/freebsd/eal/eal.c
@@ -52,6 +52,7 @@
 #include "eal_hugepages.h"
 #include "eal_options.h"
 #include "eal_memcfg.h"
+#include "eal_trace.h"
 
 #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
 
@@ -751,6 +752,13 @@ rte_eal_init(int argc, char **argv)
 		return -1;
 	}
 
+	if (eal_trace_init() < 0) {
+		rte_eal_init_alert("Cannot init trace");
+		rte_errno = EFAULT;
+		rte_atomic32_clear(&run_once);
+		return -1;
+	}
+
 	if (eal_option_device_parse()) {
 		rte_errno = ENODEV;
 		rte_atomic32_clear(&run_once);
@@ -966,6 +974,8 @@ rte_eal_cleanup(void)
 {
 	rte_service_finalize();
 	rte_mp_channel_cleanup();
+	rte_trace_save();
+	eal_trace_fini();
 	eal_cleanup_config(&internal_config);
 	return 0;
 }
diff --git a/lib/librte_eal/freebsd/eal/eal_thread.c b/lib/librte_eal/freebsd/eal/eal_thread.c
index ae7b57672..aaccb4926 100644
--- a/lib/librte_eal/freebsd/eal/eal_thread.c
+++ b/lib/librte_eal/freebsd/eal/eal_thread.c
@@ -20,6 +20,7 @@
 #include <rte_per_lcore.h>
 #include <rte_eal.h>
 #include <rte_lcore.h>
+#include <rte_trace.h>
 
 #include "eal_private.h"
 #include "eal_thread.h"
@@ -124,6 +125,8 @@ eal_thread_loop(__attribute__((unused)) void *arg)
 	RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%p;cpuset=[%s%s])\n",
 		lcore_id, thread_id, cpuset, ret == 0 ? "" : "...");
 
+	__rte_trace_mem_per_thread_alloc();
+
 	/* read on our pipe to get commands */
 	while (1) {
 		void *fct_arg;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 16/32] eal/trace: add generic tracepoints
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (14 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 15/32] eal/trace: hook internal trace APIs to FreeBSD jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 17/32] eal/trace: add alarm tracepoints jerinj
                   ` (16 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori, Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

This patch creates the following generic tracepoint for
generic tracing when there is no dedicated tracepoint is
available.

rte_trace_lib_eal_generic_void()
rte_trace_lib_eal_generic_u64()
rte_trace_lib_eal_generic_u32()
rte_trace_lib_eal_generic_u16()
rte_trace_lib_eal_generic_u8()
rte_trace_lib_eal_generic_i64()
rte_trace_lib_eal_generic_i32()
rte_trace_lib_eal_generic_i16()
rte_trace_lib_eal_generic_i8()
rte_trace_lib_eal_generic_int()
rte_trace_lib_eal_generic_long()
rte_trace_lib_eal_generic_float()
rte_trace_lib_eal_generic_double()
rte_trace_lib_eal_generic_ptr()
rte_trace_lib_eal_generic_str()

For example, if an application wishes to emit an int datatype,
it can call rte_trace_lib_eal_generic_int(val) to emit the trace.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 lib/librte_eal/common/Makefile                |   2 +-
 .../common/eal_common_trace_points.c          |  60 +++++++++
 lib/librte_eal/common/include/rte_trace_eal.h | 122 ++++++++++++++++++
 lib/librte_eal/common/meson.build             |   2 +
 lib/librte_eal/freebsd/eal/Makefile           |   1 +
 lib/librte_eal/linux/eal/Makefile             |   1 +
 lib/librte_eal/rte_eal_version.map            |  17 +++
 7 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/common/eal_common_trace_points.c
 create mode 100644 lib/librte_eal/common/include/rte_trace_eal.h

diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 8f2f25c1d..452e5e93d 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -9,7 +9,7 @@ INC += rte_debug.h rte_eal.h rte_eal_interrupts.h
 INC += rte_errno.h rte_launch.h rte_lcore.h
 INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
-INC += rte_trace.h rte_trace_provider.h rte_trace_register.h
+INC += rte_trace.h rte_trace_eal.h rte_trace_provider.h rte_trace_register.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h
diff --git a/lib/librte_eal/common/eal_common_trace_points.c b/lib/librte_eal/common/eal_common_trace_points.c
new file mode 100644
index 000000000..ff521c981
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_trace_points.c
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#define RTE_TRACE_POINT_REGISTER_SELECT /* Select trace point register macros */
+
+#include <rte_trace_eal.h>
+
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_void);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_u64);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_u32);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_u16);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_u8);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_i64);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_i32);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_i16);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_i8);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_int);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_long);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_float);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_double);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_ptr);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_str);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_func);
+
+RTE_INIT(eal_trace_init)
+{
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_void,
+				 lib.eal.generic.void, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_u64,
+				 lib.eal.generic.u64, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_u32,
+				 lib.eal.generic.u32, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_u16,
+				 lib.eal.generic.u16, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_u8,
+				 lib.eal.generic.u8, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_i64,
+				 lib.eal.generic.i64, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_i32,
+				 lib.eal.generic.i32, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_i16,
+				 lib.eal.generic.i16, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_i8,
+				 lib.eal.generic.i8, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_int,
+				 lib.eal.generic.int, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_long,
+				 lib.eal.generic.long, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_float,
+				 lib.eal.generic.float, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_double,
+				 lib.eal.generic.double, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_ptr,
+				 lib.eal.generic.ptr, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_str,
+				 lib.eal.generic.string, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_func,
+				 lib.eal.generic.func, INFO);
+}
diff --git a/lib/librte_eal/common/include/rte_trace_eal.h b/lib/librte_eal/common/include/rte_trace_eal.h
new file mode 100644
index 000000000..269ef7502
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_trace_eal.h
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_EAL_H_
+#define _RTE_TRACE_EAL_H_
+
+/**
+ * @file
+ *
+ * API for EAL trace support
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_trace.h>
+
+/* Generic */
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_void,
+	RTE_TRACE_POINT_ARGS(void),
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_u64,
+	RTE_TRACE_POINT_ARGS(uint64_t in),
+	rte_trace_ctf_u64(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_u32,
+	RTE_TRACE_POINT_ARGS(uint32_t in),
+	rte_trace_ctf_u32(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_u16,
+	RTE_TRACE_POINT_ARGS(uint16_t in),
+	rte_trace_ctf_u16(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_u8,
+	RTE_TRACE_POINT_ARGS(uint8_t in),
+	rte_trace_ctf_u8(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_i64,
+	RTE_TRACE_POINT_ARGS(int64_t in),
+	rte_trace_ctf_i64(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_i32,
+	RTE_TRACE_POINT_ARGS(int32_t in),
+	rte_trace_ctf_i32(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_i16,
+	RTE_TRACE_POINT_ARGS(int16_t in),
+	rte_trace_ctf_i16(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_i8,
+	RTE_TRACE_POINT_ARGS(int8_t in),
+	rte_trace_ctf_i8(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_int,
+	RTE_TRACE_POINT_ARGS(int in),
+	rte_trace_ctf_int(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_long,
+	RTE_TRACE_POINT_ARGS(long in),
+	rte_trace_ctf_long(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_float,
+	RTE_TRACE_POINT_ARGS(float in),
+	rte_trace_ctf_float(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_double,
+	RTE_TRACE_POINT_ARGS(double in),
+	rte_trace_ctf_double(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_ptr,
+	RTE_TRACE_POINT_ARGS(const void *ptr),
+	rte_trace_ctf_ptr(ptr);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_str,
+	RTE_TRACE_POINT_ARGS(const char *str),
+	rte_trace_ctf_string(str);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_func,
+	RTE_TRACE_POINT_ARGS(const char *func),
+	rte_trace_ctf_string(func);
+)
+
+#define RTE_TRACE_LIB_EAL_GENERIC_FUNC rte_trace_lib_eal_generic_func(__func__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TRACE_EAL_H_ */
diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
index 4ccdf1eee..7f11377b3 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -30,6 +30,7 @@ common_sources = files(
 	'eal_common_timer.c',
 	'eal_common_trace.c',
 	'eal_common_trace_ctf.c',
+	'eal_common_trace_points.c',
 	'eal_common_trace_utils.c',
 	'eal_common_uuid.c',
 	'hotplug_mp.c',
@@ -88,6 +89,7 @@ common_headers = files(
 	'include/rte_string_fns.h',
 	'include/rte_tailq.h',
 	'include/rte_trace.h',
+	'include/rte_trace_eal.h',
 	'include/rte_trace_provider.h',
 	'include/rte_trace_register.h',
 	'include/rte_time.h',
diff --git a/lib/librte_eal/freebsd/eal/Makefile b/lib/librte_eal/freebsd/eal/Makefile
index 546d79514..07232ba97 100644
--- a/lib/librte_eal/freebsd/eal/Makefile
+++ b/lib/librte_eal/freebsd/eal/Makefile
@@ -62,6 +62,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_ctf.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_points.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_utils.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c
diff --git a/lib/librte_eal/linux/eal/Makefile b/lib/librte_eal/linux/eal/Makefile
index 1980e9fc5..6158eb0b8 100644
--- a/lib/librte_eal/linux/eal/Makefile
+++ b/lib/librte_eal/linux/eal/Makefile
@@ -70,6 +70,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_ctf.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_points.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_utils.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 0c787302f..5c2ff73db 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -364,4 +364,21 @@ EXPERIMENTAL {
 	rte_trace_from_name;
 	rte_trace_metadata_dump;
 	rte_trace_dump;
+
+	__rte_trace_lib_eal_generic_void;
+	__rte_trace_lib_eal_generic_u64;
+	__rte_trace_lib_eal_generic_u32;
+	__rte_trace_lib_eal_generic_u16;
+	__rte_trace_lib_eal_generic_u8;
+	__rte_trace_lib_eal_generic_i64;
+	__rte_trace_lib_eal_generic_i32;
+	__rte_trace_lib_eal_generic_i16;
+	__rte_trace_lib_eal_generic_i8;
+	__rte_trace_lib_eal_generic_int;
+	__rte_trace_lib_eal_generic_long;
+	__rte_trace_lib_eal_generic_float;
+	__rte_trace_lib_eal_generic_double;
+	__rte_trace_lib_eal_generic_ptr;
+	__rte_trace_lib_eal_generic_str;
+	__rte_trace_lib_eal_generic_func;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 17/32] eal/trace: add alarm tracepoints
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (15 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 16/32] eal/trace: add generic tracepoints jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 18/32] eal/trace: add memory tracepoints jerinj
                   ` (15 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori, Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

Add following alarm related trace points.

rte_trace_lib_eal_alarm_set()
rte_trace_lib_eal_alarm_cancel()

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 .../common/eal_common_trace_points.c           |  9 +++++++++
 lib/librte_eal/common/include/rte_trace_eal.h  | 18 ++++++++++++++++++
 lib/librte_eal/freebsd/eal/eal_alarm.c         |  3 +++
 lib/librte_eal/linux/eal/eal_alarm.c           |  4 ++++
 lib/librte_eal/rte_eal_version.map             |  2 ++
 5 files changed, 36 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace_points.c b/lib/librte_eal/common/eal_common_trace_points.c
index ff521c981..16261b1d6 100644
--- a/lib/librte_eal/common/eal_common_trace_points.c
+++ b/lib/librte_eal/common/eal_common_trace_points.c
@@ -23,6 +23,9 @@ RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_ptr);
 RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_str);
 RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_func);
 
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_alarm_set);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_alarm_cancel);
+
 RTE_INIT(eal_trace_init)
 {
 	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_void,
@@ -57,4 +60,10 @@ RTE_INIT(eal_trace_init)
 				 lib.eal.generic.string, INFO);
 	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_func,
 				 lib.eal.generic.func, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_alarm_set,
+				 lib.eal.alarm.set, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_alarm_cancel,
+				 lib.eal.alarm.cancel, INFO);
+
 }
diff --git a/lib/librte_eal/common/include/rte_trace_eal.h b/lib/librte_eal/common/include/rte_trace_eal.h
index 269ef7502..df1b3854b 100644
--- a/lib/librte_eal/common/include/rte_trace_eal.h
+++ b/lib/librte_eal/common/include/rte_trace_eal.h
@@ -15,6 +15,7 @@
 extern "C" {
 #endif
 
+#include <rte_alarm.h>
 #include <rte_trace.h>
 
 /* Generic */
@@ -115,6 +116,23 @@ RTE_TRACE_POINT(
 
 #define RTE_TRACE_LIB_EAL_GENERIC_FUNC rte_trace_lib_eal_generic_func(__func__)
 
+/* Alarm */
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_alarm_set,
+	RTE_TRACE_POINT_ARGS(uint64_t us, rte_eal_alarm_callback cb_fn,
+			     void *cb_arg, int rc),
+	rte_trace_ctf_u64(us); rte_trace_ctf_ptr(cb_fn);
+	rte_trace_ctf_ptr(cb_arg); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_alarm_cancel,
+	RTE_TRACE_POINT_ARGS(rte_eal_alarm_callback cb_fn, void *cb_arg,
+			     int count),
+	rte_trace_ctf_ptr(cb_fn); rte_trace_ctf_ptr(cb_arg);
+	rte_trace_ctf_int(count);
+)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/freebsd/eal/eal_alarm.c b/lib/librte_eal/freebsd/eal/eal_alarm.c
index 51ea4b8c0..5f03ab4c4 100644
--- a/lib/librte_eal/freebsd/eal/eal_alarm.c
+++ b/lib/librte_eal/freebsd/eal/eal_alarm.c
@@ -17,6 +17,7 @@
 #include <rte_errno.h>
 #include <rte_interrupts.h>
 #include <rte_spinlock.h>
+#include <rte_trace_eal.h>
 
 #include "eal_private.h"
 #include "eal_alarm_private.h"
@@ -223,6 +224,7 @@ rte_eal_alarm_set(uint64_t us, rte_eal_alarm_callback cb_fn, void *cb_arg)
 
 	rte_spinlock_unlock(&alarm_list_lk);
 
+	rte_trace_lib_eal_alarm_set(us, cb_fn, cb_arg, ret);
 	return ret;
 }
 
@@ -310,5 +312,6 @@ rte_eal_alarm_cancel(rte_eal_alarm_callback cb_fn, void *cb_arg)
 
 	rte_spinlock_unlock(&alarm_list_lk);
 
+	rte_trace_lib_eal_alarm_cancel(cb_fn, cb_arg, count);
 	return count;
 }
diff --git a/lib/librte_eal/linux/eal/eal_alarm.c b/lib/librte_eal/linux/eal/eal_alarm.c
index 0924c9205..9fef3e6c8 100644
--- a/lib/librte_eal/linux/eal/eal_alarm.c
+++ b/lib/librte_eal/linux/eal/eal_alarm.c
@@ -20,6 +20,8 @@
 #include <rte_lcore.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
+#include <rte_trace_eal.h>
+
 #include <eal_private.h>
 
 #ifndef	TFD_NONBLOCK
@@ -172,6 +174,7 @@ rte_eal_alarm_set(uint64_t us, rte_eal_alarm_callback cb_fn, void *cb_arg)
 	}
 	rte_spinlock_unlock(&alarm_list_lk);
 
+	rte_trace_lib_eal_alarm_set(us, cb_fn, cb_arg, ret);
 	return ret;
 }
 
@@ -240,5 +243,6 @@ rte_eal_alarm_cancel(rte_eal_alarm_callback cb_fn, void *cb_arg)
 	else if (err)
 		rte_errno = err;
 
+	rte_trace_lib_eal_alarm_cancel(cb_fn, cb_arg, count);
 	return count;
 }
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 5c2ff73db..d822bf544 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -381,4 +381,6 @@ EXPERIMENTAL {
 	__rte_trace_lib_eal_generic_ptr;
 	__rte_trace_lib_eal_generic_str;
 	__rte_trace_lib_eal_generic_func;
+	__rte_trace_lib_eal_alarm_set;
+	__rte_trace_lib_eal_alarm_cancel;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 18/32] eal/trace: add memory tracepoints
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (16 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 17/32] eal/trace: add alarm tracepoints jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 19/32] eal/trace: add memzone tracepoints jerinj
                   ` (14 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori, Anatoly Burakov
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

Add the following memory-related tracepoints.

rte_trace_lib_eal_mem_zmalloc;
rte_trace_lib_eal_mem_malloc;
rte_trace_lib_eal_mem_realloc;
rte_trace_lib_eal_mem_free;

rte_malloc() and rte_free() has been used in the trace implementation,
in order to avoid tracing implementation specific events, added
an internal no trace version rte_malloc() and rte_free().

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c      |  4 +-
 .../common/eal_common_trace_points.c          | 14 +++++
 lib/librte_eal/common/eal_private.h           |  5 ++
 lib/librte_eal/common/include/rte_trace_eal.h | 33 ++++++++++
 lib/librte_eal/common/rte_malloc.c            | 60 ++++++++++++++++---
 lib/librte_eal/rte_eal_version.map            |  4 ++
 6 files changed, 109 insertions(+), 11 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index 94d3da0d3..33b783382 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -434,7 +434,7 @@ __rte_trace_mem_per_thread_alloc(void)
 	}
 
 	/* First attempt from huge page */
-	header = rte_malloc(NULL, trace_mem_sz(trace->buff_len), 8);
+	header = eal_malloc_no_trace(NULL, trace_mem_sz(trace->buff_len), 8);
 	if (header) {
 		trace->lcore_meta[count].area = TRACE_AREA_HUGEPAGE;
 		goto found;
@@ -486,7 +486,7 @@ trace_mem_per_thread_free(void)
 	for (count = 0; count < trace->nb_trace_mem_list; count++) {
 		mem = trace->lcore_meta[count].mem;
 		if (trace->lcore_meta[count].area == TRACE_AREA_HUGEPAGE)
-			rte_free(mem);
+			eal_free_no_trace(mem);
 		else if (trace->lcore_meta[count].area == TRACE_AREA_HEAP)
 			free(mem);
 	}
diff --git a/lib/librte_eal/common/eal_common_trace_points.c b/lib/librte_eal/common/eal_common_trace_points.c
index 16261b1d6..dcae51bac 100644
--- a/lib/librte_eal/common/eal_common_trace_points.c
+++ b/lib/librte_eal/common/eal_common_trace_points.c
@@ -26,6 +26,11 @@ RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_func);
 RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_alarm_set);
 RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_alarm_cancel);
 
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_mem_zmalloc);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_mem_malloc);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_mem_realloc);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_mem_free);
+
 RTE_INIT(eal_trace_init)
 {
 	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_void,
@@ -66,4 +71,13 @@ RTE_INIT(eal_trace_init)
 	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_alarm_cancel,
 				 lib.eal.alarm.cancel, INFO);
 
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_mem_zmalloc,
+				 lib.eal.mem.zmalloc, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_mem_malloc,
+				 lib.eal.mem.malloc, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_mem_realloc,
+				 lib.eal.mem.realloc, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_mem_free,
+				 lib.eal.mem.free, INFO);
+
 }
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 81694616b..f61f52eff 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -446,4 +446,9 @@ eal_get_baseaddr(void);
 const char *
 eal_loglevel_to_string(uint32_t level);
 
+void *
+eal_malloc_no_trace(const char *type, size_t size, unsigned int align);
+
+void eal_free_no_trace(void *addr);
+
 #endif /* _EAL_PRIVATE_H_ */
diff --git a/lib/librte_eal/common/include/rte_trace_eal.h b/lib/librte_eal/common/include/rte_trace_eal.h
index df1b3854b..a8eb422f9 100644
--- a/lib/librte_eal/common/include/rte_trace_eal.h
+++ b/lib/librte_eal/common/include/rte_trace_eal.h
@@ -133,6 +133,39 @@ RTE_TRACE_POINT(
 	rte_trace_ctf_int(count);
 )
 
+/* Memory */
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_mem_zmalloc,
+	RTE_TRACE_POINT_ARGS(const char *type, size_t size, unsigned int align,
+			     int socket, void *ptr),
+	rte_trace_ctf_string(type); rte_trace_ctf_long(size);
+	rte_trace_ctf_u32(align), rte_trace_ctf_int(socket);
+	rte_trace_ctf_ptr(ptr);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_mem_malloc,
+	RTE_TRACE_POINT_ARGS(const char *type, size_t size, unsigned int align,
+			     int socket, void *ptr),
+	rte_trace_ctf_string(type); rte_trace_ctf_long(size);
+	rte_trace_ctf_u32(align), rte_trace_ctf_int(socket);
+	rte_trace_ctf_ptr(ptr);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_mem_realloc,
+	RTE_TRACE_POINT_ARGS(size_t size, unsigned int align,
+			     int socket, void *ptr),
+	rte_trace_ctf_long(size); rte_trace_ctf_u32(align),
+	rte_trace_ctf_int(socket); rte_trace_ctf_ptr(ptr);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_mem_free,
+	RTE_TRACE_POINT_ARGS(void *ptr),
+	rte_trace_ctf_ptr(ptr);
+)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c
index d6026a2b1..9ad032aed 100644
--- a/lib/librte_eal/common/rte_malloc.c
+++ b/lib/librte_eal/common/rte_malloc.c
@@ -20,6 +20,7 @@
 #include <rte_lcore.h>
 #include <rte_common.h>
 #include <rte_spinlock.h>
+#include <rte_trace_eal.h>
 
 #include <rte_malloc.h>
 #include "malloc_elem.h"
@@ -30,20 +31,35 @@
 
 
 /* Free the memory space back to heap */
-void rte_free(void *addr)
+static void
+mem_free(void *addr, const bool trace_ena)
 {
+	if (trace_ena == true)
+		rte_trace_lib_eal_mem_free(addr);
+
 	if (addr == NULL) return;
 	if (malloc_heap_free(malloc_elem_from_data(addr)) < 0)
 		RTE_LOG(ERR, EAL, "Error: Invalid memory\n");
 }
 
-/*
- * Allocate memory on specified heap.
- */
-void *
-rte_malloc_socket(const char *type, size_t size, unsigned int align,
-		int socket_arg)
+void
+rte_free(void *addr)
 {
+	return mem_free(addr, true);
+}
+
+void
+eal_free_no_trace(void *addr)
+{
+	return mem_free(addr, false);
+}
+
+static void *
+malloc_socket(const char *type, size_t size, unsigned int align,
+		int socket_arg, const bool trace_ena)
+{
+	void *ptr;
+
 	/* return NULL if size is 0 or alignment is not power-of-2 */
 	if (size == 0 || (align && !rte_is_power_of_2(align)))
 		return NULL;
@@ -57,8 +73,29 @@ rte_malloc_socket(const char *type, size_t size, unsigned int align,
 				!rte_eal_has_hugepages())
 		socket_arg = SOCKET_ID_ANY;
 
-	return malloc_heap_alloc(type, size, socket_arg, 0,
+	ptr = malloc_heap_alloc(type, size, socket_arg, 0,
 			align == 0 ? 1 : align, 0, false);
+
+	if (trace_ena == true)
+		rte_trace_lib_eal_mem_malloc(type, size, align,
+					     socket_arg, ptr);
+	return ptr;
+}
+
+/*
+ * Allocate memory on specified heap.
+ */
+void *
+rte_malloc_socket(const char *type, size_t size, unsigned int align,
+		int socket_arg)
+{
+	return malloc_socket(type, size, align, socket_arg, true);
+}
+
+void *
+eal_malloc_no_trace(const char *type, size_t size, unsigned int align)
+{
+	return malloc_socket(type, size, align, SOCKET_ID_ANY, false);
 }
 
 /*
@@ -87,6 +124,8 @@ rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket)
 	if (ptr != NULL)
 		memset(ptr, 0, size);
 #endif
+
+	rte_trace_lib_eal_mem_zmalloc(type, size, align, socket, ptr);
 	return ptr;
 }
 
@@ -140,8 +179,10 @@ rte_realloc_socket(void *ptr, size_t size, unsigned int align, int socket)
 	if ((socket == SOCKET_ID_ANY ||
 	     (unsigned int)socket == elem->heap->socket_id) &&
 			RTE_PTR_ALIGN(ptr, align) == ptr &&
-			malloc_heap_resize(elem, size) == 0)
+			malloc_heap_resize(elem, size) == 0) {
+		rte_trace_lib_eal_mem_realloc(size, align, socket, ptr);
 		return ptr;
+	}
 
 	/* either requested socket id doesn't match, alignment is off
 	 * or we have no room to expand,
@@ -155,6 +196,7 @@ rte_realloc_socket(void *ptr, size_t size, unsigned int align, int socket)
 	rte_memcpy(new_ptr, ptr, old_size < size ? old_size : size);
 	rte_free(ptr);
 
+	rte_trace_lib_eal_mem_realloc(size, align, socket, new_ptr);
 	return new_ptr;
 }
 
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index d822bf544..787d8e076 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -383,4 +383,8 @@ EXPERIMENTAL {
 	__rte_trace_lib_eal_generic_func;
 	__rte_trace_lib_eal_alarm_set;
 	__rte_trace_lib_eal_alarm_cancel;
+	__rte_trace_lib_eal_mem_zmalloc;
+	__rte_trace_lib_eal_mem_malloc;
+	__rte_trace_lib_eal_mem_realloc;
+	__rte_trace_lib_eal_mem_free;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 19/32] eal/trace: add memzone tracepoints
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (17 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 18/32] eal/trace: add memory tracepoints jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 20/32] eal/trace: add thread tracepoints jerinj
                   ` (13 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Anatoly Burakov, Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

Add the following memzone related tracepoints.

rte_trace_lib_eal_memzone_reserve
rte_trace_lib_eal_memzone_lookup
rte_trace_lib_eal_memzone_free

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/eal_common_memzone.c    |  9 +++++++
 .../common/eal_common_trace_points.c          | 10 +++++++
 lib/librte_eal/common/include/rte_trace_eal.h | 26 +++++++++++++++++++
 lib/librte_eal/rte_eal_version.map            |  3 +++
 4 files changed, 48 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_memzone.c b/lib/librte_eal/common/eal_common_memzone.c
index 86f61369b..0f6556714 100644
--- a/lib/librte_eal/common/eal_common_memzone.c
+++ b/lib/librte_eal/common/eal_common_memzone.c
@@ -19,6 +19,7 @@
 #include <rte_errno.h>
 #include <rte_string_fns.h>
 #include <rte_common.h>
+#include <rte_trace_eal.h>
 
 #include "malloc_heap.h"
 #include "malloc_elem.h"
@@ -201,6 +202,9 @@ rte_memzone_reserve_thread_safe(const char *name, size_t len, int socket_id,
 	mz = memzone_reserve_aligned_thread_unsafe(
 		name, len, socket_id, flags, align, bound);
 
+	rte_trace_lib_eal_memzone_reserve(name, len, socket_id, flags, align,
+					  bound, mz);
+
 	rte_rwlock_write_unlock(&mcfg->mlock);
 
 	return mz;
@@ -246,6 +250,7 @@ rte_memzone_reserve(const char *name, size_t len, int socket_id,
 int
 rte_memzone_free(const struct rte_memzone *mz)
 {
+	char name[RTE_MEMZONE_NAMESIZE];
 	struct rte_mem_config *mcfg;
 	struct rte_fbarray *arr;
 	struct rte_memzone *found_mz;
@@ -256,6 +261,7 @@ rte_memzone_free(const struct rte_memzone *mz)
 	if (mz == NULL)
 		return -EINVAL;
 
+	rte_strlcpy(name, mz->name, RTE_MEMZONE_NAMESIZE);
 	mcfg = rte_eal_get_configuration()->mem_config;
 	arr = &mcfg->memzones;
 
@@ -280,6 +286,8 @@ rte_memzone_free(const struct rte_memzone *mz)
 	if (addr != NULL)
 		rte_free(addr);
 
+	rte_trace_lib_eal_memzone_free(name, addr, ret);
+
 	return ret;
 }
 
@@ -300,6 +308,7 @@ rte_memzone_lookup(const char *name)
 
 	rte_rwlock_read_unlock(&mcfg->mlock);
 
+	rte_trace_lib_eal_memzone_lookup(name, memzone);
 	return memzone;
 }
 
diff --git a/lib/librte_eal/common/eal_common_trace_points.c b/lib/librte_eal/common/eal_common_trace_points.c
index dcae51bac..aeaeac061 100644
--- a/lib/librte_eal/common/eal_common_trace_points.c
+++ b/lib/librte_eal/common/eal_common_trace_points.c
@@ -31,6 +31,10 @@ RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_mem_malloc);
 RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_mem_realloc);
 RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_mem_free);
 
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_memzone_reserve);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_memzone_lookup);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_memzone_free);
+
 RTE_INIT(eal_trace_init)
 {
 	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_void,
@@ -80,4 +84,10 @@ RTE_INIT(eal_trace_init)
 	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_mem_free,
 				 lib.eal.mem.free, INFO);
 
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_memzone_reserve,
+				 lib.eal.memzone.reserve, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_memzone_lookup,
+				 lib.eal.memzone.lookup, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_memzone_free,
+				 lib.eal.memzone.free, INFO);
 }
diff --git a/lib/librte_eal/common/include/rte_trace_eal.h b/lib/librte_eal/common/include/rte_trace_eal.h
index a8eb422f9..316bc8c97 100644
--- a/lib/librte_eal/common/include/rte_trace_eal.h
+++ b/lib/librte_eal/common/include/rte_trace_eal.h
@@ -166,6 +166,32 @@ RTE_TRACE_POINT(
 	rte_trace_ctf_ptr(ptr);
 )
 
+/* Memzone */
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_memzone_reserve,
+	RTE_TRACE_POINT_ARGS(const char *name, size_t len, int socket_id,
+			     unsigned int flags, unsigned int align,
+			     unsigned int bound, const void *mz),
+	rte_trace_ctf_string(name); rte_trace_ctf_long(len);
+	rte_trace_ctf_int(socket_id); rte_trace_ctf_u32(flags);
+	rte_trace_ctf_u32(align); rte_trace_ctf_u32(bound);
+	rte_trace_ctf_ptr(mz);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_memzone_lookup,
+	RTE_TRACE_POINT_ARGS(const char *name, const void *memzone),
+	rte_trace_ctf_string(name); rte_trace_ctf_ptr(memzone);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_memzone_free,
+	RTE_TRACE_POINT_ARGS(const char *name, void *addr, int rc),
+	rte_trace_ctf_string(name); rte_trace_ctf_ptr(addr);
+	rte_trace_ctf_int(rc);
+)
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 787d8e076..8a716be9e 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -387,4 +387,7 @@ EXPERIMENTAL {
 	__rte_trace_lib_eal_mem_malloc;
 	__rte_trace_lib_eal_mem_realloc;
 	__rte_trace_lib_eal_mem_free;
+	__rte_trace_lib_eal_memzone_reserve;
+	__rte_trace_lib_eal_memzone_lookup;
+	__rte_trace_lib_eal_memzone_free;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 20/32] eal/trace: add thread tracepoints
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (18 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 19/32] eal/trace: add memzone tracepoints jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 21/32] eal/trace: add interrupt tracepoints jerinj
                   ` (12 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori, Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

Add the following thread related tracepoints.

rte_trace_lib_eal_thread_remote_launch;
rte_trace_lib_eal_thread_lcore_ready;

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/eal_common_trace_points.c |  9 +++++++++
 lib/librte_eal/common/include/rte_trace_eal.h   | 14 ++++++++++++++
 lib/librte_eal/freebsd/eal/eal_thread.c         | 11 ++++++++---
 lib/librte_eal/linux/eal/eal_thread.c           | 11 ++++++++---
 lib/librte_eal/rte_eal_version.map              |  2 ++
 5 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_trace_points.c b/lib/librte_eal/common/eal_common_trace_points.c
index aeaeac061..2c0b72b5c 100644
--- a/lib/librte_eal/common/eal_common_trace_points.c
+++ b/lib/librte_eal/common/eal_common_trace_points.c
@@ -35,6 +35,9 @@ RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_memzone_reserve);
 RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_memzone_lookup);
 RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_memzone_free);
 
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_thread_remote_launch);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_thread_lcore_ready);
+
 RTE_INIT(eal_trace_init)
 {
 	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_void,
@@ -90,4 +93,10 @@ RTE_INIT(eal_trace_init)
 				 lib.eal.memzone.lookup, INFO);
 	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_memzone_free,
 				 lib.eal.memzone.free, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_thread_remote_launch,
+				 lib.eal.thread.remote.launch, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_thread_lcore_ready,
+				 lib.eal.thread.lcore.ready, INFO);
+
 }
diff --git a/lib/librte_eal/common/include/rte_trace_eal.h b/lib/librte_eal/common/include/rte_trace_eal.h
index 316bc8c97..82e08809b 100644
--- a/lib/librte_eal/common/include/rte_trace_eal.h
+++ b/lib/librte_eal/common/include/rte_trace_eal.h
@@ -191,6 +191,20 @@ RTE_TRACE_POINT(
 	rte_trace_ctf_int(rc);
 )
 
+/* Thread */
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_thread_remote_launch,
+	RTE_TRACE_POINT_ARGS(int (*f)(void *), void *arg,
+			     unsigned int slave_id, int rc),
+	rte_trace_ctf_ptr(f); rte_trace_ctf_ptr(arg);
+	rte_trace_ctf_u32(slave_id); rte_trace_ctf_int(rc);
+)
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_thread_lcore_ready,
+	RTE_TRACE_POINT_ARGS(unsigned int lcore_id, const char *cpuset),
+	rte_trace_ctf_u32(lcore_id); rte_trace_ctf_string(cpuset);
+)
+
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_eal/freebsd/eal/eal_thread.c b/lib/librte_eal/freebsd/eal/eal_thread.c
index aaccb4926..66b0765cf 100644
--- a/lib/librte_eal/freebsd/eal/eal_thread.c
+++ b/lib/librte_eal/freebsd/eal/eal_thread.c
@@ -20,7 +20,7 @@
 #include <rte_per_lcore.h>
 #include <rte_eal.h>
 #include <rte_lcore.h>
-#include <rte_trace.h>
+#include <rte_trace_eal.h>
 
 #include "eal_private.h"
 #include "eal_thread.h"
@@ -41,9 +41,10 @@ rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned slave_id)
 	char c = 0;
 	int m2s = lcore_config[slave_id].pipe_master2slave[1];
 	int s2m = lcore_config[slave_id].pipe_slave2master[0];
+	int rc = -EBUSY;
 
 	if (lcore_config[slave_id].state != WAIT)
-		return -EBUSY;
+		goto finish;
 
 	lcore_config[slave_id].f = f;
 	lcore_config[slave_id].arg = arg;
@@ -63,7 +64,10 @@ rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned slave_id)
 	if (n <= 0)
 		rte_panic("cannot read on configuration pipe\n");
 
-	return 0;
+	rc = 0;
+finish:
+	rte_trace_lib_eal_thread_remote_launch(f, arg, slave_id, rc);
+	return rc;
 }
 
 /* set affinity for current thread */
@@ -126,6 +130,7 @@ eal_thread_loop(__attribute__((unused)) void *arg)
 		lcore_id, thread_id, cpuset, ret == 0 ? "" : "...");
 
 	__rte_trace_mem_per_thread_alloc();
+	rte_trace_lib_eal_thread_lcore_ready(lcore_id, cpuset);
 
 	/* read on our pipe to get commands */
 	while (1) {
diff --git a/lib/librte_eal/linux/eal/eal_thread.c b/lib/librte_eal/linux/eal/eal_thread.c
index 45f4dce44..afadbcbd7 100644
--- a/lib/librte_eal/linux/eal/eal_thread.c
+++ b/lib/librte_eal/linux/eal/eal_thread.c
@@ -20,7 +20,7 @@
 #include <rte_per_lcore.h>
 #include <rte_eal.h>
 #include <rte_lcore.h>
-#include <rte_trace.h>
+#include <rte_trace_eal.h>
 
 #include "eal_private.h"
 #include "eal_thread.h"
@@ -41,9 +41,10 @@ rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned slave_id)
 	char c = 0;
 	int m2s = lcore_config[slave_id].pipe_master2slave[1];
 	int s2m = lcore_config[slave_id].pipe_slave2master[0];
+	int rc = -EBUSY;
 
 	if (lcore_config[slave_id].state != WAIT)
-		return -EBUSY;
+		goto finish;
 
 	lcore_config[slave_id].f = f;
 	lcore_config[slave_id].arg = arg;
@@ -63,7 +64,10 @@ rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned slave_id)
 	if (n <= 0)
 		rte_panic("cannot read on configuration pipe\n");
 
-	return 0;
+	rc = 0;
+finish:
+	rte_trace_lib_eal_thread_remote_launch(f, arg, slave_id, rc);
+	return rc;
 }
 
 /* set affinity for current EAL thread */
@@ -126,6 +130,7 @@ eal_thread_loop(__attribute__((unused)) void *arg)
 		lcore_id, (uintptr_t)thread_id, cpuset, ret == 0 ? "" : "...");
 
 	__rte_trace_mem_per_thread_alloc();
+	rte_trace_lib_eal_thread_lcore_ready(lcore_id, cpuset);
 
 	/* read on our pipe to get commands */
 	while (1) {
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 8a716be9e..dc9241919 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -390,4 +390,6 @@ EXPERIMENTAL {
 	__rte_trace_lib_eal_memzone_reserve;
 	__rte_trace_lib_eal_memzone_lookup;
 	__rte_trace_lib_eal_memzone_free;
+	__rte_trace_lib_eal_thread_remote_launch;
+	__rte_trace_lib_eal_thread_lcore_ready;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 21/32] eal/trace: add interrupt tracepoints
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (19 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 20/32] eal/trace: add thread tracepoints jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 22/32] eal/trace: add trace level configuration parameter jerinj
                   ` (11 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Jerin Jacob, Sunil Kumar Kori, Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom

From: Jerin Jacob <jerinj@marvell.com>

Add the following interrupt related tracepoints.

rte_trace_lib_eal_intr_callback_register;
rte_trace_lib_eal_intr_callback_unregister;
rte_trace_lib_eal_intr_enable;
rte_trace_lib_eal_intr_disable;

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 .../common/eal_common_trace_points.c          | 13 +++
 lib/librte_eal/common/include/rte_trace_eal.h | 34 ++++++++
 lib/librte_eal/freebsd/eal/eal_interrupts.c   | 52 ++++++++----
 lib/librte_eal/linux/eal/eal_interrupts.c     | 84 ++++++++++++-------
 lib/librte_eal/rte_eal_version.map            |  4 +
 5 files changed, 139 insertions(+), 48 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_trace_points.c b/lib/librte_eal/common/eal_common_trace_points.c
index 2c0b72b5c..7f1a43519 100644
--- a/lib/librte_eal/common/eal_common_trace_points.c
+++ b/lib/librte_eal/common/eal_common_trace_points.c
@@ -38,6 +38,11 @@ RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_memzone_free);
 RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_thread_remote_launch);
 RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_thread_lcore_ready);
 
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_intr_callback_register);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_intr_callback_unregister);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_intr_enable);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_intr_disable);
+
 RTE_INIT(eal_trace_init)
 {
 	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_void,
@@ -99,4 +104,12 @@ RTE_INIT(eal_trace_init)
 	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_thread_lcore_ready,
 				 lib.eal.thread.lcore.ready, INFO);
 
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_intr_callback_register,
+				 lib.eal.intr.register, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_intr_callback_unregister,
+				 lib.eal.intr.unregister, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_intr_enable,
+				 lib.eal.intr.enable, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_intr_disable,
+				 lib.eal.intr.disable, INFO);
 }
diff --git a/lib/librte_eal/common/include/rte_trace_eal.h b/lib/librte_eal/common/include/rte_trace_eal.h
index 82e08809b..ea2572723 100644
--- a/lib/librte_eal/common/include/rte_trace_eal.h
+++ b/lib/librte_eal/common/include/rte_trace_eal.h
@@ -16,6 +16,7 @@ extern "C" {
 #endif
 
 #include <rte_alarm.h>
+#include <rte_interrupts.h>
 #include <rte_trace.h>
 
 /* Generic */
@@ -205,6 +206,39 @@ RTE_TRACE_POINT(
 	rte_trace_ctf_u32(lcore_id); rte_trace_ctf_string(cpuset);
 )
 
+/* Interrupt */
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_intr_callback_register,
+	RTE_TRACE_POINT_ARGS(const struct rte_intr_handle *handle,
+			     rte_intr_callback_fn cb, void *cb_arg, int rc),
+	rte_trace_ctf_int(rc); rte_trace_ctf_int(handle->vfio_dev_fd);
+	rte_trace_ctf_int(handle->fd); rte_trace_ctf_int(handle->type);
+	rte_trace_ctf_u32(handle->max_intr); rte_trace_ctf_u32(handle->nb_efd);
+	rte_trace_ctf_ptr(cb); rte_trace_ctf_ptr(cb_arg);
+)
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_intr_callback_unregister,
+	RTE_TRACE_POINT_ARGS(const struct rte_intr_handle *handle,
+			     rte_intr_callback_fn cb, void *cb_arg, int rc),
+	rte_trace_ctf_int(rc); rte_trace_ctf_int(handle->vfio_dev_fd);
+	rte_trace_ctf_int(handle->fd); rte_trace_ctf_int(handle->type);
+	rte_trace_ctf_u32(handle->max_intr); rte_trace_ctf_u32(handle->nb_efd);
+	rte_trace_ctf_ptr(cb); rte_trace_ctf_ptr(cb_arg);
+)
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_intr_enable,
+	RTE_TRACE_POINT_ARGS(const struct rte_intr_handle *handle, int rc),
+	rte_trace_ctf_int(rc); rte_trace_ctf_int(handle->vfio_dev_fd);
+	rte_trace_ctf_int(handle->fd); rte_trace_ctf_int(handle->type);
+	rte_trace_ctf_u32(handle->max_intr); rte_trace_ctf_u32(handle->nb_efd);
+)
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_intr_disable,
+	RTE_TRACE_POINT_ARGS(const struct rte_intr_handle *handle, int rc),
+	rte_trace_ctf_int(rc); rte_trace_ctf_int(handle->vfio_dev_fd);
+	rte_trace_ctf_int(handle->fd); rte_trace_ctf_int(handle->type);
+	rte_trace_ctf_u32(handle->max_intr); rte_trace_ctf_u32(handle->nb_efd);
+)
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_eal/freebsd/eal/eal_interrupts.c b/lib/librte_eal/freebsd/eal/eal_interrupts.c
index ce2a27b4a..24b614bf2 100644
--- a/lib/librte_eal/freebsd/eal/eal_interrupts.c
+++ b/lib/librte_eal/freebsd/eal/eal_interrupts.c
@@ -13,6 +13,7 @@
 #include <rte_spinlock.h>
 #include <rte_common.h>
 #include <rte_interrupts.h>
+#include <rte_trace_eal.h>
 
 #include "eal_private.h"
 #include "eal_alarm_private.h"
@@ -176,6 +177,7 @@ rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
 			goto fail;
 		}
 	}
+	rte_trace_lib_eal_intr_callback_register(intr_handle, cb, cb_arg, ret);
 	rte_spinlock_unlock(&intr_lock);
 
 	return ret;
@@ -189,6 +191,7 @@ rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
 		}
 	}
 	free(callback);
+	rte_trace_lib_eal_intr_callback_register(intr_handle, cb, cb_arg, ret);
 	rte_spinlock_unlock(&intr_lock);
 	return ret;
 }
@@ -328,6 +331,8 @@ rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
 		}
 	}
 out:
+	rte_trace_lib_eal_intr_callback_unregister(intr_handle, cb_fn,
+						   cb_arg, ret);
 	rte_spinlock_unlock(&intr_lock);
 
 	return ret;
@@ -336,55 +341,68 @@ rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
 int
 rte_intr_enable(const struct rte_intr_handle *intr_handle)
 {
-	if (intr_handle && intr_handle->type == RTE_INTR_HANDLE_VDEV)
-		return 0;
+	int rc = 0;
 
-	if (!intr_handle || intr_handle->fd < 0 || intr_handle->uio_cfg_fd < 0)
-		return -1;
+	if (intr_handle && intr_handle->type == RTE_INTR_HANDLE_VDEV) {
+		rc = 0; goto out;
+	}
+
+	if (!intr_handle || intr_handle->fd < 0 ||
+				intr_handle->uio_cfg_fd < 0) {
+		rc = -1; goto out;
+	}
 
 	switch (intr_handle->type) {
 	/* not used at this moment */
 	case RTE_INTR_HANDLE_ALARM:
-		return -1;
+		rc = -1; break;
 	/* not used at this moment */
 	case RTE_INTR_HANDLE_DEV_EVENT:
-		return -1;
+		rc = -1; break;
 	/* unknown handle type */
 	default:
 		RTE_LOG(ERR, EAL,
 			"Unknown handle type of fd %d\n",
 					intr_handle->fd);
-		return -1;
+		rc = -1; break;
 	}
 
-	return 0;
+out:
+	rte_trace_lib_eal_intr_enable(intr_handle, rc);
+	return rc;
 }
 
 int
 rte_intr_disable(const struct rte_intr_handle *intr_handle)
 {
-	if (intr_handle && intr_handle->type == RTE_INTR_HANDLE_VDEV)
-		return 0;
+	int rc = 0;
 
-	if (!intr_handle || intr_handle->fd < 0 || intr_handle->uio_cfg_fd < 0)
-		return -1;
+	if (intr_handle && intr_handle->type == RTE_INTR_HANDLE_VDEV) {
+		rc = 0; goto out;
+	}
+
+	if (!intr_handle || intr_handle->fd < 0 ||
+				intr_handle->uio_cfg_fd < 0) {
+		rc = -1; goto out;
+	}
 
 	switch (intr_handle->type) {
 	/* not used at this moment */
 	case RTE_INTR_HANDLE_ALARM:
-		return -1;
+		rc = -1; break;
 	/* not used at this moment */
 	case RTE_INTR_HANDLE_DEV_EVENT:
-		return -1;
+		rc = -1; break;
 	/* unknown handle type */
 	default:
 		RTE_LOG(ERR, EAL,
 			"Unknown handle type of fd %d\n",
 					intr_handle->fd);
-		return -1;
+		rc = -1; break;
 	}
-
-	return 0;
+out:
+	rte_trace_lib_eal_intr_disable(intr_handle, rc);
+	return rc;
 }
 
 int
diff --git a/lib/librte_eal/linux/eal/eal_interrupts.c b/lib/librte_eal/linux/eal/eal_interrupts.c
index cb8e10709..20e9cb35e 100644
--- a/lib/librte_eal/linux/eal/eal_interrupts.c
+++ b/lib/librte_eal/linux/eal/eal_interrupts.c
@@ -34,6 +34,7 @@
 #include <rte_spinlock.h>
 #include <rte_pause.h>
 #include <rte_vfio.h>
+#include <rte_trace_eal.h>
 
 #include "eal_private.h"
 #include "eal_vfio.h"
@@ -539,8 +540,9 @@ rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
 	 */
 	if (wake_thread)
 		if (write(intr_pipe.writefd, "1", 1) < 0)
-			return -EPIPE;
+			ret = -EPIPE;
 
+	rte_trace_lib_eal_intr_callback_register(intr_handle, cb, cb_arg, ret);
 	return ret;
 }
 
@@ -656,63 +658,74 @@ rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
 		ret = -EPIPE;
 	}
 
+	rte_trace_lib_eal_intr_callback_unregister(intr_handle, cb_fn,
+						   cb_arg, ret);
 	return ret;
 }
 
 int
 rte_intr_enable(const struct rte_intr_handle *intr_handle)
 {
-	if (intr_handle && intr_handle->type == RTE_INTR_HANDLE_VDEV)
-		return 0;
+	int rc = 0;
 
-	if (!intr_handle || intr_handle->fd < 0 || intr_handle->uio_cfg_fd < 0)
-		return -1;
+	if (intr_handle && intr_handle->type == RTE_INTR_HANDLE_VDEV) {
+		rc = 0; goto out;
+	}
+
+	if (!intr_handle || intr_handle->fd < 0 ||
+						intr_handle->uio_cfg_fd < 0) {
+		rc = -1; goto out;
+	}
 
 	switch (intr_handle->type){
 	/* write to the uio fd to enable the interrupt */
 	case RTE_INTR_HANDLE_UIO:
 		if (uio_intr_enable(intr_handle))
-			return -1;
+			rc = -1;
 		break;
 	case RTE_INTR_HANDLE_UIO_INTX:
 		if (uio_intx_intr_enable(intr_handle))
-			return -1;
+			rc = -1;
 		break;
 	/* not used at this moment */
 	case RTE_INTR_HANDLE_ALARM:
-		return -1;
+		rc = -1;
+		break;
 #ifdef VFIO_PRESENT
 	case RTE_INTR_HANDLE_VFIO_MSIX:
 		if (vfio_enable_msix(intr_handle))
-			return -1;
+			rc = -1;
 		break;
 	case RTE_INTR_HANDLE_VFIO_MSI:
 		if (vfio_enable_msi(intr_handle))
-			return -1;
+			rc = -1;
 		break;
 	case RTE_INTR_HANDLE_VFIO_LEGACY:
 		if (vfio_enable_intx(intr_handle))
-			return -1;
+			rc = -1;
 		break;
 #ifdef HAVE_VFIO_DEV_REQ_INTERFACE
 	case RTE_INTR_HANDLE_VFIO_REQ:
 		if (vfio_enable_req(intr_handle))
-			return -1;
+			rc = -1;
 		break;
 #endif
 #endif
 	/* not used at this moment */
 	case RTE_INTR_HANDLE_DEV_EVENT:
-		return -1;
+		rc = -1;
+		break;
 	/* unknown handle type */
 	default:
 		RTE_LOG(ERR, EAL,
 			"Unknown handle type of fd %d\n",
 					intr_handle->fd);
-		return -1;
+		rc = -1;
+		break;
 	}
-
-	return 0;
+out:
+	rte_trace_lib_eal_intr_enable(intr_handle, rc);
+	return rc;
 }
 
 /**
@@ -778,57 +791,66 @@ rte_intr_ack(const struct rte_intr_handle *intr_handle)
 int
 rte_intr_disable(const struct rte_intr_handle *intr_handle)
 {
-	if (intr_handle && intr_handle->type == RTE_INTR_HANDLE_VDEV)
-		return 0;
+	int rc = 0;
 
-	if (!intr_handle || intr_handle->fd < 0 || intr_handle->uio_cfg_fd < 0)
-		return -1;
+	if (intr_handle && intr_handle->type == RTE_INTR_HANDLE_VDEV) {
+		rc = 0; goto out;
+	}
+
+	if (!intr_handle || intr_handle->fd < 0 ||
+					intr_handle->uio_cfg_fd < 0) {
+		rc = -1; goto out;
+	}
 
 	switch (intr_handle->type){
 	/* write to the uio fd to disable the interrupt */
 	case RTE_INTR_HANDLE_UIO:
 		if (uio_intr_disable(intr_handle))
-			return -1;
+			rc = -1;
 		break;
 	case RTE_INTR_HANDLE_UIO_INTX:
 		if (uio_intx_intr_disable(intr_handle))
-			return -1;
+			rc = -1;
 		break;
 	/* not used at this moment */
 	case RTE_INTR_HANDLE_ALARM:
-		return -1;
+		rc = -1;
+		break;
 #ifdef VFIO_PRESENT
 	case RTE_INTR_HANDLE_VFIO_MSIX:
 		if (vfio_disable_msix(intr_handle))
-			return -1;
+			rc = -1;
 		break;
 	case RTE_INTR_HANDLE_VFIO_MSI:
 		if (vfio_disable_msi(intr_handle))
-			return -1;
+			rc = -1;
 		break;
 	case RTE_INTR_HANDLE_VFIO_LEGACY:
 		if (vfio_disable_intx(intr_handle))
-			return -1;
+			rc = -1;
 		break;
 #ifdef HAVE_VFIO_DEV_REQ_INTERFACE
 	case RTE_INTR_HANDLE_VFIO_REQ:
 		if (vfio_disable_req(intr_handle))
-			return -1;
+			rc = -1;
 		break;
 #endif
 #endif
 	/* not used at this moment */
 	case RTE_INTR_HANDLE_DEV_EVENT:
-		return -1;
+		rc = -1;
+		break;
 	/* unknown handle type */
 	default:
 		RTE_LOG(ERR, EAL,
 			"Unknown handle type of fd %d\n",
 					intr_handle->fd);
-		return -1;
+		rc = -1;
+		break;
 	}
-
-	return 0;
+out:
+	rte_trace_lib_eal_intr_disable(intr_handle, rc);
+	return rc;
 }
 
 static int
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index dc9241919..ffa449076 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -392,4 +392,8 @@ EXPERIMENTAL {
 	__rte_trace_lib_eal_memzone_free;
 	__rte_trace_lib_eal_thread_remote_launch;
 	__rte_trace_lib_eal_thread_lcore_ready;
+	__rte_trace_lib_eal_intr_callback_register;
+	__rte_trace_lib_eal_intr_callback_unregister;
+	__rte_trace_lib_eal_intr_enable;
+	__rte_trace_lib_eal_intr_disable;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 22/32] eal/trace: add trace level configuration parameter
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (20 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 21/32] eal/trace: add interrupt tracepoints jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 23/32] eal/trace: add trace dir " jerinj
                   ` (10 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: John McNamara, Marko Kovacevic, Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Sunil Kumar Kori <skori@marvell.com>

Trace library exposes --trace-level EAL parameter to configure
global and trace point specific level.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 doc/guides/linux_gsg/eal_args.include.rst     |  19 ++++
 lib/librte_eal/common/eal_common_options.c    |  19 +++-
 lib/librte_eal/common/eal_common_trace.c      |  10 ++
 .../common/eal_common_trace_utils.c           | 104 ++++++++++++++++++
 lib/librte_eal/common/eal_options.h           |   2 +
 lib/librte_eal/common/eal_private.h           |   3 +
 lib/librte_eal/common/eal_trace.h             |  11 +-
 7 files changed, 166 insertions(+), 2 deletions(-)

diff --git a/doc/guides/linux_gsg/eal_args.include.rst b/doc/guides/linux_gsg/eal_args.include.rst
index ed8b0e35b..94289d1e2 100644
--- a/doc/guides/linux_gsg/eal_args.include.rst
+++ b/doc/guides/linux_gsg/eal_args.include.rst
@@ -136,6 +136,25 @@ Debugging options
 
     Can be specified multiple times.
 
+*   ``--trace-level=<val> | <*type*:val> | <type, val>``
+
+    Specify trace level for global or specific component, based on pattern or
+    regular expression matching. For example:
+
+    Global trace level configuration::
+
+        --trace-level=8
+
+    Global trace level configuration for EAL only using pattern match::
+
+        --trace-level=*eal*:8
+
+    Global trace level configuration for EAL only using regexp match::
+
+        --trace-level=eal,8
+
+    Can be specified multiple times up to 32 times.
+
 Other options
 ~~~~~~~~~~~~~
 
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 525e51e7d..0d6576a12 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -34,6 +34,7 @@
 #include "eal_options.h"
 #include "eal_filesystem.h"
 #include "eal_private.h"
+#include "eal_trace.h"
 
 #define BITS_PER_HEX 4
 #define LCORE_OPT_LST 1
@@ -67,6 +68,7 @@ eal_long_options[] = {
 	{OPT_IOVA_MODE,	        1, NULL, OPT_IOVA_MODE_NUM        },
 	{OPT_LCORES,            1, NULL, OPT_LCORES_NUM           },
 	{OPT_LOG_LEVEL,         1, NULL, OPT_LOG_LEVEL_NUM        },
+	{OPT_TRACE_LEVEL,       1, NULL, OPT_TRACE_LEVEL_NUM      },
 	{OPT_MASTER_LCORE,      1, NULL, OPT_MASTER_LCORE_NUM     },
 	{OPT_MBUF_POOL_OPS_NAME, 1, NULL, OPT_MBUF_POOL_OPS_NAME_NUM},
 	{OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
@@ -976,7 +978,7 @@ eal_parse_syslog(const char *facility, struct internal_config *conf)
 }
 #endif
 
-static int
+int
 eal_parse_log_priority(const char *level)
 {
 	static const char * const levels[] = {
@@ -1418,6 +1420,16 @@ eal_parse_common_option(int opt, const char *optarg,
 		}
 		break;
 	}
+
+	case OPT_TRACE_LEVEL_NUM: {
+		if (eal_trace_level_args_save(optarg) < 0) {
+			RTE_LOG(ERR, EAL, "invalid parameters for --"
+				OPT_TRACE_LEVEL "\n");
+			return -1;
+		}
+		break;
+	}
+
 	case OPT_LCORES_NUM:
 		if (eal_parse_lcores(optarg) < 0) {
 			RTE_LOG(ERR, EAL, "invalid parameter for --"
@@ -1693,6 +1705,11 @@ eal_common_usage(void)
 	       "  --"OPT_LOG_LEVEL"=<int>   Set global log level\n"
 	       "  --"OPT_LOG_LEVEL"=<type-match>:<int>\n"
 	       "                      Set specific log level\n"
+	       "  --"OPT_TRACE_LEVEL"=<int> Set global trace level\n"
+	       "  --"OPT_TRACE_LEVEL"=<type-match>:<int>\n"
+	       "                    Set trace level specific to component\n"
+	       "                    Default, there is no trace level enabled\n"
+	       "                    User must specify this option if required\n"
 	       "  -v                  Display version information on startup\n"
 	       "  -h, --help          This help\n"
 	       "  --"OPT_IN_MEMORY"   Operate entirely in memory. This will\n"
diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index 33b783382..697cdbcf3 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -38,6 +38,8 @@ trace_list_head_get(void)
 int
 eal_trace_init(void)
 {
+	uint8_t i;
+
 	/* Trace memory should start with 8B aligned for natural alignment */
 	RTE_BUILD_BUG_ON((offsetof(struct __rte_trace_header, mem) % 8) != 0);
 
@@ -47,6 +49,9 @@ eal_trace_init(void)
 		goto fail;
 	}
 
+	if (trace.args.nb_args)
+		trace.global_status = true;
+
 	if (rte_trace_global_is_disabled())
 		return 0;
 
@@ -71,6 +76,10 @@ eal_trace_init(void)
 	if (trace_epoch_time_save())
 		goto free_meta;
 
+	/* Apply global configurations */
+	for (i = 0; i < trace.args.nb_args; i++)
+		trace_level_args_apply(trace.args.args[i]);
+
 	rte_trace_global_mode_set(trace.mode);
 
 	return 0;
@@ -89,6 +98,7 @@ eal_trace_fini(void)
 		return;
 	trace_mem_per_thread_free();
 	trace_metadata_destroy();
+	eal_trace_level_args_free();
 }
 
 bool
diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
index 230e4ac95..156ae36de 100644
--- a/lib/librte_eal/common/eal_common_trace_utils.c
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -118,6 +118,110 @@ trace_session_name_generate(char *trace_dir)
 	return -rte_errno;
 }
 
+int
+eal_trace_level_args_save(const char *optarg)
+{
+	struct trace *trace = trace_obj_get();
+	char *trace_args;
+	uint8_t nb_args;
+
+	nb_args = trace->args.nb_args;
+
+	if (nb_args >= TRACE_LEVEL_MAX_ARGS) {
+		trace_err("ignoring trace level %s as limit exceeds", optarg);
+		return 0;
+	}
+
+	trace_args = (char *)calloc(1, (strlen(optarg) + 1));
+	if (trace_args == NULL) {
+		trace_err("fail to allocate memory for %s", optarg);
+		return -ENOMEM;
+	}
+
+	memcpy(trace_args, optarg, strlen(optarg));
+	trace->args.args[nb_args++] = trace_args;
+	trace->args.nb_args = nb_args;
+	return 0;
+}
+
+void
+eal_trace_level_args_free(void)
+{
+	struct trace *trace = trace_obj_get();
+	int i;
+
+	for (i = 0; i < trace->args.nb_args; i++) {
+		if (trace->args.args[i]) {
+			free((void *)trace->args.args[i]);
+			trace->args.args[i] = NULL;
+		}
+	}
+}
+
+int
+trace_level_args_apply(const char *arg)
+{
+	struct trace *trace = trace_obj_get();
+	const char *pattern = NULL;
+	const char *regex = NULL;
+	char *str, *level;
+	int level_idx;
+
+	str = strdup(arg);
+	if (str == NULL)
+		return -1;
+
+	level = strchr(str, ',');
+	if (level) {
+		regex = str;
+		*level++ = '\0';
+		goto found;
+	}
+
+	level = strchr(str, ':');
+	if (level) {
+		pattern = str;
+		*level++ = '\0';
+		goto found;
+	}
+
+	level = str;
+
+found:
+	level_idx = eal_parse_log_priority(level);
+	if (level_idx < 0) {
+		trace_err("invalid trace level: %s\n", level);
+		goto fail;
+	}
+
+	/* Update global level */
+	trace->level = level_idx;
+
+	if (regex) {
+		if (rte_trace_regexp(regex, true, NULL) < 0) {
+			trace_err("cannot set trace level %s:%d\n",
+				regex, level_idx);
+			goto fail;
+		}
+
+	} else if (pattern) {
+		if (rte_trace_pattern(pattern, true, NULL) < 0) {
+			trace_err("cannot set trace level %s:%d\n",
+				pattern, level_idx);
+			goto fail;
+		}
+	} else {
+		rte_trace_global_level_set(level_idx);
+	}
+
+	free(str);
+	return 0;
+
+fail:
+	free(str);
+	return -1;
+}
+
 int
 trace_epoch_time_save(void)
 {
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index 9855429e5..c274a30cc 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -33,6 +33,8 @@ enum {
 	OPT_LCORES_NUM,
 #define OPT_LOG_LEVEL         "log-level"
 	OPT_LOG_LEVEL_NUM,
+#define OPT_TRACE_LEVEL       "trace-level"
+	OPT_TRACE_LEVEL_NUM,
 #define OPT_MASTER_LCORE      "master-lcore"
 	OPT_MASTER_LCORE_NUM,
 #define OPT_MBUF_POOL_OPS_NAME "mbuf-pool-ops-name"
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index f61f52eff..1876bc01e 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -446,6 +446,9 @@ eal_get_baseaddr(void);
 const char *
 eal_loglevel_to_string(uint32_t level);
 
+int
+eal_parse_log_priority(const char *level);
+
 void *
 eal_malloc_no_trace(const char *type, size_t size, unsigned int align);
 
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index c2d00bbb8..2d4a73415 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -28,7 +28,7 @@
 #define TRACE_CTF_FIELD_SIZE 384
 #define TRACE_POINT_NAME_SIZE 64
 #define TRACE_CTF_MAGIC 0xC1FC1FC1
-
+#define TRACE_LEVEL_MAX_ARGS	32
 
 struct trace_point {
 	STAILQ_ENTRY(trace_point) next;
@@ -47,6 +47,11 @@ struct thread_mem_meta {
 	enum trace_area_e area;
 };
 
+struct trace_args {
+	uint8_t nb_args;
+	char *args[TRACE_LEVEL_MAX_ARGS];
+};
+
 struct trace {
 	char dir[PATH_MAX];
 	int dir_offset;
@@ -56,6 +61,7 @@ struct trace {
 	rte_uuid_t uuid;
 	uint32_t buff_len;
 	uint32_t level;
+	struct trace_args args;
 	uint32_t nb_trace_points;
 	uint32_t nb_trace_mem_list;
 	struct thread_mem_meta *lcore_meta;
@@ -94,6 +100,7 @@ struct trace_point_head *trace_list_head_get(void);
 /* Util functions */
 const char *trace_mode_to_string(enum rte_trace_mode_e mode);
 const char *trace_area_to_string(enum trace_area_e area);
+int trace_level_args_apply(const char *arg);
 bool trace_has_duplicate_entry(void);
 void trace_uuid_generate(void);
 int trace_metadata_create(void);
@@ -105,5 +112,7 @@ void trace_mem_per_thread_free(void);
 /* EAL interface */
 int eal_trace_init(void);
 void eal_trace_fini(void);
+int eal_trace_level_args_save(const char *optarg);
+void eal_trace_level_args_free(void);
 
 #endif /* __EAL_TRACE_H */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 23/32] eal/trace: add trace dir configuration parameter
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (21 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 22/32] eal/trace: add trace level configuration parameter jerinj
@ 2020-03-18 19:02 ` " jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 24/32] eal/trace: add trace bufsize " jerinj
                   ` (9 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: John McNamara, Marko Kovacevic, Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Sunil Kumar Kori <skori@marvell.com>

Trace library exposes --trace-dir EAL parameter to configure
directory where traces will be generated.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 doc/guides/linux_gsg/eal_args.include.rst     | 11 ++++
 lib/librte_eal/common/eal_common_options.c    | 15 ++++++
 .../common/eal_common_trace_utils.c           | 54 +++++++++++++++++++
 lib/librte_eal/common/eal_options.h           |  2 +
 lib/librte_eal/common/eal_trace.h             |  1 +
 5 files changed, 83 insertions(+)

diff --git a/doc/guides/linux_gsg/eal_args.include.rst b/doc/guides/linux_gsg/eal_args.include.rst
index 94289d1e2..8c72363b4 100644
--- a/doc/guides/linux_gsg/eal_args.include.rst
+++ b/doc/guides/linux_gsg/eal_args.include.rst
@@ -155,6 +155,17 @@ Debugging options
 
     Can be specified multiple times up to 32 times.
 
+*   ``--trace-dir=<directory path>``
+
+    Specify trace directory for trace output. For example:
+
+    Configuring ``/tmp/`` as a trace output directory::
+
+        --trace-dir=/tmp
+
+    By default, trace output will created at ``home`` directory and parameter
+    must be specified once only.
+
 Other options
 ~~~~~~~~~~~~~
 
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 0d6576a12..d71f89be2 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -69,6 +69,7 @@ eal_long_options[] = {
 	{OPT_LCORES,            1, NULL, OPT_LCORES_NUM           },
 	{OPT_LOG_LEVEL,         1, NULL, OPT_LOG_LEVEL_NUM        },
 	{OPT_TRACE_LEVEL,       1, NULL, OPT_TRACE_LEVEL_NUM      },
+	{OPT_TRACE_DIR,         1, NULL, OPT_TRACE_DIR_NUM        },
 	{OPT_MASTER_LCORE,      1, NULL, OPT_MASTER_LCORE_NUM     },
 	{OPT_MBUF_POOL_OPS_NAME, 1, NULL, OPT_MBUF_POOL_OPS_NAME_NUM},
 	{OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
@@ -1430,6 +1431,15 @@ eal_parse_common_option(int opt, const char *optarg,
 		break;
 	}
 
+	case OPT_TRACE_DIR_NUM: {
+		if (eal_trace_dir_args_save(optarg) < 0) {
+			RTE_LOG(ERR, EAL, "invalid parameters for --"
+				OPT_TRACE_DIR "\n");
+			return -1;
+		}
+		break;
+	}
+
 	case OPT_LCORES_NUM:
 		if (eal_parse_lcores(optarg) < 0) {
 			RTE_LOG(ERR, EAL, "invalid parameter for --"
@@ -1710,6 +1720,11 @@ eal_common_usage(void)
 	       "                    Set trace level specific to component\n"
 	       "                    Default, there is no trace level enabled\n"
 	       "                    User must specify this option if required\n"
+	       "  --"OPT_TRACE_DIR"=<directory path>\n"
+	       "                    Specify trace directory for trace output.\n"
+	       "                    By default, trace output will created at\n"
+	       "                    HOME directory and parameter must be\n"
+	       "                    specified once only\n"
 	       "  -v                  Display version information on startup\n"
 	       "  -h, --help          This help\n"
 	       "  --"OPT_IN_MEMORY"   Operate entirely in memory. This will\n"
diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
index 156ae36de..013415ba2 100644
--- a/lib/librte_eal/common/eal_common_trace_utils.c
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -118,6 +118,22 @@ trace_session_name_generate(char *trace_dir)
 	return -rte_errno;
 }
 
+static int
+trace_dir_update(const char *str)
+{
+	struct trace *trace = trace_obj_get();
+	int rc, remaining;
+
+	remaining = sizeof(trace->dir) - trace->dir_offset;
+	rc = rte_strscpy(&trace->dir[0] + trace->dir_offset, str, remaining);
+	if (rc < 0)
+		goto fail;
+
+	trace->dir_offset += rc;
+fail:
+	return rc;
+}
+
 int
 eal_trace_level_args_save(const char *optarg)
 {
@@ -222,6 +238,37 @@ trace_level_args_apply(const char *arg)
 	return -1;
 }
 
+int
+eal_trace_dir_args_save(char const *optarg)
+{
+	struct trace *trace = trace_obj_get();
+	uint32_t size = sizeof(trace->dir);
+	char *dir_path = NULL;
+	int rc;
+
+	if (optarg == NULL) {
+		trace_err("no optarg is passed\n");
+		return -EINVAL;
+	}
+
+	if (strlen(optarg) >= size) {
+		trace_err("input string is too big\n");
+		return -ENAMETOOLONG;
+	}
+
+	dir_path = (char *)calloc(1, size);
+	if (dir_path == NULL) {
+		trace_err("fail to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	sprintf(dir_path, "%s/", optarg);
+	rc = trace_dir_update(dir_path);
+
+	free(dir_path);
+	return rc;
+}
+
 int
 trace_epoch_time_save(void)
 {
@@ -292,6 +339,10 @@ trace_mkdir(void)
 			return rc;
 		}
 
+		rc = trace_dir_update(dir_path);
+		free(dir_path);
+		if (rc < 0)
+			return rc;
 	}
 
 	/* Create the path if it t exist, no "mkdir -p" available here */
@@ -303,6 +354,9 @@ trace_mkdir(void)
 	}
 
 	rc = trace_session_name_generate(session);
+	if (rc < 0)
+		return rc;
+	rc = trace_dir_update(session);
 	if (rc < 0)
 		return rc;
 
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index c274a30cc..8c8283165 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -35,6 +35,8 @@ enum {
 	OPT_LOG_LEVEL_NUM,
 #define OPT_TRACE_LEVEL       "trace-level"
 	OPT_TRACE_LEVEL_NUM,
+#define OPT_TRACE_DIR         "trace-dir"
+	OPT_TRACE_DIR_NUM,
 #define OPT_MASTER_LCORE      "master-lcore"
 	OPT_MASTER_LCORE_NUM,
 #define OPT_MBUF_POOL_OPS_NAME "mbuf-pool-ops-name"
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index 2d4a73415..e1754de63 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -114,5 +114,6 @@ int eal_trace_init(void);
 void eal_trace_fini(void);
 int eal_trace_level_args_save(const char *optarg);
 void eal_trace_level_args_free(void);
+int eal_trace_dir_args_save(const char *optarg);
 
 #endif /* __EAL_TRACE_H */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 24/32] eal/trace: add trace bufsize configuration parameter
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (22 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 23/32] eal/trace: add trace dir " jerinj
@ 2020-03-18 19:02 ` " jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 25/32] eal/trace: add trace mode " jerinj
                   ` (8 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: John McNamara, Marko Kovacevic, Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Sunil Kumar Kori <skori@marvell.com>

Trace library exposes --trace-bufsz EAL parameter to configure
maximum size of ring buffer where events are to be stored.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 doc/guides/linux_gsg/eal_args.include.rst     | 13 ++++++++
 lib/librte_eal/common/eal_common_options.c    | 17 +++++++++++
 lib/librte_eal/common/eal_common_trace.c      |  3 ++
 .../common/eal_common_trace_utils.c           | 30 +++++++++++++++++++
 lib/librte_eal/common/eal_options.h           |  2 ++
 lib/librte_eal/common/eal_trace.h             |  2 ++
 6 files changed, 67 insertions(+)

diff --git a/doc/guides/linux_gsg/eal_args.include.rst b/doc/guides/linux_gsg/eal_args.include.rst
index 8c72363b4..cc9fc0255 100644
--- a/doc/guides/linux_gsg/eal_args.include.rst
+++ b/doc/guides/linux_gsg/eal_args.include.rst
@@ -166,6 +166,19 @@ Debugging options
     By default, trace output will created at ``home`` directory and parameter
     must be specified once only.
 
+*   ``--trace-bufsz=<val>``
+
+    Specify maximum size of allocated memory for trace output for each thread.
+    Valid unit can be either ``B`` or ``K`` or ``M`` for ``Bytes``, ``KBytes``
+    and ``MBytes`` respectively. For example:
+
+    Configuring ``2MB`` as a maximum size for trace output file::
+
+        --trace-bufsz=2M
+
+    By default, size of trace output file is ``1MB`` and parameter
+    must be specified once only.
+
 Other options
 ~~~~~~~~~~~~~
 
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index d71f89be2..fb07206b0 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -70,6 +70,7 @@ eal_long_options[] = {
 	{OPT_LOG_LEVEL,         1, NULL, OPT_LOG_LEVEL_NUM        },
 	{OPT_TRACE_LEVEL,       1, NULL, OPT_TRACE_LEVEL_NUM      },
 	{OPT_TRACE_DIR,         1, NULL, OPT_TRACE_DIR_NUM        },
+	{OPT_TRACE_BUF_SIZE,    1, NULL, OPT_TRACE_BUF_SIZE_NUM   },
 	{OPT_MASTER_LCORE,      1, NULL, OPT_MASTER_LCORE_NUM     },
 	{OPT_MBUF_POOL_OPS_NAME, 1, NULL, OPT_MBUF_POOL_OPS_NAME_NUM},
 	{OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
@@ -1440,6 +1441,15 @@ eal_parse_common_option(int opt, const char *optarg,
 		break;
 	}
 
+	case OPT_TRACE_BUF_SIZE_NUM: {
+		if (eal_trace_bufsz_args_save(optarg) < 0) {
+			RTE_LOG(ERR, EAL, "invalid parameters for --"
+				OPT_TRACE_BUF_SIZE "\n");
+			return -1;
+		}
+		break;
+	}
+
 	case OPT_LCORES_NUM:
 		if (eal_parse_lcores(optarg) < 0) {
 			RTE_LOG(ERR, EAL, "invalid parameter for --"
@@ -1725,6 +1735,13 @@ eal_common_usage(void)
 	       "                    By default, trace output will created at\n"
 	       "                    HOME directory and parameter must be\n"
 	       "                    specified once only\n"
+	       "  --"OPT_TRACE_BUF_SIZE"=<int>\n"
+	       "                    Specify maximum size of allocated memory\n"
+	       "                    for trace output for each thread. Valid\n"
+	       "                    unit can be either 'B|K|M' for 'Bytes',\n"
+	       "                    'KBytes' and 'MBytes' respectively.\n"
+	       "                    Default is 1MB and parameter must be\n"
+	       "                    specified once only\n"
 	       "  -v                  Display version information on startup\n"
 	       "  -h, --help          This help\n"
 	       "  --"OPT_IN_MEMORY"   Operate entirely in memory. This will\n"
diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index 697cdbcf3..a6271d984 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -64,6 +64,9 @@ eal_trace_init(void)
 	/* Generate UUID ver 4 with total size of events and number of events */
 	trace_uuid_generate();
 
+	/* Apply buffer size configuration for trace output */
+	trace_bufsz_args_apply();
+
 	/* Generate CTF TDSL metadata */
 	if (trace_metadata_create())
 		goto fail;
diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
index 013415ba2..a45e731b2 100644
--- a/lib/librte_eal/common/eal_common_trace_utils.c
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -238,6 +238,36 @@ trace_level_args_apply(const char *arg)
 	return -1;
 }
 
+int
+eal_trace_bufsz_args_save(char const *optarg)
+{
+	struct trace *trace = trace_obj_get();
+	uint64_t bufsz;
+
+	if (optarg == NULL) {
+		trace_err("no optarg is passed\n");
+		return -EINVAL;
+	}
+
+	bufsz = rte_str_to_size(optarg);
+	if (bufsz == 0) {
+		trace_err("buffer size cannot be zero\n");
+		return -EINVAL;
+	}
+
+	trace->buff_len = bufsz;
+	return 0;
+}
+
+void
+trace_bufsz_args_apply(void)
+{
+	struct trace *trace = trace_obj_get();
+
+	if (trace->buff_len == 0)
+		trace->buff_len = 1024 * 1024; /* 1MB */
+}
+
 int
 eal_trace_dir_args_save(char const *optarg)
 {
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index 8c8283165..cc7e0ea70 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -37,6 +37,8 @@ enum {
 	OPT_TRACE_LEVEL_NUM,
 #define OPT_TRACE_DIR         "trace-dir"
 	OPT_TRACE_DIR_NUM,
+#define OPT_TRACE_BUF_SIZE    "trace-bufsz"
+	OPT_TRACE_BUF_SIZE_NUM,
 #define OPT_MASTER_LCORE      "master-lcore"
 	OPT_MASTER_LCORE_NUM,
 #define OPT_MBUF_POOL_OPS_NAME "mbuf-pool-ops-name"
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index e1754de63..11e5cc16f 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -101,6 +101,7 @@ struct trace_point_head *trace_list_head_get(void);
 const char *trace_mode_to_string(enum rte_trace_mode_e mode);
 const char *trace_area_to_string(enum trace_area_e area);
 int trace_level_args_apply(const char *arg);
+void trace_bufsz_args_apply(void);
 bool trace_has_duplicate_entry(void);
 void trace_uuid_generate(void);
 int trace_metadata_create(void);
@@ -115,5 +116,6 @@ void eal_trace_fini(void);
 int eal_trace_level_args_save(const char *optarg);
 void eal_trace_level_args_free(void);
 int eal_trace_dir_args_save(const char *optarg);
+int eal_trace_bufsz_args_save(const char *optarg);
 
 #endif /* __EAL_TRACE_H */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 25/32] eal/trace: add trace mode configuration parameter
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (23 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 24/32] eal/trace: add trace bufsize " jerinj
@ 2020-03-18 19:02 ` " jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 26/32] eal/trace: add unit test cases jerinj
                   ` (7 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: John McNamara, Marko Kovacevic, Jerin Jacob, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

From: Sunil Kumar Kori <skori@marvell.com>

Trace library exposes --trace-mode eal parameter to configure
event record mode when ring buffers are full.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 doc/guides/linux_gsg/eal_args.include.rst     | 12 ++++++
 lib/librte_eal/common/eal_common_options.c    | 17 ++++++++
 .../common/eal_common_trace_utils.c           | 40 +++++++++++++++++++
 lib/librte_eal/common/eal_options.h           |  2 +
 lib/librte_eal/common/eal_trace.h             |  1 +
 5 files changed, 72 insertions(+)

diff --git a/doc/guides/linux_gsg/eal_args.include.rst b/doc/guides/linux_gsg/eal_args.include.rst
index cc9fc0255..51d6670f4 100644
--- a/doc/guides/linux_gsg/eal_args.include.rst
+++ b/doc/guides/linux_gsg/eal_args.include.rst
@@ -179,6 +179,18 @@ Debugging options
     By default, size of trace output file is ``1MB`` and parameter
     must be specified once only.
 
+*   ``--trace-mode=<o[verwrite] | d[iscard] >``
+
+    Specify the mode of update of trace output file. Either update on a file
+    can be wrapped or discarded when file size reaches its maximum limit.
+    For example:
+
+    To ``discard`` update on trace output file::
+
+        --trace-mode=d or --trace-mode=discard
+
+    Default mode is ``overwrite`` and parameter must be specified once only.
+
 Other options
 ~~~~~~~~~~~~~
 
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index fb07206b0..902bd1527 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -71,6 +71,7 @@ eal_long_options[] = {
 	{OPT_TRACE_LEVEL,       1, NULL, OPT_TRACE_LEVEL_NUM      },
 	{OPT_TRACE_DIR,         1, NULL, OPT_TRACE_DIR_NUM        },
 	{OPT_TRACE_BUF_SIZE,    1, NULL, OPT_TRACE_BUF_SIZE_NUM   },
+	{OPT_TRACE_MODE,        1, NULL, OPT_TRACE_MODE_NUM       },
 	{OPT_MASTER_LCORE,      1, NULL, OPT_MASTER_LCORE_NUM     },
 	{OPT_MBUF_POOL_OPS_NAME, 1, NULL, OPT_MBUF_POOL_OPS_NAME_NUM},
 	{OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
@@ -1450,6 +1451,15 @@ eal_parse_common_option(int opt, const char *optarg,
 		break;
 	}
 
+	case OPT_TRACE_MODE_NUM: {
+		if (eal_trace_mode_args_save(optarg) < 0) {
+			RTE_LOG(ERR, EAL, "invalid parameters for --"
+				OPT_TRACE_MODE "\n");
+			return -1;
+		}
+		break;
+	}
+
 	case OPT_LCORES_NUM:
 		if (eal_parse_lcores(optarg) < 0) {
 			RTE_LOG(ERR, EAL, "invalid parameter for --"
@@ -1742,6 +1752,13 @@ eal_common_usage(void)
 	       "                    'KBytes' and 'MBytes' respectively.\n"
 	       "                    Default is 1MB and parameter must be\n"
 	       "                    specified once only\n"
+	       "  --"OPT_TRACE_MODE"=<o[verwrite] | d[iscard]>\n"
+	       "                    Specify the mode of update of trace\n"
+	       "                    output file. Either update on a file can\n"
+	       "                    be wrapped or discarded when file size\n"
+	       "                    reaches its maximum limit.\n"
+	       "                    Default mode is 'overwrite' and parameter\n"
+	       "                    must be specified once only\n"
 	       "  -v                  Display version information on startup\n"
 	       "  -h, --help          This help\n"
 	       "  --"OPT_IN_MEMORY"   Operate entirely in memory. This will\n"
diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
index a45e731b2..3e8aa5629 100644
--- a/lib/librte_eal/common/eal_common_trace_utils.c
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -268,6 +268,46 @@ trace_bufsz_args_apply(void)
 		trace->buff_len = 1024 * 1024; /* 1MB */
 }
 
+int
+eal_trace_mode_args_save(const char *optarg)
+{
+	struct trace *trace = trace_obj_get();
+	size_t len = strlen(optarg);
+	unsigned long tmp;
+	char *pattern;
+
+	if (optarg == NULL) {
+		trace_err("no optarg is passed\n");
+		return -EINVAL;
+	}
+
+	if (len == 0) {
+		trace_err("value is not provided with option\n");
+		return -EINVAL;
+	}
+
+	pattern = (char *)calloc(1, len + 2);
+	if (pattern == NULL) {
+		trace_err("fail to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	sprintf(pattern, "%s*", optarg);
+
+	if (fnmatch(pattern, "overwrite", 0) == 0)
+		tmp = RTE_TRACE_MODE_OVERWRITE;
+	else if (fnmatch(pattern, "discard", 0) == 0)
+		tmp = RTE_TRACE_MODE_DISCARD;
+	else {
+		free(pattern);
+		return -EINVAL;
+	}
+
+	trace->mode = tmp;
+	free(pattern);
+	return 0;
+}
+
 int
 eal_trace_dir_args_save(char const *optarg)
 {
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index cc7e0ea70..3cddaf964 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -39,6 +39,8 @@ enum {
 	OPT_TRACE_DIR_NUM,
 #define OPT_TRACE_BUF_SIZE    "trace-bufsz"
 	OPT_TRACE_BUF_SIZE_NUM,
+#define OPT_TRACE_MODE        "trace-mode"
+	OPT_TRACE_MODE_NUM,
 #define OPT_MASTER_LCORE      "master-lcore"
 	OPT_MASTER_LCORE_NUM,
 #define OPT_MBUF_POOL_OPS_NAME "mbuf-pool-ops-name"
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index 11e5cc16f..68bcf6a3a 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -116,6 +116,7 @@ void eal_trace_fini(void);
 int eal_trace_level_args_save(const char *optarg);
 void eal_trace_level_args_free(void);
 int eal_trace_dir_args_save(const char *optarg);
+int eal_trace_mode_args_save(const char *optarg);
 int eal_trace_bufsz_args_save(const char *optarg);
 
 #endif /* __EAL_TRACE_H */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 26/32] eal/trace: add unit test cases
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (24 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 25/32] eal/trace: add trace mode " jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 27/32] eal/trace: add trace performance " jerinj
                   ` (6 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom, skori

From: Sunil Kumar Kori <skori@marvell.com>

Example commands to run UT and check the traces with babeltrace viewer.

- Delete the existing /root/dpdk-traces/ directory if needed.
> sudo rm -rf /root/dpdk-traces/

- Start the dpdk-test
> sudo ./build/app/test/dpdk-test  -c 0x3 - --trace-level=8

- Run trace_autotest
> trace_autotest

- View the traces with babletrace viewer.
> sudo babeltrace /root/dpdk-traces/

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 app/test/Makefile              |   3 +-
 app/test/meson.build           |   2 +
 app/test/test_trace.c          | 618 +++++++++++++++++++++++++++++++++
 app/test/test_trace.h          |  52 +++
 app/test/test_trace_register.c |  46 +++
 5 files changed, 720 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_trace.c
 create mode 100644 app/test/test_trace.h
 create mode 100644 app/test/test_trace_register.c

diff --git a/app/test/Makefile b/app/test/Makefile
index 1f080d162..8374c5399 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -148,7 +148,8 @@ SRCS-y += test_alarm.c
 SRCS-y += test_interrupts.c
 SRCS-y += test_version.c
 SRCS-y += test_func_reentrancy.c
-
+SRCS-y += test_trace.c
+SRCS-y += test_trace_register.c
 SRCS-y += test_service_cores.c
 
 ifeq ($(CONFIG_RTE_LIBRTE_PMD_RING),y)
diff --git a/app/test/meson.build b/app/test/meson.build
index 0a2ce710f..68c1b56df 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -121,6 +121,8 @@ test_sources = files('commands.c',
 	'test_timer_racecond.c',
 	'test_timer_secondary.c',
 	'test_ticketlock.c',
+	'test_trace.c',
+	'test_trace_register.c',
 	'test_version.c',
 	'virtual_pmd.c'
 )
diff --git a/app/test/test_trace.c b/app/test/test_trace.c
new file mode 100644
index 000000000..7065b072a
--- /dev/null
+++ b/app/test/test_trace.c
@@ -0,0 +1,618 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#include <rte_trace_eal.h>
+#include <rte_lcore.h>
+
+#include "test.h"
+#include "test_trace.h"
+
+struct tp_config {
+	int mode;
+	int level;
+	bool enabled;
+};
+
+struct trace_config {
+	uint32_t level;
+	enum rte_trace_mode_e mode;
+	struct tp_config conf[RTE_LOG_DEBUG + 1];
+};
+
+static void
+trace_config_save(struct trace_config *conf)
+{
+	/* Save global config */
+	conf->mode = rte_trace_global_mode_get();
+	conf->level = rte_trace_global_level_get();
+
+	/* Save trace specific config */
+	conf->conf[RTE_LOG_EMERG].mode =
+			rte_trace_mode_get(&__app_dpdk_test_emerg);
+	conf->conf[RTE_LOG_EMERG].level =
+			rte_trace_level_get(&__app_dpdk_test_emerg);
+	conf->conf[RTE_LOG_EMERG].enabled =
+			rte_trace_is_enabled(&__app_dpdk_test_emerg);
+
+	conf->conf[RTE_LOG_ALERT].mode =
+			rte_trace_mode_get(&__app_dpdk_test_alert);
+	conf->conf[RTE_LOG_ALERT].level =
+			rte_trace_level_get(&__app_dpdk_test_alert);
+	conf->conf[RTE_LOG_ALERT].enabled =
+			rte_trace_is_enabled(&__app_dpdk_test_alert);
+
+	conf->conf[RTE_LOG_CRIT].mode =
+			rte_trace_mode_get(&__app_dpdk_test_crit);
+	conf->conf[RTE_LOG_CRIT].level =
+			rte_trace_level_get(&__app_dpdk_test_crit);
+	conf->conf[RTE_LOG_CRIT].enabled =
+			rte_trace_is_enabled(&__app_dpdk_test_crit);
+
+	conf->conf[RTE_LOG_ERR].mode =
+			rte_trace_mode_get(&__app_dpdk_test_err);
+	conf->conf[RTE_LOG_ERR].level =
+			rte_trace_level_get(&__app_dpdk_test_err);
+	conf->conf[RTE_LOG_ERR].enabled =
+			rte_trace_is_enabled(&__app_dpdk_test_err);
+
+	conf->conf[RTE_LOG_WARNING].mode =
+			rte_trace_mode_get(&__app_dpdk_test_warning);
+	conf->conf[RTE_LOG_WARNING].level =
+			rte_trace_level_get(&__app_dpdk_test_warning);
+	conf->conf[RTE_LOG_WARNING].enabled =
+			rte_trace_is_enabled(&__app_dpdk_test_warning);
+
+	conf->conf[RTE_LOG_NOTICE].mode =
+			rte_trace_mode_get(&__app_dpdk_test_notice);
+	conf->conf[RTE_LOG_NOTICE].level =
+			rte_trace_level_get(&__app_dpdk_test_notice);
+	conf->conf[RTE_LOG_NOTICE].enabled =
+			rte_trace_is_enabled(&__app_dpdk_test_notice);
+
+	conf->conf[RTE_LOG_INFO].mode =
+			rte_trace_mode_get(&__app_dpdk_test_info);
+	conf->conf[RTE_LOG_INFO].level =
+			rte_trace_level_get(&__app_dpdk_test_info);
+	conf->conf[RTE_LOG_INFO].enabled =
+			rte_trace_is_enabled(&__app_dpdk_test_info);
+
+	conf->conf[RTE_LOG_DEBUG].mode =
+			rte_trace_mode_get(&__app_dpdk_test_debug);
+	conf->conf[RTE_LOG_DEBUG].level =
+			rte_trace_level_get(&__app_dpdk_test_debug);
+	conf->conf[RTE_LOG_DEBUG].enabled =
+			rte_trace_is_enabled(&__app_dpdk_test_debug);
+}
+
+static void
+trace_config_restore(struct trace_config *conf)
+{
+	/* Restore global config */
+	rte_trace_global_mode_set(conf->mode);
+	rte_trace_global_level_set(conf->level);
+
+	/* Restore trace specific config */
+	rte_trace_mode_set(&__app_dpdk_test_emerg,
+			   conf->conf[RTE_LOG_EMERG].mode);
+	rte_trace_level_set(&__app_dpdk_test_emerg,
+			    conf->conf[RTE_LOG_EMERG].level);
+	if (conf->conf[RTE_LOG_EMERG].enabled)
+		rte_trace_enable(&__app_dpdk_test_emerg);
+	else
+		rte_trace_disable(&__app_dpdk_test_emerg);
+
+	rte_trace_mode_set(&__app_dpdk_test_alert,
+			   conf->conf[RTE_LOG_ALERT].mode);
+	rte_trace_level_set(&__app_dpdk_test_alert,
+			    conf->conf[RTE_LOG_ALERT].level);
+	if (conf->conf[RTE_LOG_ALERT].enabled)
+		rte_trace_enable(&__app_dpdk_test_alert);
+	else
+		rte_trace_disable(&__app_dpdk_test_alert);
+
+	rte_trace_mode_set(&__app_dpdk_test_crit,
+			   conf->conf[RTE_LOG_CRIT].mode);
+	rte_trace_level_set(&__app_dpdk_test_crit,
+			    conf->conf[RTE_LOG_CRIT].level);
+	if (conf->conf[RTE_LOG_CRIT].enabled)
+		rte_trace_enable(&__app_dpdk_test_crit);
+	else
+		rte_trace_disable(&__app_dpdk_test_crit);
+
+	rte_trace_mode_set(&__app_dpdk_test_err,
+			   conf->conf[RTE_LOG_ERR].mode);
+	rte_trace_level_set(&__app_dpdk_test_err,
+			    conf->conf[RTE_LOG_ERR].level);
+	if (conf->conf[RTE_LOG_ERR].enabled)
+		rte_trace_enable(&__app_dpdk_test_err);
+	else
+		rte_trace_disable(&__app_dpdk_test_err);
+
+	rte_trace_mode_set(&__app_dpdk_test_warning,
+			   conf->conf[RTE_LOG_WARNING].mode);
+	rte_trace_level_set(&__app_dpdk_test_warning,
+			    conf->conf[RTE_LOG_WARNING].level);
+	if (conf->conf[RTE_LOG_WARNING].enabled)
+		rte_trace_enable(&__app_dpdk_test_warning);
+	else
+		rte_trace_disable(&__app_dpdk_test_warning);
+
+	rte_trace_mode_set(&__app_dpdk_test_notice,
+			   conf->conf[RTE_LOG_NOTICE].mode);
+	rte_trace_level_set(&__app_dpdk_test_notice,
+			    conf->conf[RTE_LOG_NOTICE].level);
+	if (conf->conf[RTE_LOG_NOTICE].enabled)
+		rte_trace_enable(&__app_dpdk_test_notice);
+	else
+		rte_trace_disable(&__app_dpdk_test_notice);
+
+	rte_trace_mode_set(&__app_dpdk_test_info,
+			   conf->conf[RTE_LOG_INFO].mode);
+	rte_trace_level_set(&__app_dpdk_test_info,
+			    conf->conf[RTE_LOG_INFO].level);
+	if (conf->conf[RTE_LOG_INFO].enabled)
+		rte_trace_enable(&__app_dpdk_test_info);
+	else
+		rte_trace_disable(&__app_dpdk_test_info);
+
+	rte_trace_mode_set(&__app_dpdk_test_debug,
+			   conf->conf[RTE_LOG_DEBUG].mode);
+	rte_trace_level_set(&__app_dpdk_test_debug,
+			    conf->conf[RTE_LOG_DEBUG].level);
+	if (conf->conf[RTE_LOG_DEBUG].enabled)
+		rte_trace_enable(&__app_dpdk_test_debug);
+	else
+		rte_trace_disable(&__app_dpdk_test_debug);
+}
+
+static void
+emit_trace_points(void)
+{
+	app_dpdk_test_emerg("app.dpdk.test.emerg");
+	app_dpdk_test_alert("app.dpdk.test.alert");
+	app_dpdk_test_crit("app.dpdk.test.crit");
+	app_dpdk_test_err("app.dpdk.test.err");
+	app_dpdk_test_warning("app.dpdk.test.warning");
+	app_dpdk_test_notice("app.dpdk.test.notice");
+	app_dpdk_test_info("app.dpdk.test.info");
+	app_dpdk_test_debug("app.dpdk.test.debug");
+}
+
+static int32_t
+enable_trace_points(void)
+{
+	int rc;
+
+	rc = rte_trace_enable(&__app_dpdk_test_emerg);
+	if (rc < 0 && rc != -EACCES)
+		goto failed;
+
+	rc = rte_trace_enable(&__app_dpdk_test_alert);
+	if (rc < 0 && rc != -EACCES)
+		goto failed;
+
+	rc = rte_trace_enable(&__app_dpdk_test_crit);
+	if (rc < 0 && rc != -EACCES)
+		goto failed;
+
+	rc = rte_trace_enable(&__app_dpdk_test_err);
+	if (rc < 0 && rc != -EACCES)
+		goto failed;
+
+	rc = rte_trace_enable(&__app_dpdk_test_warning);
+	if (rc < 0 && rc != -EACCES)
+		goto failed;
+
+	rc = rte_trace_enable(&__app_dpdk_test_notice);
+	if (rc < 0 && rc != -EACCES)
+		goto failed;
+
+	rc = rte_trace_enable(&__app_dpdk_test_info);
+	if (rc < 0 && rc != -EACCES)
+		goto failed;
+
+	rc = rte_trace_enable(&__app_dpdk_test_debug);
+	if (rc < 0 && rc != -EACCES)
+		goto failed;
+
+	return 0;
+
+failed:
+	return rc;
+}
+
+static int32_t
+disable_trace_points(void)
+{
+	int rc;
+
+	rc = rte_trace_disable(&__app_dpdk_test_emerg);
+	if (rc < 0)
+		goto failed;
+
+	rc = rte_trace_disable(&__app_dpdk_test_alert);
+	if (rc < 0)
+		goto failed;
+
+	rc = rte_trace_disable(&__app_dpdk_test_crit);
+	if (rc < 0)
+		goto failed;
+
+	rc = rte_trace_disable(&__app_dpdk_test_err);
+	if (rc < 0)
+		goto failed;
+
+	rc = rte_trace_disable(&__app_dpdk_test_warning);
+	if (rc < 0)
+		goto failed;
+
+	rc = rte_trace_disable(&__app_dpdk_test_notice);
+	if (rc < 0)
+		goto failed;
+
+	rc = rte_trace_disable(&__app_dpdk_test_info);
+	if (rc < 0)
+		goto failed;
+
+	rc = rte_trace_disable(&__app_dpdk_test_debug);
+	if (rc < 0)
+		goto failed;
+
+	return 0;
+
+failed:
+	return rc;
+}
+
+static int32_t
+reverse_trace_points_mode(void)
+{
+	enum rte_trace_mode_e mode[] = {RTE_TRACE_MODE_DISCARD,
+					RTE_TRACE_MODE_OVERWRITE};
+	uint32_t trace_mode;
+	int rc = -1;
+
+	trace_mode = rte_trace_mode_get(&__app_dpdk_test_emerg);
+	if (trace_mode == RTE_TRACE_MODE_DISCARD ||
+	    trace_mode == RTE_TRACE_MODE_OVERWRITE) {
+		rc = rte_trace_mode_set(&__app_dpdk_test_emerg,
+					mode[trace_mode]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_mode = rte_trace_mode_get(&__app_dpdk_test_alert);
+	if (trace_mode == RTE_TRACE_MODE_DISCARD ||
+	    trace_mode == RTE_TRACE_MODE_OVERWRITE) {
+		rc = rte_trace_mode_set(&__app_dpdk_test_alert,
+					mode[trace_mode]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_mode = rte_trace_mode_get(&__app_dpdk_test_crit);
+	if (trace_mode == RTE_TRACE_MODE_DISCARD ||
+	    trace_mode == RTE_TRACE_MODE_OVERWRITE) {
+		rc = rte_trace_mode_set(&__app_dpdk_test_crit,
+					mode[trace_mode]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_mode = rte_trace_mode_get(&__app_dpdk_test_err);
+	if (trace_mode == RTE_TRACE_MODE_DISCARD ||
+	    trace_mode == RTE_TRACE_MODE_OVERWRITE) {
+		rc = rte_trace_mode_set(&__app_dpdk_test_err,
+					mode[trace_mode]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_mode = rte_trace_mode_get(&__app_dpdk_test_warning);
+	if (trace_mode == RTE_TRACE_MODE_DISCARD ||
+	    trace_mode == RTE_TRACE_MODE_OVERWRITE) {
+		rc = rte_trace_mode_set(&__app_dpdk_test_warning,
+					mode[trace_mode]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_mode = rte_trace_mode_get(&__app_dpdk_test_notice);
+	if (trace_mode == RTE_TRACE_MODE_DISCARD ||
+	    trace_mode == RTE_TRACE_MODE_OVERWRITE) {
+		rc = rte_trace_mode_set(&__app_dpdk_test_notice,
+					mode[trace_mode]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_mode = rte_trace_mode_get(&__app_dpdk_test_info);
+	if (trace_mode == RTE_TRACE_MODE_DISCARD ||
+	    trace_mode == RTE_TRACE_MODE_OVERWRITE) {
+		rc = rte_trace_mode_set(&__app_dpdk_test_info,
+					mode[trace_mode]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_mode = rte_trace_mode_get(&__app_dpdk_test_debug);
+	if (trace_mode == RTE_TRACE_MODE_DISCARD ||
+	    trace_mode == RTE_TRACE_MODE_OVERWRITE) {
+		rc = rte_trace_mode_set(&__app_dpdk_test_debug,
+					mode[trace_mode]);
+		if (rc < 0)
+			goto failed;
+	}
+
+failed:
+	return rc;
+}
+
+static int32_t
+reverse_trace_points_level(void)
+{
+	uint32_t level[] = {0, RTE_LOG_DEBUG, RTE_LOG_INFO, RTE_LOG_NOTICE,
+			    RTE_LOG_WARNING, RTE_LOG_ERR, RTE_LOG_CRIT,
+			    RTE_LOG_ALERT, RTE_LOG_EMERG, 0};
+	uint32_t trace_level;
+	int rc = -1;
+
+	trace_level = rte_trace_level_get(&__app_dpdk_test_emerg);
+	if (trace_level >= RTE_LOG_EMERG && trace_level <= RTE_LOG_DEBUG) {
+		rc = rte_trace_level_set(&__app_dpdk_test_emerg,
+					 level[trace_level]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_level = rte_trace_level_get(&__app_dpdk_test_alert);
+	if (trace_level >= RTE_LOG_EMERG && trace_level <= RTE_LOG_DEBUG) {
+		rc = rte_trace_level_set(&__app_dpdk_test_alert,
+					 level[trace_level]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_level = rte_trace_level_get(&__app_dpdk_test_crit);
+	if (trace_level >= RTE_LOG_EMERG && trace_level <= RTE_LOG_DEBUG) {
+		rc = rte_trace_level_set(&__app_dpdk_test_crit,
+					 level[trace_level]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_level = rte_trace_level_get(&__app_dpdk_test_err);
+	if (trace_level >= RTE_LOG_EMERG && trace_level <= RTE_LOG_DEBUG) {
+		rc = rte_trace_level_set(&__app_dpdk_test_err,
+					 level[trace_level]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_level = rte_trace_level_get(&__app_dpdk_test_warning);
+	if (trace_level >= RTE_LOG_EMERG && trace_level <= RTE_LOG_DEBUG) {
+		rc = rte_trace_level_set(&__app_dpdk_test_warning,
+					 level[trace_level]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_level = rte_trace_level_get(&__app_dpdk_test_notice);
+	if (trace_level >= RTE_LOG_EMERG && trace_level <= RTE_LOG_DEBUG) {
+		rc = rte_trace_level_set(&__app_dpdk_test_notice,
+					 level[trace_level]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_level = rte_trace_level_get(&__app_dpdk_test_info);
+	if (trace_level >= RTE_LOG_EMERG && trace_level <= RTE_LOG_DEBUG) {
+		rc = rte_trace_level_set(&__app_dpdk_test_info,
+					 level[trace_level]);
+		if (rc < 0)
+			goto failed;
+	}
+
+	trace_level = rte_trace_level_get(&__app_dpdk_test_debug);
+	if (trace_level >= RTE_LOG_EMERG && trace_level <= RTE_LOG_DEBUG) {
+		rc = rte_trace_level_set(&__app_dpdk_test_debug,
+					 level[trace_level]);
+		if (rc < 0)
+			goto failed;
+	}
+
+failed:
+	return rc;
+}
+
+static int
+test_trace_level(void)
+{
+	if (enable_trace_points() < 0)
+		goto failed;
+
+	emit_trace_points();
+
+	if (reverse_trace_points_level() < 0)
+		goto failed;
+
+	emit_trace_points();
+
+	return 0;
+
+failed:
+	return -1;
+}
+
+static int32_t
+test_trace_points_enable_disable(void)
+{
+	struct trace_config conf;
+	int rc;
+
+	trace_config_save(&conf);
+
+	if (enable_trace_points() < 0)
+		goto failed;
+
+	if (disable_trace_points() < 0)
+		goto failed;
+
+	rc = rte_trace_pattern("app.dpdk.test*", true, NULL);
+	if (rc < 0 && rc != -EACCES)
+		goto failed;
+
+	rc = rte_trace_pattern("app.dpdk.test*", false, NULL);
+	if (rc < 0 && rc != -EACCES)
+		goto failed;
+
+	rc = rte_trace_regexp("app.dpdk.test", true, NULL);
+	if (rc < 0 && rc != -EACCES)
+		goto failed;
+
+	rc = rte_trace_regexp("app.dpdk.test", false, NULL);
+	if (rc < 0 && rc != -EACCES)
+		goto failed;
+
+	trace_config_restore(&conf);
+	test_trace_level();
+	trace_config_restore(&conf);
+
+	return TEST_SUCCESS;
+
+failed:
+	return TEST_FAILED;
+}
+
+static int32_t
+test_trace_points_level_get_set(void)
+{
+	uint32_t level[] = {0, RTE_LOG_DEBUG, RTE_LOG_INFO, RTE_LOG_NOTICE,
+			    RTE_LOG_WARNING, RTE_LOG_ERR, RTE_LOG_CRIT,
+			    RTE_LOG_ALERT, RTE_LOG_EMERG, 0};
+	struct trace_config conf;
+	uint32_t g_level;
+
+	trace_config_save(&conf);
+
+	/* Validate global trace level */
+	g_level = rte_trace_global_level_get();
+	if (g_level >= RTE_LOG_EMERG && g_level <= RTE_LOG_DEBUG)
+		rte_trace_global_level_set(level[g_level]);
+
+	if (reverse_trace_points_level() < 0)
+		return TEST_FAILED;
+
+	trace_config_restore(&conf);
+	return TEST_SUCCESS;
+}
+
+static int32_t
+test_trace_points_mode_get_set(void)
+{
+	enum rte_trace_mode_e mode[] = {RTE_TRACE_MODE_DISCARD,
+					RTE_TRACE_MODE_OVERWRITE};
+	struct trace_config conf;
+	uint32_t g_mode;
+
+	trace_config_save(&conf);
+	emit_trace_points();
+
+	/* Validate global trace mode */
+	g_mode = rte_trace_global_mode_get();
+	if (g_mode == RTE_TRACE_MODE_DISCARD ||
+	    g_mode == RTE_TRACE_MODE_OVERWRITE)
+		rte_trace_global_mode_set(mode[g_mode]);
+
+	emit_trace_points();
+
+	if (reverse_trace_points_mode() < 0)
+		return TEST_FAILED;
+
+	emit_trace_points();
+
+	trace_config_restore(&conf);
+	return TEST_SUCCESS;
+}
+
+static int
+test_trace_points_lookup(void)
+{
+	rte_trace_t trace;
+
+	trace =  rte_trace_from_name("app.dpdk.test.emerg");
+	if (trace == NULL)
+		goto fail;
+	trace = rte_trace_from_name("this_trace_point_does_not_exist");
+	if (trace != NULL)
+		goto fail;
+
+	return TEST_SUCCESS;
+fail:
+	return TEST_FAILED;
+}
+
+static int
+test_generic_trace_points(void)
+{
+	int tmp;
+
+	rte_trace_lib_eal_generic_void();
+	rte_trace_lib_eal_generic_u64(0x10000000000000);
+	rte_trace_lib_eal_generic_u32(0x10000000);
+	rte_trace_lib_eal_generic_u16(0xffee);
+	rte_trace_lib_eal_generic_u8(0xc);
+	rte_trace_lib_eal_generic_i64(-1234);
+	rte_trace_lib_eal_generic_i32(-1234567);
+	rte_trace_lib_eal_generic_i16(12);
+	rte_trace_lib_eal_generic_i8(-3);
+	rte_trace_lib_eal_generic_int(3333333);
+	rte_trace_lib_eal_generic_long(333);
+	rte_trace_lib_eal_generic_float(20.45);
+	rte_trace_lib_eal_generic_double(20000.5000004);
+	rte_trace_lib_eal_generic_ptr(&tmp);
+	rte_trace_lib_eal_generic_str("my string");
+	RTE_TRACE_LIB_EAL_GENERIC_FUNC;
+
+	return TEST_SUCCESS;
+}
+
+static struct unit_test_suite trace_tests = {
+	.suite_name = "trace autotest",
+	.setup = NULL,
+	.teardown = NULL,
+	.unit_test_cases = {
+		TEST_CASE(test_generic_trace_points),
+		TEST_CASE(test_trace_points_enable_disable),
+		TEST_CASE(test_trace_points_level_get_set),
+		TEST_CASE(test_trace_points_mode_get_set),
+		TEST_CASE(test_trace_points_lookup),
+		TEST_CASES_END()
+	}
+};
+
+static int
+test_trace(void)
+{
+	return unit_test_suite_runner(&trace_tests);
+}
+
+REGISTER_TEST_COMMAND(trace_autotest, test_trace);
+
+static int
+test_trace_dump(void)
+{
+	rte_trace_dump(stdout);
+	return 0;
+}
+
+REGISTER_TEST_COMMAND(trace_dump, test_trace_dump);
+
+static int
+test_trace_metadata_dump(void)
+{
+	return rte_trace_metadata_dump(stdout);
+}
+
+REGISTER_TEST_COMMAND(trace_metadata_dump, test_trace_metadata_dump);
diff --git a/app/test/test_trace.h b/app/test/test_trace.h
new file mode 100644
index 000000000..fc1310c73
--- /dev/null
+++ b/app/test/test_trace.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+#include <rte_trace.h>
+
+RTE_TRACE_POINT(
+	app_dpdk_test_emerg,
+	RTE_TRACE_POINT_ARGS(const char *str),
+	rte_trace_ctf_string(str);
+)
+
+RTE_TRACE_POINT(
+	app_dpdk_test_alert,
+	RTE_TRACE_POINT_ARGS(const char *str),
+	rte_trace_ctf_string(str);
+)
+
+RTE_TRACE_POINT(
+	app_dpdk_test_crit,
+	RTE_TRACE_POINT_ARGS(const char *str),
+	rte_trace_ctf_string(str);
+)
+
+RTE_TRACE_POINT(
+	app_dpdk_test_err,
+	RTE_TRACE_POINT_ARGS(const char *str),
+	rte_trace_ctf_string(str);
+)
+
+RTE_TRACE_POINT(
+	app_dpdk_test_warning,
+	RTE_TRACE_POINT_ARGS(const char *str),
+	rte_trace_ctf_string(str);
+)
+
+RTE_TRACE_POINT(
+	app_dpdk_test_notice,
+	RTE_TRACE_POINT_ARGS(const char *str),
+	rte_trace_ctf_string(str);
+)
+
+RTE_TRACE_POINT(
+	app_dpdk_test_info,
+	RTE_TRACE_POINT_ARGS(const char *str),
+	rte_trace_ctf_string(str);
+)
+
+RTE_TRACE_POINT(
+	app_dpdk_test_debug,
+	RTE_TRACE_POINT_ARGS(const char *str),
+	rte_trace_ctf_string(str);
+)
diff --git a/app/test/test_trace_register.c b/app/test/test_trace_register.c
new file mode 100644
index 000000000..8fb6bf6e1
--- /dev/null
+++ b/app/test/test_trace_register.c
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+#define RTE_TRACE_POINT_REGISTER_SELECT /* Select trace point register macros */
+
+#include <rte_trace.h>
+
+#include "test_trace.h"
+
+/* Define trace points */
+RTE_TRACE_POINT_DEFINE(app_dpdk_test_emerg);
+RTE_TRACE_POINT_DEFINE(app_dpdk_test_alert);
+RTE_TRACE_POINT_DEFINE(app_dpdk_test_crit);
+RTE_TRACE_POINT_DEFINE(app_dpdk_test_err);
+RTE_TRACE_POINT_DEFINE(app_dpdk_test_warning);
+RTE_TRACE_POINT_DEFINE(app_dpdk_test_notice);
+RTE_TRACE_POINT_DEFINE(app_dpdk_test_info);
+RTE_TRACE_POINT_DEFINE(app_dpdk_test_debug);
+
+RTE_INIT(register_valid_trace_points)
+{
+	RTE_TRACE_POINT_REGISTER(app_dpdk_test_emerg,
+				 app.dpdk.test.emerg, EMERG);
+
+	RTE_TRACE_POINT_REGISTER(app_dpdk_test_alert,
+				 app.dpdk.test.alert, ALERT);
+
+	RTE_TRACE_POINT_REGISTER(app_dpdk_test_crit,
+				 app.dpdk.test.crit, CRIT);
+
+	RTE_TRACE_POINT_REGISTER(app_dpdk_test_err,
+				 app.dpdk.test.err, ERR);
+
+	RTE_TRACE_POINT_REGISTER(app_dpdk_test_warning,
+				 app.dpdk.test.warning, WARNING);
+
+	RTE_TRACE_POINT_REGISTER(app_dpdk_test_notice,
+				 app.dpdk.test.notice, NOTICE);
+
+	RTE_TRACE_POINT_REGISTER(app_dpdk_test_info,
+				 app.dpdk.test.info, INFO);
+
+	RTE_TRACE_POINT_REGISTER(app_dpdk_test_debug,
+				 app.dpdk.test.debug, DEBUG);
+}
+
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v1 27/32] eal/trace: add trace performance test cases
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (25 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 26/32] eal/trace: add unit test cases jerinj
@ 2020-03-18 19:02 ` " jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 28/32] ethdev: add tracepoints jerinj
                   ` (5 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

This test case shall be used to measure the trace overhead.

Example command to run the performance test case.

echo "trace_perf" | ./build/app/test/dpdk-test -c 0x3 --trace-level=8

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 app/test/Makefile          |   1 +
 app/test/meson.build       |   1 +
 app/test/test_trace_perf.c | 179 +++++++++++++++++++++++++++++++++++++
 3 files changed, 181 insertions(+)
 create mode 100644 app/test/test_trace_perf.c

diff --git a/app/test/Makefile b/app/test/Makefile
index 8374c5399..1bd00ca9e 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -150,6 +150,7 @@ SRCS-y += test_version.c
 SRCS-y += test_func_reentrancy.c
 SRCS-y += test_trace.c
 SRCS-y += test_trace_register.c
+SRCS-y += test_trace_perf.c
 SRCS-y += test_service_cores.c
 
 ifeq ($(CONFIG_RTE_LIBRTE_PMD_RING),y)
diff --git a/app/test/meson.build b/app/test/meson.build
index 68c1b56df..fef37d7e2 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -123,6 +123,7 @@ test_sources = files('commands.c',
 	'test_ticketlock.c',
 	'test_trace.c',
 	'test_trace_register.c',
+	'test_trace_perf.c',
 	'test_version.c',
 	'virtual_pmd.c'
 )
diff --git a/app/test/test_trace_perf.c b/app/test/test_trace_perf.c
new file mode 100644
index 000000000..d0f291771
--- /dev/null
+++ b/app/test/test_trace_perf.c
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#include <rte_cycles.h>
+#include <rte_debug.h>
+#include <rte_eal.h>
+#include <rte_malloc.h>
+#include <rte_lcore.h>
+#include <rte_trace_eal.h>
+
+#include "test.h"
+
+struct test_data;
+
+struct lcore_data {
+	volatile bool done;
+	volatile bool started;
+	uint64_t total_cycles;
+	uint64_t total_calls;
+} __rte_cache_aligned;
+
+struct test_data {
+	unsigned int nb_workers;
+	struct lcore_data ldata[];
+} __rte_cache_aligned;
+
+#define STEP 100
+#define CENT_OPS(OP) do {     \
+OP; OP; OP; OP; OP; OP; OP; OP; OP; OP;\
+OP; OP; OP; OP; OP; OP; OP; OP; OP; OP;\
+OP; OP; OP; OP; OP; OP; OP; OP; OP; OP;\
+OP; OP; OP; OP; OP; OP; OP; OP; OP; OP;\
+OP; OP; OP; OP; OP; OP; OP; OP; OP; OP;\
+OP; OP; OP; OP; OP; OP; OP; OP; OP; OP;\
+OP; OP; OP; OP; OP; OP; OP; OP; OP; OP;\
+OP; OP; OP; OP; OP; OP; OP; OP; OP; OP;\
+OP; OP; OP; OP; OP; OP; OP; OP; OP; OP;\
+OP; OP; OP; OP; OP; OP; OP; OP; OP; OP;\
+} while (0)
+
+static void
+measure_perf(const char *str, struct test_data *data)
+{
+	uint64_t hz = rte_get_timer_hz();
+	uint64_t total_cycles = 0;
+	uint64_t total_calls = 0;
+	double cycles, ns;
+	unsigned int workers;
+
+	for (workers = 0; workers < data->nb_workers; workers++) {
+		total_cycles += data->ldata[workers].total_cycles;
+		total_calls += data->ldata[workers].total_calls;
+	}
+
+	cycles = total_calls ? (double)total_cycles / (double)total_calls : 0;
+	cycles /= STEP;
+	cycles /= 100; /* CENT_OPS */
+
+	ns = (cycles / (double)hz) * 1E9;
+	printf("%16s: cycles=%f ns=%f\n", str, cycles, ns);
+}
+
+static void
+wait_till_workers_are_ready(struct test_data *data)
+{
+	unsigned int workers;
+
+	for (workers = 0; workers < data->nb_workers; workers++)
+		while (!data->ldata[workers].started)
+			rte_pause();
+}
+
+static void
+signal_workers_to_finish(struct test_data *data)
+{
+	unsigned int workers;
+
+	for (workers = 0; workers < data->nb_workers; workers++) {
+		data->ldata[workers].done = 1;
+		rte_smp_wmb();
+	}
+}
+
+#define WORKER_DEFINE(func)\
+static void __rte_noinline \
+__worker_##func(struct lcore_data *ldata)\
+{\
+	uint64_t start;\
+	int i;\
+	while (!ldata->done) {\
+		start = rte_get_timer_cycles();\
+		for (i = 0; i < STEP; i++)\
+			CENT_OPS(func);\
+		ldata->total_cycles += rte_get_timer_cycles() - start;\
+		ldata->total_calls++;\
+	} \
+} \
+static int \
+worker_fn_##func(void *arg)\
+{\
+	struct lcore_data *ldata = arg;\
+	ldata->started = 1;\
+	rte_smp_wmb();\
+	__worker_##func(ldata);\
+	return 0;\
+}
+
+
+/* Test to find trace overhead */
+#define GENERIC_VOID rte_trace_lib_eal_generic_void()
+#define GENERIC_U64 rte_trace_lib_eal_generic_u64(0x120000)
+#define GENERIC_INT rte_trace_lib_eal_generic_int(-34)
+#define GENERIC_FLOAT rte_trace_lib_eal_generic_float(3.3f)
+#define GENERIC_DOUBLE rte_trace_lib_eal_generic_double(3.66666)
+#define GENERIC_STR rte_trace_lib_eal_generic_str("hello world")
+
+WORKER_DEFINE(GENERIC_VOID)
+WORKER_DEFINE(GENERIC_U64)
+WORKER_DEFINE(GENERIC_INT)
+WORKER_DEFINE(GENERIC_FLOAT)
+WORKER_DEFINE(GENERIC_DOUBLE)
+WORKER_DEFINE(GENERIC_STR)
+
+static void
+run_test(const char *str, lcore_function_t f, struct test_data *data, size_t sz)
+{
+	unsigned int id, worker = 0;
+
+	memset(data, 0, sz);
+	data->nb_workers = rte_lcore_count() - 1;
+	RTE_LCORE_FOREACH_SLAVE(id)
+		rte_eal_remote_launch(f, &data->ldata[worker++], id);
+
+	wait_till_workers_are_ready(data);
+	rte_delay_ms(100); /* Wait for some time to accumulate the stats */
+	measure_perf(str, data);
+	signal_workers_to_finish(data);
+
+	RTE_LCORE_FOREACH_SLAVE(id)
+		rte_eal_wait_lcore(id);
+}
+
+static int
+test_trace_perf(void)
+{
+	unsigned int nb_cores, nb_workers;
+	struct test_data *data;
+	size_t sz;
+
+	nb_cores = rte_lcore_count();
+	nb_workers = nb_cores - 1;
+	if (nb_cores < 2) {
+		printf("Need minimum two cores for testing\n");
+		return TEST_SKIPPED;
+	}
+
+	printf("Timer running at %5.2fMHz\n", rte_get_timer_hz()/1E6);
+	sz = sizeof(struct test_data);
+	sz += nb_workers * sizeof(struct lcore_data);
+
+	data = rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE);
+	if (data == NULL) {
+		printf("Failed to allocate memory\n");
+		return TEST_FAILED;
+	}
+
+	run_test("void", worker_fn_GENERIC_VOID, data, sz);
+	run_test("u64", worker_fn_GENERIC_U64, data, sz);
+	run_test("int", worker_fn_GENERIC_INT, data, sz);
+	run_test("float", worker_fn_GENERIC_FLOAT, data, sz);
+	run_test("double", worker_fn_GENERIC_DOUBLE, data, sz);
+	run_test("string", worker_fn_GENERIC_STR, data, sz);
+
+	rte_free(data);
+	return TEST_SUCCESS;
+}
+
+REGISTER_TEST_COMMAND(trace_perf, test_trace_perf);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 28/32] ethdev: add tracepoints
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (26 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 27/32] eal/trace: add trace performance " jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 29/32] eventdev: " jerinj
                   ` (4 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Thomas Monjalon, Reshma Pattan, Maryam Tahhan,
	Konstantin Ananyev, Olivier Matz, Jerin Jacob,
	Cristian Dumitrescu, Harry van Haaren, John W. Linville,
	Xiaolong Ye, Qi Zhang, Shepard Siegel, Ed Czeck, John Miller,
	Ajit Khaparde, Somnath Kotur, Rahul Lakkireddy, Gagandeep Singh,
	Sachin Saxena, Ziyang Xuan, Xiaoyun Wang, Guoyang Zhou,
	Alfredo Cardigliano, Ferruh Yigit, Shijith Thotton,
	Srisivasubramanian Srinivasan, Zyta Szpak, Liron Himi,
	Tomasz Duszynski, Martin Zizka, Jakub Neruda, Tetsuya Mukawa,
	Harman Kalra, Nithin Dabilpuram, Kiran Kumar K, Bruce Richardson,
	Maciej Czekaj, Maxime Coquelin, Zhihong Wang, David Hunt,
	Marko Kovacevic, Ori Kam, Radu Nicolau, Akhil Goyal,
	Tomasz Kantecki, Sunil Kumar Kori, Pavan Nikhilesh,
	Anatoly Burakov, John McNamara, Kirill Rybalchenko, Xiaoyun Li,
	Jasvinder Singh, Byron Marohn, Yipeng Wang, Robert Sanford,
	Erik Gabriel Carrillo, Andrew Rybchenko, Jiayu Hu
  Cc: dev, david.marchand, mattias.ronnblom

From: Sunil Kumar Kori <skori@marvell.com>

Add tracepoints at important and mandatory APIs for
tracing support.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 MAINTAINERS                                   |  2 +
 app/pdump/Makefile                            |  1 +
 app/pdump/meson.build                         |  1 +
 app/proc-info/Makefile                        |  1 +
 app/proc-info/meson.build                     |  1 +
 app/test-acl/Makefile                         |  1 +
 app/test-acl/meson.build                      |  1 +
 app/test-cmdline/Makefile                     |  1 +
 app/test-cmdline/meson.build                  |  1 +
 app/test-eventdev/Makefile                    |  1 +
 app/test-eventdev/meson.build                 |  1 +
 app/test-pipeline/Makefile                    |  1 +
 app/test-pipeline/meson.build                 |  1 +
 drivers/event/octeontx/Makefile               |  1 +
 drivers/event/octeontx/meson.build            |  1 +
 drivers/event/sw/Makefile                     |  1 +
 drivers/event/sw/meson.build                  |  1 +
 drivers/net/af_packet/Makefile                |  1 +
 drivers/net/af_packet/meson.build             |  1 +
 drivers/net/af_xdp/Makefile                   |  1 +
 drivers/net/af_xdp/meson.build                |  1 +
 drivers/net/ark/Makefile                      |  1 +
 drivers/net/ark/meson.build                   |  1 +
 drivers/net/bnxt/Makefile                     |  1 +
 drivers/net/bnxt/meson.build                  |  1 +
 drivers/net/cxgbe/Makefile                    |  1 +
 drivers/net/cxgbe/meson.build                 |  1 +
 drivers/net/enetc/Makefile                    |  1 +
 drivers/net/enetc/meson.build                 |  1 +
 drivers/net/hinic/Makefile                    |  1 +
 drivers/net/hinic/base/meson.build            |  3 +-
 drivers/net/hinic/meson.build                 |  1 +
 drivers/net/ionic/ionic_dev.c                 |  1 +
 drivers/net/ionic/ionic_dev.h                 |  2 +
 drivers/net/ionic/ionic_mac_api.c             |  1 +
 drivers/net/ionic/ionic_main.c                |  1 +
 drivers/net/ionic/ionic_osdep.h               |  6 --
 drivers/net/ionic/ionic_rx_filter.c           |  1 +
 drivers/net/kni/Makefile                      |  1 +
 drivers/net/kni/meson.build                   |  1 +
 drivers/net/liquidio/Makefile                 |  1 +
 drivers/net/liquidio/meson.build              |  1 +
 drivers/net/mvneta/Makefile                   |  1 +
 drivers/net/mvneta/meson.build                |  1 +
 drivers/net/mvpp2/Makefile                    |  1 +
 drivers/net/mvpp2/meson.build                 |  1 +
 drivers/net/nfb/Makefile                      |  1 +
 drivers/net/nfb/meson.build                   |  1 +
 drivers/net/null/Makefile                     |  1 +
 drivers/net/null/meson.build                  |  1 +
 drivers/net/octeontx/Makefile                 |  1 +
 drivers/net/octeontx2/Makefile                |  1 +
 drivers/net/octeontx2/meson.build             |  1 +
 drivers/net/pcap/Makefile                     |  1 +
 drivers/net/pcap/meson.build                  |  1 +
 drivers/net/ring/Makefile                     |  1 +
 drivers/net/ring/meson.build                  |  1 +
 drivers/net/szedata2/Makefile                 |  1 +
 drivers/net/szedata2/meson.build              |  1 +
 drivers/net/thunderx/base/meson.build         |  1 +
 drivers/net/vhost/Makefile                    |  1 +
 drivers/net/vhost/meson.build                 |  1 +
 examples/cmdline/Makefile                     |  1 +
 examples/cmdline/meson.build                  |  1 +
 examples/distributor/Makefile                 |  1 +
 examples/distributor/meson.build              |  1 +
 examples/ethtool/ethtool-app/Makefile         |  1 +
 examples/flow_filtering/Makefile              |  1 +
 examples/flow_filtering/meson.build           |  1 +
 examples/helloworld/Makefile                  |  1 +
 examples/helloworld/meson.build               |  1 +
 examples/ioat/Makefile                        |  1 +
 examples/ioat/meson.build                     |  1 +
 examples/ip_reassembly/Makefile               |  1 +
 examples/ip_reassembly/meson.build            |  1 +
 examples/ipv4_multicast/Makefile              |  1 +
 examples/ipv4_multicast/meson.build           |  1 +
 examples/l2fwd-cat/Makefile                   |  1 +
 examples/l2fwd-cat/meson.build                |  1 +
 examples/l2fwd-event/Makefile                 |  1 +
 examples/l2fwd-event/meson.build              |  1 +
 examples/l2fwd-jobstats/Makefile              |  1 +
 examples/l2fwd-jobstats/meson.build           |  1 +
 examples/l2fwd-keepalive/Makefile             |  1 +
 examples/l2fwd-keepalive/ka-agent/Makefile    |  1 +
 examples/l2fwd-keepalive/meson.build          |  1 +
 examples/l3fwd-acl/Makefile                   |  1 +
 examples/l3fwd-acl/meson.build                |  1 +
 examples/l3fwd/Makefile                       |  1 +
 examples/l3fwd/meson.build                    |  1 +
 examples/link_status_interrupt/Makefile       |  1 +
 examples/link_status_interrupt/meson.build    |  1 +
 .../client_server_mp/mp_client/Makefile       |  1 +
 .../client_server_mp/mp_client/meson.build    |  1 +
 .../client_server_mp/mp_server/meson.build    |  1 +
 examples/multi_process/hotplug_mp/Makefile    |  1 +
 examples/multi_process/hotplug_mp/meson.build |  1 +
 examples/multi_process/simple_mp/Makefile     |  1 +
 examples/multi_process/simple_mp/meson.build  |  1 +
 examples/multi_process/symmetric_mp/Makefile  |  1 +
 .../multi_process/symmetric_mp/meson.build    |  1 +
 examples/packet_ordering/Makefile             |  1 +
 examples/packet_ordering/meson.build          |  1 +
 .../performance-thread/l3fwd-thread/Makefile  |  1 +
 .../l3fwd-thread/meson.build                  |  1 +
 .../performance-thread/pthread_shim/Makefile  |  1 +
 .../pthread_shim/meson.build                  |  1 +
 examples/ptpclient/Makefile                   |  1 +
 examples/ptpclient/meson.build                |  1 +
 examples/qos_meter/Makefile                   |  1 +
 examples/qos_meter/meson.build                |  1 +
 examples/qos_sched/Makefile                   |  1 +
 examples/qos_sched/meson.build                |  1 +
 examples/server_node_efd/node/Makefile        |  1 +
 examples/server_node_efd/node/meson.build     |  1 +
 examples/server_node_efd/server/Makefile      |  1 +
 examples/server_node_efd/server/meson.build   |  1 +
 examples/service_cores/Makefile               |  1 +
 examples/service_cores/meson.build            |  1 +
 examples/skeleton/Makefile                    |  1 +
 examples/skeleton/meson.build                 |  1 +
 examples/timer/Makefile                       |  1 +
 examples/timer/meson.build                    |  1 +
 examples/vm_power_manager/Makefile            |  1 +
 examples/vm_power_manager/meson.build         |  1 +
 examples/vmdq/Makefile                        |  1 +
 examples/vmdq/meson.build                     |  1 +
 examples/vmdq_dcb/Makefile                    |  1 +
 examples/vmdq_dcb/meson.build                 |  1 +
 lib/librte_bitratestats/Makefile              |  1 +
 lib/librte_bitratestats/meson.build           |  1 +
 lib/librte_ethdev/Makefile                    |  3 +
 lib/librte_ethdev/ethdev_trace_points.c       | 43 +++++++++
 lib/librte_ethdev/meson.build                 |  5 +-
 lib/librte_ethdev/rte_ethdev.c                | 12 +++
 lib/librte_ethdev/rte_ethdev.h                |  5 ++
 lib/librte_ethdev/rte_ethdev_version.map      | 10 +++
 lib/librte_ethdev/rte_trace_ethdev.h          | 90 +++++++++++++++++++
 lib/librte_ethdev/rte_trace_ethdev_fp.h       | 40 +++++++++
 lib/librte_gro/Makefile                       |  1 +
 lib/librte_gro/meson.build                    |  1 +
 lib/librte_gso/Makefile                       |  1 +
 lib/librte_gso/meson.build                    |  1 +
 lib/librte_kni/Makefile                       |  1 +
 lib/librte_kni/meson.build                    |  1 +
 lib/librte_latencystats/Makefile              |  1 +
 lib/librte_latencystats/meson.build           |  1 +
 lib/librte_port/Makefile                      |  1 +
 lib/librte_port/meson.build                   |  1 +
 149 files changed, 350 insertions(+), 8 deletions(-)
 create mode 100644 lib/librte_ethdev/ethdev_trace_points.c
 create mode 100644 lib/librte_ethdev/rte_trace_ethdev.h
 create mode 100644 lib/librte_ethdev/rte_trace_ethdev_fp.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 452fd2c4f..a1d3e3746 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -202,6 +202,8 @@ M: Sunil Kumar Kori <skori@marvell.com>
 F: lib/librte_eal/common/include/rte_trace*.h
 F: lib/librte_eal/common/eal_common_trace*.c
 F: lib/librte_eal/common/eal_trace.h
+F: lib/librte_ethdev/ethdev_trace_points.c
+F: lib/librte_ethdev/rte_trace_ethdev*.h
 
 Memory Allocation
 M: Anatoly Burakov <anatoly.burakov@intel.com>
diff --git a/app/pdump/Makefile b/app/pdump/Makefile
index e6b9eea91..b5c485c36 100644
--- a/app/pdump/Makefile
+++ b/app/pdump/Makefile
@@ -8,6 +8,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_PDUMP),y)
 APP = dpdk-pdump
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # all source are stored in SRCS-y
 
diff --git a/app/pdump/meson.build b/app/pdump/meson.build
index 7bb908e04..02f9c6ab4 100644
--- a/app/pdump/meson.build
+++ b/app/pdump/meson.build
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('main.c')
 deps += ['ethdev', 'kvargs', 'pdump']
diff --git a/app/proc-info/Makefile b/app/proc-info/Makefile
index 214f3f54a..ad6a52745 100644
--- a/app/proc-info/Makefile
+++ b/app/proc-info/Makefile
@@ -6,6 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 APP = dpdk-procinfo
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # all source are stored in SRCS-y
 
diff --git a/app/proc-info/meson.build b/app/proc-info/meson.build
index f050c4a9b..ad2a96a48 100644
--- a/app/proc-info/meson.build
+++ b/app/proc-info/meson.build
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('main.c')
 deps += ['ethdev', 'metrics', 'security']
diff --git a/app/test-acl/Makefile b/app/test-acl/Makefile
index 5f26294cf..019ef84b0 100644
--- a/app/test-acl/Makefile
+++ b/app/test-acl/Makefile
@@ -8,6 +8,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_ACL),y)
 APP = testacl
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # all source are stored in SRCS-y
 SRCS-y := main.c
diff --git a/app/test-acl/meson.build b/app/test-acl/meson.build
index d5c2581b4..ac40cb243 100644
--- a/app/test-acl/meson.build
+++ b/app/test-acl/meson.build
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2019 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('main.c')
 deps += ['acl', 'net']
diff --git a/app/test-cmdline/Makefile b/app/test-cmdline/Makefile
index 3e7421906..770eba338 100644
--- a/app/test-cmdline/Makefile
+++ b/app/test-cmdline/Makefile
@@ -18,6 +18,7 @@ SRCS-y += commands.c
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.app.mk
 
diff --git a/app/test-cmdline/meson.build b/app/test-cmdline/meson.build
index 9d0a9aeb6..5e9f5a485 100644
--- a/app/test-cmdline/meson.build
+++ b/app/test-cmdline/meson.build
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2019 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('commands.c', 'cmdline_test.c')
 deps += 'cmdline'
diff --git a/app/test-eventdev/Makefile b/app/test-eventdev/Makefile
index e600e21c4..f70ff366b 100644
--- a/app/test-eventdev/Makefile
+++ b/app/test-eventdev/Makefile
@@ -8,6 +8,7 @@ APP = dpdk-test-eventdev
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 #
 # all source are stored in SRCS-y
diff --git a/app/test-eventdev/meson.build b/app/test-eventdev/meson.build
index 9e588d9ec..36934efdf 100644
--- a/app/test-eventdev/meson.build
+++ b/app/test-eventdev/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Cavium, Inc
 
+allow_experimental_apis = true
 sources = files('evt_main.c',
 		'evt_options.c',
 		'evt_test.c',
diff --git a/app/test-pipeline/Makefile b/app/test-pipeline/Makefile
index fc3a50440..7d1e9e6af 100644
--- a/app/test-pipeline/Makefile
+++ b/app/test-pipeline/Makefile
@@ -12,6 +12,7 @@ APP = testpipeline
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 #
 # all source are stored in SRCS-y
diff --git a/app/test-pipeline/meson.build b/app/test-pipeline/meson.build
index d5eddaba9..3eaf892cc 100644
--- a/app/test-pipeline/meson.build
+++ b/app/test-pipeline/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2019 Intel Corporation
 
+allow_experimental_apis = true
 sources = files(
 	'config.c',
 	'init.c',
diff --git a/drivers/event/octeontx/Makefile b/drivers/event/octeontx/Makefile
index c1233e098..860f45700 100644
--- a/drivers/event/octeontx/Makefile
+++ b/drivers/event/octeontx/Makefile
@@ -10,6 +10,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_pmd_octeontx_ssovf.a
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -I$(RTE_SDK)/drivers/common/octeontx/
 CFLAGS += -I$(RTE_SDK)/drivers/mempool/octeontx/
 CFLAGS += -I$(RTE_SDK)/drivers/net/octeontx/
diff --git a/drivers/event/octeontx/meson.build b/drivers/event/octeontx/meson.build
index 73118a485..be8423e17 100644
--- a/drivers/event/octeontx/meson.build
+++ b/drivers/event/octeontx/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Cavium, Inc
 
+allow_experimental_apis = true
 sources = files('ssovf_worker.c',
 		'ssovf_evdev.c',
 		'ssovf_evdev_selftest.c',
diff --git a/drivers/event/sw/Makefile b/drivers/event/sw/Makefile
index 8ea5cceb8..28823dae1 100644
--- a/drivers/event/sw/Makefile
+++ b/drivers/event/sw/Makefile
@@ -9,6 +9,7 @@ LIB = librte_pmd_sw_event.a
 # build flags
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_eventdev -lrte_kvargs -lrte_ring
 LDLIBS += -lrte_mempool -lrte_mbuf
 LDLIBS += -lrte_bus_vdev
diff --git a/drivers/event/sw/meson.build b/drivers/event/sw/meson.build
index 985012219..30d221647 100644
--- a/drivers/event/sw/meson.build
+++ b/drivers/event/sw/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('sw_evdev_scheduler.c',
 	'sw_evdev_selftest.c',
 	'sw_evdev_worker.c',
diff --git a/drivers/net/af_packet/Makefile b/drivers/net/af_packet/Makefile
index 91dbf0a69..3338a39dc 100644
--- a/drivers/net/af_packet/Makefile
+++ b/drivers/net/af_packet/Makefile
@@ -15,6 +15,7 @@ EXPORT_MAP := rte_pmd_af_packet_version.map
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_vdev
diff --git a/drivers/net/af_packet/meson.build b/drivers/net/af_packet/meson.build
index a7f392ea1..6998538e9 100644
--- a/drivers/net/af_packet/meson.build
+++ b/drivers/net/af_packet/meson.build
@@ -5,4 +5,5 @@ if not is_linux
 	build = false
 	reason = 'only supported on linux'
 endif
+allow_experimental_apis = true
 sources = files('rte_eth_af_packet.c')
diff --git a/drivers/net/af_xdp/Makefile b/drivers/net/af_xdp/Makefile
index 55db6085a..6de67b4fb 100644
--- a/drivers/net/af_xdp/Makefile
+++ b/drivers/net/af_xdp/Makefile
@@ -13,6 +13,7 @@ EXPORT_MAP := rte_pmd_af_xdp_version.map
 CFLAGS += -O3
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_vdev
diff --git a/drivers/net/af_xdp/meson.build b/drivers/net/af_xdp/meson.build
index 307aa0e38..0e8d89bea 100644
--- a/drivers/net/af_xdp/meson.build
+++ b/drivers/net/af_xdp/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2019 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_eth_af_xdp.c')
 
 bpf_dep = dependency('libbpf', required: false)
diff --git a/drivers/net/ark/Makefile b/drivers/net/ark/Makefile
index c02080bdd..e0364945e 100644
--- a/drivers/net/ark/Makefile
+++ b/drivers/net/ark/Makefile
@@ -10,6 +10,7 @@ LIB = librte_pmd_ark.a
 
 CFLAGS += -O3 -I./
 CFLAGS += $(WERROR_FLAGS) -Werror
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_pmd_ark_version.map
 
diff --git a/drivers/net/ark/meson.build b/drivers/net/ark/meson.build
index 99151bba1..7608a1c54 100644
--- a/drivers/net/ark/meson.build
+++ b/drivers/net/ark/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('ark_ddm.c',
 	'ark_ethdev.c',
 	'ark_ethdev_rx.c',
diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index b77532b81..a756f41de 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -15,6 +15,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_pci
diff --git a/drivers/net/bnxt/meson.build b/drivers/net/bnxt/meson.build
index 0c311d235..1af7dd00c 100644
--- a/drivers/net/bnxt/meson.build
+++ b/drivers/net/bnxt/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Intel Corporation
 
+allow_experimental_apis = true
 install_headers('rte_pmd_bnxt.h')
 sources = files('bnxt_cpr.c',
 	'bnxt_ethdev.c',
diff --git a/drivers/net/cxgbe/Makefile b/drivers/net/cxgbe/Makefile
index 79c6e1d1f..d58aedfda 100644
--- a/drivers/net/cxgbe/Makefile
+++ b/drivers/net/cxgbe/Makefile
@@ -11,6 +11,7 @@ LIB = librte_pmd_cxgbe.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_pmd_cxgbe_version.map
 
diff --git a/drivers/net/cxgbe/meson.build b/drivers/net/cxgbe/meson.build
index c51af26e9..002d7ff91 100644
--- a/drivers/net/cxgbe/meson.build
+++ b/drivers/net/cxgbe/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('cxgbe_ethdev.c',
 	'cxgbe_main.c',
 	'cxgbevf_ethdev.c',
diff --git a/drivers/net/enetc/Makefile b/drivers/net/enetc/Makefile
index 7276026e3..bae79dbd2 100644
--- a/drivers/net/enetc/Makefile
+++ b/drivers/net/enetc/Makefile
@@ -10,6 +10,7 @@ LIB = librte_pmd_enetc.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax
 EXPORT_MAP := rte_pmd_enetc_version.map
 SRCS-$(CONFIG_RTE_LIBRTE_ENETC_PMD) += enetc_ethdev.c
diff --git a/drivers/net/enetc/meson.build b/drivers/net/enetc/meson.build
index bea54bea8..d7436e5bc 100644
--- a/drivers/net/enetc/meson.build
+++ b/drivers/net/enetc/meson.build
@@ -6,6 +6,7 @@ if not is_linux
 	reason = 'only supported on linux'
 endif
 
+allow_experimental_apis = true
 deps += ['common_dpaax']
 sources = files('enetc_ethdev.c',
 		'enetc_rxtx.c')
diff --git a/drivers/net/hinic/Makefile b/drivers/net/hinic/Makefile
index 87fd843e4..2c34f228e 100644
--- a/drivers/net/hinic/Makefile
+++ b/drivers/net/hinic/Makefile
@@ -10,6 +10,7 @@ LIB = librte_pmd_hinic.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 ifeq ($(CONFIG_RTE_ARCH_ARM64),y)
 CFLAGS += -D__ARM64_NEON__
diff --git a/drivers/net/hinic/base/meson.build b/drivers/net/hinic/base/meson.build
index 6cf947f84..eaabf297a 100644
--- a/drivers/net/hinic/base/meson.build
+++ b/drivers/net/hinic/base/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Huawei Technologies Co., Ltd
 
+allow_experimental_apis = true
 sources = [
 	'hinic_pmd_api_cmd.c',
 	'hinic_pmd_cfg.c',
@@ -29,7 +30,7 @@ endforeach
 
 deps += ['hash']
 
-c_args = cflags
+c_args += cflags
 
 base_lib = static_library('hinic_base', sources,
 	dependencies: [static_rte_eal, static_rte_ethdev, static_rte_bus_pci, static_rte_hash],
diff --git a/drivers/net/hinic/meson.build b/drivers/net/hinic/meson.build
index bc7e24639..a28eb3a9c 100644
--- a/drivers/net/hinic/meson.build
+++ b/drivers/net/hinic/meson.build
@@ -4,6 +4,7 @@
 subdir('base')
 objs = [base_objs]
 
+allow_experimental_apis = true
 sources = files(
 	'hinic_pmd_ethdev.c',
 	'hinic_pmd_rx.c',
diff --git a/drivers/net/ionic/ionic_dev.c b/drivers/net/ionic/ionic_dev.c
index aba388115..fe111a515 100644
--- a/drivers/net/ionic/ionic_dev.c
+++ b/drivers/net/ionic/ionic_dev.c
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
  * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
  */
+#include <stdbool.h>
 
 #include <rte_malloc.h>
 
diff --git a/drivers/net/ionic/ionic_dev.h b/drivers/net/ionic/ionic_dev.h
index 8c1ec13a6..532255a60 100644
--- a/drivers/net/ionic/ionic_dev.h
+++ b/drivers/net/ionic/ionic_dev.h
@@ -5,6 +5,8 @@
 #ifndef _IONIC_DEV_H_
 #define _IONIC_DEV_H_
 
+#include <stdbool.h>
+
 #include "ionic_osdep.h"
 #include "ionic_if.h"
 #include "ionic_regs.h"
diff --git a/drivers/net/ionic/ionic_mac_api.c b/drivers/net/ionic/ionic_mac_api.c
index 189b8b81a..40421fd4e 100644
--- a/drivers/net/ionic/ionic_mac_api.c
+++ b/drivers/net/ionic/ionic_mac_api.c
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
  * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
  */
+#include <stdbool.h>
 
 #include "ionic_mac_api.h"
 
diff --git a/drivers/net/ionic/ionic_main.c b/drivers/net/ionic/ionic_main.c
index b828d230d..9d74ec73e 100644
--- a/drivers/net/ionic/ionic_main.c
+++ b/drivers/net/ionic/ionic_main.c
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
  * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
  */
+#include <stdbool.h>
 
 #include <rte_memzone.h>
 
diff --git a/drivers/net/ionic/ionic_osdep.h b/drivers/net/ionic/ionic_osdep.h
index ecdbc24e6..e04bb8f65 100644
--- a/drivers/net/ionic/ionic_osdep.h
+++ b/drivers/net/ionic/ionic_osdep.h
@@ -44,12 +44,6 @@ typedef uint16_t __le16;
 typedef uint32_t __le32;
 typedef uint64_t __le64;
 
-#ifndef __cplusplus
-typedef uint8_t bool;
-#define false   0
-#define true    1
-#endif
-
 static inline uint32_t div_round_up(uint32_t n, uint32_t d)
 {
 	return (n + d - 1) / d;
diff --git a/drivers/net/ionic/ionic_rx_filter.c b/drivers/net/ionic/ionic_rx_filter.c
index f75b81a27..fe624538d 100644
--- a/drivers/net/ionic/ionic_rx_filter.c
+++ b/drivers/net/ionic/ionic_rx_filter.c
@@ -3,6 +3,7 @@
  */
 
 #include <errno.h>
+#include <stdbool.h>
 
 #include <rte_malloc.h>
 
diff --git a/drivers/net/kni/Makefile b/drivers/net/kni/Makefile
index 0694ffd02..d9a9eca8d 100644
--- a/drivers/net/kni/Makefile
+++ b/drivers/net/kni/Makefile
@@ -10,6 +10,7 @@ LIB = librte_pmd_kni.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lpthread
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_kni
diff --git a/drivers/net/kni/meson.build b/drivers/net/kni/meson.build
index 0539b4768..191adec70 100644
--- a/drivers/net/kni/meson.build
+++ b/drivers/net/kni/meson.build
@@ -4,5 +4,6 @@
 # this driver can be built if-and-only-if KNI library is buildable
 build = dpdk_conf.has('RTE_LIBRTE_KNI')
 reason = 'missing dependency, DPDK KNI library'
+allow_experimental_apis = true
 sources = files('rte_eth_kni.c')
 deps += 'kni'
diff --git a/drivers/net/liquidio/Makefile b/drivers/net/liquidio/Makefile
index d7fda7f52..4604e7689 100644
--- a/drivers/net/liquidio/Makefile
+++ b/drivers/net/liquidio/Makefile
@@ -11,6 +11,7 @@ LIB = librte_pmd_lio.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)/base -I$(SRCDIR)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_pci
diff --git a/drivers/net/liquidio/meson.build b/drivers/net/liquidio/meson.build
index 9ae48e213..6213c1461 100644
--- a/drivers/net/liquidio/meson.build
+++ b/drivers/net/liquidio/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('base/lio_23xx_vf.c',
 	'base/lio_mbox.c',
 	'lio_ethdev.c',
diff --git a/drivers/net/mvneta/Makefile b/drivers/net/mvneta/Makefile
index 41e50479f..d712a8631 100644
--- a/drivers/net/mvneta/Makefile
+++ b/drivers/net/mvneta/Makefile
@@ -27,6 +27,7 @@ CFLAGS += -DMVCONF_DMA_PHYS_ADDR_T_PUBLIC
 CFLAGS += -DMVCONF_DMA_PHYS_ADDR_T_SIZE=64
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -L$(LIBMUSDK_PATH)/lib
 LDLIBS += -lmusdk
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/net/mvneta/meson.build b/drivers/net/mvneta/meson.build
index 8d7202788..1b371ad8f 100644
--- a/drivers/net/mvneta/meson.build
+++ b/drivers/net/mvneta/meson.build
@@ -21,6 +21,7 @@ else
 	]
 endif
 
+allow_experimental_apis = true
 sources = files(
 	'mvneta_ethdev.c',
 	'mvneta_rxtx.c'
diff --git a/drivers/net/mvpp2/Makefile b/drivers/net/mvpp2/Makefile
index 8a3ec93a6..97e33f67e 100644
--- a/drivers/net/mvpp2/Makefile
+++ b/drivers/net/mvpp2/Makefile
@@ -26,6 +26,7 @@ CFLAGS += -DMVCONF_TYPES_PUBLIC
 CFLAGS += -DMVCONF_DMA_PHYS_ADDR_T_PUBLIC
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -L$(LIBMUSDK_PATH)/lib
 LDLIBS += -lmusdk
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/net/mvpp2/meson.build b/drivers/net/mvpp2/meson.build
index e06eddaac..04bc550a6 100644
--- a/drivers/net/mvpp2/meson.build
+++ b/drivers/net/mvpp2/meson.build
@@ -17,6 +17,7 @@ else
 	cflags += ['-DMVCONF_TYPES_PUBLIC', '-DMVCONF_DMA_PHYS_ADDR_T_PUBLIC']
 endif
 
+allow_experimental_apis = true
 sources = files(
 	'mrvl_ethdev.c',
 	'mrvl_flow.c',
diff --git a/drivers/net/nfb/Makefile b/drivers/net/nfb/Makefile
index e92d29dcd..8eb82733f 100644
--- a/drivers/net/nfb/Makefile
+++ b/drivers/net/nfb/Makefile
@@ -15,6 +15,7 @@ INCLUDES :=-I$(SRCDIR)
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(shell command -v pkg-config > /dev/null 2>&1 && pkg-config --cflags netcope-common)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_kvargs
 LDLIBS += -lrte_ethdev -lrte_net
diff --git a/drivers/net/nfb/meson.build b/drivers/net/nfb/meson.build
index d53e8eca7..d4e7d553e 100644
--- a/drivers/net/nfb/meson.build
+++ b/drivers/net/nfb/meson.build
@@ -7,5 +7,6 @@ dep = dependency('netcope-common', required: false)
 reason = 'missing dependency, "libnfb"'
 build = dep.found()
 ext_deps += dep
+allow_experimental_apis = true
 
 sources = files('nfb_rx.c', 'nfb_tx.c', 'nfb_stats.c', 'nfb_ethdev.c', 'nfb_rxmode.c')
diff --git a/drivers/net/null/Makefile b/drivers/net/null/Makefile
index f51150c13..664c6ae23 100644
--- a/drivers/net/null/Makefile
+++ b/drivers/net/null/Makefile
@@ -10,6 +10,7 @@ LIB = librte_pmd_null.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_vdev
diff --git a/drivers/net/null/meson.build b/drivers/net/null/meson.build
index 68ac0d2ae..16be6b7d2 100644
--- a/drivers/net/null/meson.build
+++ b/drivers/net/null/meson.build
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_eth_null.c')
diff --git a/drivers/net/octeontx/Makefile b/drivers/net/octeontx/Makefile
index 8ddfc3089..4fb0566e5 100644
--- a/drivers/net/octeontx/Makefile
+++ b/drivers/net/octeontx/Makefile
@@ -10,6 +10,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_pmd_octeontx.a
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -I$(RTE_SDK)/drivers/common/octeontx/
 CFLAGS += -I$(RTE_SDK)/drivers/mempool/octeontx/
 
diff --git a/drivers/net/octeontx2/Makefile b/drivers/net/octeontx2/Makefile
index 0de43e36a..d0354114e 100644
--- a/drivers/net/octeontx2/Makefile
+++ b/drivers/net/octeontx2/Makefile
@@ -20,6 +20,7 @@ ifneq ($(CONFIG_RTE_TOOLCHAIN_ICC),y)
 CFLAGS += -flax-vector-conversions
 endif
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 ifneq ($(CONFIG_RTE_ARCH_64),y)
 CFLAGS += -Wno-int-to-pointer-cast
 CFLAGS += -Wno-pointer-to-int-cast
diff --git a/drivers/net/octeontx2/meson.build b/drivers/net/octeontx2/meson.build
index 599ade672..43c68d32e 100644
--- a/drivers/net/octeontx2/meson.build
+++ b/drivers/net/octeontx2/meson.build
@@ -2,6 +2,7 @@
 # Copyright(C) 2019 Marvell International Ltd.
 #
 
+allow_experimental_apis = true
 sources = files('otx2_rx.c',
 		'otx2_tx.c',
 		'otx2_tm.c',
diff --git a/drivers/net/pcap/Makefile b/drivers/net/pcap/Makefile
index f243d1a0f..332b5384c 100644
--- a/drivers/net/pcap/Makefile
+++ b/drivers/net/pcap/Makefile
@@ -12,6 +12,7 @@ LIB = librte_pmd_pcap.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lpcap
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
diff --git a/drivers/net/pcap/meson.build b/drivers/net/pcap/meson.build
index b680710aa..f9c21bf43 100644
--- a/drivers/net/pcap/meson.build
+++ b/drivers/net/pcap/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 if not dpdk_conf.has('RTE_PORT_PCAP')
 	build = false
 	reason = 'missing dependency, "libpcap"'
diff --git a/drivers/net/ring/Makefile b/drivers/net/ring/Makefile
index d6a3dec35..77c76b42f 100644
--- a/drivers/net/ring/Makefile
+++ b/drivers/net/ring/Makefile
@@ -10,6 +10,7 @@ LIB = librte_pmd_ring.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_vdev
diff --git a/drivers/net/ring/meson.build b/drivers/net/ring/meson.build
index e877a4b4b..0047400e0 100644
--- a/drivers/net/ring/meson.build
+++ b/drivers/net/ring/meson.build
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_eth_ring.c')
 install_headers('rte_eth_ring.h')
diff --git a/drivers/net/szedata2/Makefile b/drivers/net/szedata2/Makefile
index 675d0938a..5d1e6bc55 100644
--- a/drivers/net/szedata2/Makefile
+++ b/drivers/net/szedata2/Makefile
@@ -10,6 +10,7 @@ LIB = librte_pmd_szedata2.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lsze2
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
diff --git a/drivers/net/szedata2/meson.build b/drivers/net/szedata2/meson.build
index b53fcbc59..e7326df2c 100644
--- a/drivers/net/szedata2/meson.build
+++ b/drivers/net/szedata2/meson.build
@@ -5,4 +5,5 @@ dep = dependency('libsze2', required: false)
 build = dep.found()
 reason = 'missing dependency, "libsze2"'
 ext_deps += dep
+allow_experimental_apis = true
 sources = files('rte_eth_szedata2.c')
diff --git a/drivers/net/thunderx/base/meson.build b/drivers/net/thunderx/base/meson.build
index bf4e8608a..97c55a2e2 100644
--- a/drivers/net/thunderx/base/meson.build
+++ b/drivers/net/thunderx/base/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Cavium, Inc
 
+allow_experimental_apis = true
 sources = [
 	'nicvf_hw.c',
 	'nicvf_mbox.c',
diff --git a/drivers/net/vhost/Makefile b/drivers/net/vhost/Makefile
index 0461e29f2..d5be3bcd3 100644
--- a/drivers/net/vhost/Makefile
+++ b/drivers/net/vhost/Makefile
@@ -15,6 +15,7 @@ LDLIBS += -lrte_bus_vdev
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_pmd_vhost_version.map
 
diff --git a/drivers/net/vhost/meson.build b/drivers/net/vhost/meson.build
index d7930862a..47a7c2c3e 100644
--- a/drivers/net/vhost/meson.build
+++ b/drivers/net/vhost/meson.build
@@ -3,6 +3,7 @@
 
 build = dpdk_conf.has('RTE_LIBRTE_VHOST')
 reason = 'missing dependency, DPDK vhost library'
+allow_experimental_apis = true
 sources = files('rte_eth_vhost.c')
 install_headers('rte_eth_vhost.h')
 deps += 'vhost'
diff --git a/examples/cmdline/Makefile b/examples/cmdline/Makefile
index 0b6b54540..9a33355d0 100644
--- a/examples/cmdline/Makefile
+++ b/examples/cmdline/Makefile
@@ -57,6 +57,7 @@ SRCS-y := main.c commands.c parse_obj_list.c
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
 
diff --git a/examples/cmdline/meson.build b/examples/cmdline/meson.build
index a8608c21a..7de0f1625 100644
--- a/examples/cmdline/meson.build
+++ b/examples/cmdline/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 sources = files(
 	'commands.c', 'main.c', 'parse_obj_list.c'
 )
diff --git a/examples/distributor/Makefile b/examples/distributor/Makefile
index 4192d8a4a..63c14dfca 100644
--- a/examples/distributor/Makefile
+++ b/examples/distributor/Makefile
@@ -50,6 +50,7 @@ RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.conf
 include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # workaround for a gcc bug with noreturn attribute
 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
diff --git a/examples/distributor/meson.build b/examples/distributor/meson.build
index 26f108d65..9fec7f883 100644
--- a/examples/distributor/meson.build
+++ b/examples/distributor/meson.build
@@ -9,6 +9,7 @@
 # require the power library
 build = dpdk_conf.has('RTE_LIBRTE_POWER')
 
+allow_experimental_apis = true
 deps += ['distributor', 'power']
 sources = files(
 	'main.c'
diff --git a/examples/ethtool/ethtool-app/Makefile b/examples/ethtool/ethtool-app/Makefile
index 3543bdee0..20ac0d324 100644
--- a/examples/ethtool/ethtool-app/Makefile
+++ b/examples/ethtool/ethtool-app/Makefile
@@ -18,6 +18,7 @@ SRCS-y := main.c ethapp.c
 
 CFLAGS += -O3 -pthread -I$(SRCDIR)/../lib
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 LDLIBS += -L$(subst ethtool-app,lib,$(RTE_OUTPUT))/lib
 LDLIBS += -lrte_ethtool
diff --git a/examples/flow_filtering/Makefile b/examples/flow_filtering/Makefile
index 6c51c0b7a..e0d546de9 100644
--- a/examples/flow_filtering/Makefile
+++ b/examples/flow_filtering/Makefile
@@ -49,6 +49,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
 
diff --git a/examples/flow_filtering/meson.build b/examples/flow_filtering/meson.build
index 407795c42..6f5d1b08a 100644
--- a/examples/flow_filtering/meson.build
+++ b/examples/flow_filtering/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 sources = files(
 	'main.c',
 )
diff --git a/examples/helloworld/Makefile b/examples/helloworld/Makefile
index 16d82b02f..0f5af0806 100644
--- a/examples/helloworld/Makefile
+++ b/examples/helloworld/Makefile
@@ -51,6 +51,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
 
diff --git a/examples/helloworld/meson.build b/examples/helloworld/meson.build
index c34e11e36..2b0a25036 100644
--- a/examples/helloworld/meson.build
+++ b/examples/helloworld/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 sources = files(
 	'main.c'
 )
diff --git a/examples/ioat/Makefile b/examples/ioat/Makefile
index ef63f5d68..9b277eb7b 100644
--- a/examples/ioat/Makefile
+++ b/examples/ioat/Makefile
@@ -51,6 +51,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
 endif
diff --git a/examples/ioat/meson.build b/examples/ioat/meson.build
index ed8328963..f72cf70e7 100644
--- a/examples/ioat/meson.build
+++ b/examples/ioat/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 build = dpdk_conf.has('RTE_LIBRTE_PMD_IOAT_RAWDEV')
 
 deps += ['rawdev_ioat']
diff --git a/examples/ip_reassembly/Makefile b/examples/ip_reassembly/Makefile
index 3f2888b33..11be2a74a 100644
--- a/examples/ip_reassembly/Makefile
+++ b/examples/ip_reassembly/Makefile
@@ -52,6 +52,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # workaround for a gcc bug with noreturn attribute
 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
diff --git a/examples/ip_reassembly/meson.build b/examples/ip_reassembly/meson.build
index 8ebd48291..517bd4e19 100644
--- a/examples/ip_reassembly/meson.build
+++ b/examples/ip_reassembly/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 deps += ['lpm', 'ip_frag']
 sources = files(
 	'main.c'
diff --git a/examples/ipv4_multicast/Makefile b/examples/ipv4_multicast/Makefile
index 92d3db0f4..b9f0813ed 100644
--- a/examples/ipv4_multicast/Makefile
+++ b/examples/ipv4_multicast/Makefile
@@ -52,6 +52,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # workaround for a gcc bug with noreturn attribute
 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
diff --git a/examples/ipv4_multicast/meson.build b/examples/ipv4_multicast/meson.build
index d9e4c7c21..7dc13fb8f 100644
--- a/examples/ipv4_multicast/meson.build
+++ b/examples/ipv4_multicast/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 deps += 'hash'
 sources = files(
 	'main.c'
diff --git a/examples/l2fwd-cat/Makefile b/examples/l2fwd-cat/Makefile
index b0e53c37e..ca1202be1 100644
--- a/examples/l2fwd-cat/Makefile
+++ b/examples/l2fwd-cat/Makefile
@@ -56,6 +56,7 @@ RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.conf
 include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # workaround for a gcc bug with noreturn attribute
 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
diff --git a/examples/l2fwd-cat/meson.build b/examples/l2fwd-cat/meson.build
index 4e2777a03..2bed18e74 100644
--- a/examples/l2fwd-cat/meson.build
+++ b/examples/l2fwd-cat/meson.build
@@ -9,6 +9,7 @@
 pqos = cc.find_library('pqos', required: false)
 build = pqos.found()
 ext_deps += pqos
+allow_experimental_apis = true
 cflags += '-I/usr/local/include' # assume pqos lib installed in /usr/local
 sources = files(
 	'cat.c', 'l2fwd-cat.c'
diff --git a/examples/l2fwd-event/Makefile b/examples/l2fwd-event/Makefile
index 4cdae36f1..807f7f1b8 100644
--- a/examples/l2fwd-event/Makefile
+++ b/examples/l2fwd-event/Makefile
@@ -57,6 +57,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
 endif
diff --git a/examples/l2fwd-event/meson.build b/examples/l2fwd-event/meson.build
index c4664c3a3..1819ccdf5 100644
--- a/examples/l2fwd-event/meson.build
+++ b/examples/l2fwd-event/meson.build
@@ -7,6 +7,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 deps += 'eventdev'
 sources = files(
 	'main.c',
diff --git a/examples/l2fwd-jobstats/Makefile b/examples/l2fwd-jobstats/Makefile
index 73c91faa8..6cd9dcd9c 100644
--- a/examples/l2fwd-jobstats/Makefile
+++ b/examples/l2fwd-jobstats/Makefile
@@ -52,6 +52,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
 endif
diff --git a/examples/l2fwd-jobstats/meson.build b/examples/l2fwd-jobstats/meson.build
index 1ffd484e2..72273736b 100644
--- a/examples/l2fwd-jobstats/meson.build
+++ b/examples/l2fwd-jobstats/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 deps += ['jobstats', 'timer']
 sources = files(
 	'main.c'
diff --git a/examples/l2fwd-keepalive/Makefile b/examples/l2fwd-keepalive/Makefile
index 94d1e58bb..0db5e6015 100644
--- a/examples/l2fwd-keepalive/Makefile
+++ b/examples/l2fwd-keepalive/Makefile
@@ -53,6 +53,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDFLAGS += -lrt
 
 include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/l2fwd-keepalive/ka-agent/Makefile b/examples/l2fwd-keepalive/ka-agent/Makefile
index 755e47438..8d5061b17 100644
--- a/examples/l2fwd-keepalive/ka-agent/Makefile
+++ b/examples/l2fwd-keepalive/ka-agent/Makefile
@@ -17,5 +17,6 @@ APP = ka-agent
 SRCS-y := main.c
 
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)/../
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDFLAGS += -lrt
 include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/l2fwd-keepalive/meson.build b/examples/l2fwd-keepalive/meson.build
index 6f7b007e1..d678a8ddd 100644
--- a/examples/l2fwd-keepalive/meson.build
+++ b/examples/l2fwd-keepalive/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 ext_deps += cc.find_library('rt')
 deps += 'timer'
 sources = files(
diff --git a/examples/l3fwd-acl/Makefile b/examples/l3fwd-acl/Makefile
index d9909584b..9f31abef8 100644
--- a/examples/l3fwd-acl/Makefile
+++ b/examples/l3fwd-acl/Makefile
@@ -51,6 +51,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # workaround for a gcc bug with noreturn attribute
 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
diff --git a/examples/l3fwd-acl/meson.build b/examples/l3fwd-acl/meson.build
index 7096e00c1..6fa468b3a 100644
--- a/examples/l3fwd-acl/meson.build
+++ b/examples/l3fwd-acl/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 deps += ['acl', 'lpm', 'hash']
 sources = files(
 	'main.c'
diff --git a/examples/l3fwd/Makefile b/examples/l3fwd/Makefile
index 59a110d12..839439f0f 100644
--- a/examples/l3fwd/Makefile
+++ b/examples/l3fwd/Makefile
@@ -53,6 +53,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 CFLAGS += -I$(SRCDIR)
 CFLAGS += -O3 $(USER_FLAGS)
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
 endif
diff --git a/examples/l3fwd/meson.build b/examples/l3fwd/meson.build
index ebed3b518..7d72b1b36 100644
--- a/examples/l3fwd/meson.build
+++ b/examples/l3fwd/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 deps += ['hash', 'lpm', 'eventdev']
 sources = files(
 	'l3fwd_em.c', 'l3fwd_lpm.c', 'l3fwd_event.c',
diff --git a/examples/link_status_interrupt/Makefile b/examples/link_status_interrupt/Makefile
index 4f02a8901..613bb1167 100644
--- a/examples/link_status_interrupt/Makefile
+++ b/examples/link_status_interrupt/Makefile
@@ -51,6 +51,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
 endif
diff --git a/examples/link_status_interrupt/meson.build b/examples/link_status_interrupt/meson.build
index c34e11e36..2b0a25036 100644
--- a/examples/link_status_interrupt/meson.build
+++ b/examples/link_status_interrupt/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 sources = files(
 	'main.c'
 )
diff --git a/examples/multi_process/client_server_mp/mp_client/Makefile b/examples/multi_process/client_server_mp/mp_client/Makefile
index 298e1b020..7c447feba 100644
--- a/examples/multi_process/client_server_mp/mp_client/Makefile
+++ b/examples/multi_process/client_server_mp/mp_client/Makefile
@@ -16,5 +16,6 @@ SRCS-y := client.c
 
 CFLAGS += $(WERROR_FLAGS) -O3
 CFLAGS += -I$(SRCDIR)/../shared
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/multi_process/client_server_mp/mp_client/meson.build b/examples/multi_process/client_server_mp/mp_client/meson.build
index a6241b83a..69c3d3bfb 100644
--- a/examples/multi_process/client_server_mp/mp_client/meson.build
+++ b/examples/multi_process/client_server_mp/mp_client/meson.build
@@ -8,6 +8,7 @@
 
 includes += include_directories('../shared')
 
+allow_experimental_apis = true
 sources = files(
 	'client.c'
 )
diff --git a/examples/multi_process/client_server_mp/mp_server/meson.build b/examples/multi_process/client_server_mp/mp_server/meson.build
index 1b2f78638..0ef6424f4 100644
--- a/examples/multi_process/client_server_mp/mp_server/meson.build
+++ b/examples/multi_process/client_server_mp/mp_server/meson.build
@@ -8,6 +8,7 @@
 
 includes += include_directories('../shared')
 
+allow_experimental_apis = true
 sources = files(
 	'args.c', 'init.c', 'main.c'
 )
diff --git a/examples/multi_process/hotplug_mp/Makefile b/examples/multi_process/hotplug_mp/Makefile
index 3ff74d52a..1fd7aa085 100644
--- a/examples/multi_process/hotplug_mp/Makefile
+++ b/examples/multi_process/hotplug_mp/Makefile
@@ -18,5 +18,6 @@ SRCS-y := main.c commands.c
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/multi_process/hotplug_mp/meson.build b/examples/multi_process/hotplug_mp/meson.build
index 076f4e3dc..f82f4d48a 100644
--- a/examples/multi_process/hotplug_mp/meson.build
+++ b/examples/multi_process/hotplug_mp/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 sources = files(
 	'commands.c', 'main.c'
 )
diff --git a/examples/multi_process/simple_mp/Makefile b/examples/multi_process/simple_mp/Makefile
index 4c0764451..f88b499bd 100644
--- a/examples/multi_process/simple_mp/Makefile
+++ b/examples/multi_process/simple_mp/Makefile
@@ -18,5 +18,6 @@ SRCS-y := main.c mp_commands.c
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/multi_process/simple_mp/meson.build b/examples/multi_process/simple_mp/meson.build
index b2261e00e..cb02c65a6 100644
--- a/examples/multi_process/simple_mp/meson.build
+++ b/examples/multi_process/simple_mp/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 sources = files(
 	'mp_commands.c', 'main.c'
 )
diff --git a/examples/multi_process/symmetric_mp/Makefile b/examples/multi_process/symmetric_mp/Makefile
index bdc415621..b7544489b 100644
--- a/examples/multi_process/symmetric_mp/Makefile
+++ b/examples/multi_process/symmetric_mp/Makefile
@@ -18,5 +18,6 @@ SRCS-y := main.c
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/multi_process/symmetric_mp/meson.build b/examples/multi_process/symmetric_mp/meson.build
index 458f83642..14167825b 100644
--- a/examples/multi_process/symmetric_mp/meson.build
+++ b/examples/multi_process/symmetric_mp/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 sources = files(
 	'main.c'
 )
diff --git a/examples/packet_ordering/Makefile b/examples/packet_ordering/Makefile
index 261b7f06a..f5b68c97e 100644
--- a/examples/packet_ordering/Makefile
+++ b/examples/packet_ordering/Makefile
@@ -51,6 +51,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
 endif
diff --git a/examples/packet_ordering/meson.build b/examples/packet_ordering/meson.build
index 6c2fccdcb..b38195914 100644
--- a/examples/packet_ordering/meson.build
+++ b/examples/packet_ordering/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 deps += 'reorder'
 sources = files(
 	'main.c'
diff --git a/examples/performance-thread/l3fwd-thread/Makefile b/examples/performance-thread/l3fwd-thread/Makefile
index b14b21e30..c6cf05a43 100644
--- a/examples/performance-thread/l3fwd-thread/Makefile
+++ b/examples/performance-thread/l3fwd-thread/Makefile
@@ -19,5 +19,6 @@ SRCS-y := main.c
 include $(RTE_SDK)/examples/performance-thread/common/common.mk
 
 CFLAGS += -O3 -g $(USER_FLAGS) $(INCLUDES) $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/performance-thread/l3fwd-thread/meson.build b/examples/performance-thread/l3fwd-thread/meson.build
index 185fa59a4..99de24be7 100644
--- a/examples/performance-thread/l3fwd-thread/meson.build
+++ b/examples/performance-thread/l3fwd-thread/meson.build
@@ -8,6 +8,7 @@
 
 build = dpdk_conf.has('RTE_ARCH_X86_64')
 deps += ['timer', 'lpm']
+allow_experimental_apis = true
 
 # get the performance thread (pt) architecture subdir
 if dpdk_conf.has('RTE_ARCH_ARM64')
diff --git a/examples/performance-thread/pthread_shim/Makefile b/examples/performance-thread/pthread_shim/Makefile
index efd66febf..cdadf2cb7 100644
--- a/examples/performance-thread/pthread_shim/Makefile
+++ b/examples/performance-thread/pthread_shim/Makefile
@@ -20,6 +20,7 @@ include $(RTE_SDK)/examples/performance-thread/common/common.mk
 
 CFLAGS += -g -O3 $(USER_FLAGS) $(INCLUDES)
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 LDFLAGS += -lpthread
 
diff --git a/examples/performance-thread/pthread_shim/meson.build b/examples/performance-thread/pthread_shim/meson.build
index 393fbd122..26ef78635 100644
--- a/examples/performance-thread/pthread_shim/meson.build
+++ b/examples/performance-thread/pthread_shim/meson.build
@@ -8,6 +8,7 @@
 
 build = dpdk_conf.has('RTE_ARCH_X86_64') or dpdk_conf.has('RTE_ARCH_ARM64')
 deps += ['timer']
+allow_experimental_apis = true
 
 # get the performance thread (pt) architecture subdir
 if dpdk_conf.has('RTE_ARCH_ARM64')
diff --git a/examples/ptpclient/Makefile b/examples/ptpclient/Makefile
index 82d72b3e3..7cd36632a 100644
--- a/examples/ptpclient/Makefile
+++ b/examples/ptpclient/Makefile
@@ -51,6 +51,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # workaround for a gcc bug with noreturn attribute
 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
diff --git a/examples/ptpclient/meson.build b/examples/ptpclient/meson.build
index fa0cbe93c..d4171a218 100644
--- a/examples/ptpclient/meson.build
+++ b/examples/ptpclient/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 sources = files(
 	'ptpclient.c'
 )
diff --git a/examples/qos_meter/Makefile b/examples/qos_meter/Makefile
index 7c2bf88a9..90e3533d1 100644
--- a/examples/qos_meter/Makefile
+++ b/examples/qos_meter/Makefile
@@ -53,6 +53,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # workaround for a gcc bug with noreturn attribute
 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
diff --git a/examples/qos_meter/meson.build b/examples/qos_meter/meson.build
index ef7779f2f..2f9ab13af 100644
--- a/examples/qos_meter/meson.build
+++ b/examples/qos_meter/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 deps += 'meter'
 sources = files(
 	'main.c', 'rte_policer.c'
diff --git a/examples/qos_sched/Makefile b/examples/qos_sched/Makefile
index 525061ca0..92e3de79b 100644
--- a/examples/qos_sched/Makefile
+++ b/examples/qos_sched/Makefile
@@ -58,6 +58,7 @@ else
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
 
diff --git a/examples/qos_sched/meson.build b/examples/qos_sched/meson.build
index 289b81ce8..ba59d3c9e 100644
--- a/examples/qos_sched/meson.build
+++ b/examples/qos_sched/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 deps += ['sched', 'cfgfile']
 sources = files(
 	'app_thread.c', 'args.c', 'cfg_file.c', 'cmdline.c',
diff --git a/examples/server_node_efd/node/Makefile b/examples/server_node_efd/node/Makefile
index fffbe3576..ecc551e1d 100644
--- a/examples/server_node_efd/node/Makefile
+++ b/examples/server_node_efd/node/Makefile
@@ -16,5 +16,6 @@ SRCS-y := node.c
 
 CFLAGS += $(WERROR_FLAGS) -O3
 CFLAGS += -I$(SRCDIR)/../shared
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/server_node_efd/node/meson.build b/examples/server_node_efd/node/meson.build
index 30f28761f..1c720968a 100644
--- a/examples/server_node_efd/node/meson.build
+++ b/examples/server_node_efd/node/meson.build
@@ -8,6 +8,7 @@
 
 name = 'efd_node'
 
+allow_experimental_apis = true
 deps += ['hash']
 sources += files('node.c')
 includes += include_directories('../shared')
diff --git a/examples/server_node_efd/server/Makefile b/examples/server_node_efd/server/Makefile
index 4837bd3ea..acbd12ae2 100644
--- a/examples/server_node_efd/server/Makefile
+++ b/examples/server_node_efd/server/Makefile
@@ -25,5 +25,6 @@ INC := $(sort $(wildcard *.h))
 
 CFLAGS += $(WERROR_FLAGS) -O3
 CFLAGS += -I$(SRCDIR)/../shared
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/server_node_efd/server/meson.build b/examples/server_node_efd/server/meson.build
index 23e08d1ae..7abc333e1 100644
--- a/examples/server_node_efd/server/meson.build
+++ b/examples/server_node_efd/server/meson.build
@@ -8,6 +8,7 @@
 
 name = 'efd_server'
 
+allow_experimental_apis = true
 deps += 'efd'
 sources += files('args.c', 'init.c', 'main.c')
 includes += include_directories('../shared')
diff --git a/examples/service_cores/Makefile b/examples/service_cores/Makefile
index c47055813..aac207bd9 100644
--- a/examples/service_cores/Makefile
+++ b/examples/service_cores/Makefile
@@ -50,6 +50,7 @@ RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.conf
 include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # workaround for a gcc bug with noreturn attribute
 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
diff --git a/examples/service_cores/meson.build b/examples/service_cores/meson.build
index c34e11e36..2b0a25036 100644
--- a/examples/service_cores/meson.build
+++ b/examples/service_cores/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 sources = files(
 	'main.c'
 )
diff --git a/examples/skeleton/Makefile b/examples/skeleton/Makefile
index 2c29004d7..2612688c0 100644
--- a/examples/skeleton/Makefile
+++ b/examples/skeleton/Makefile
@@ -50,6 +50,7 @@ RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.conf
 include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # workaround for a gcc bug with noreturn attribute
 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
diff --git a/examples/skeleton/meson.build b/examples/skeleton/meson.build
index 9bb9ec329..ef46b187e 100644
--- a/examples/skeleton/meson.build
+++ b/examples/skeleton/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 sources = files(
 	'basicfwd.c'
 )
diff --git a/examples/timer/Makefile b/examples/timer/Makefile
index bf86339ab..e58e90a28 100644
--- a/examples/timer/Makefile
+++ b/examples/timer/Makefile
@@ -51,6 +51,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # workaround for a gcc bug with noreturn attribute
 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
diff --git a/examples/timer/meson.build b/examples/timer/meson.build
index c3d901637..87c21a867 100644
--- a/examples/timer/meson.build
+++ b/examples/timer/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 deps += 'timer'
 sources = files(
 	'main.c'
diff --git a/examples/vm_power_manager/Makefile b/examples/vm_power_manager/Makefile
index 2fdb991d7..65c2ad179 100644
--- a/examples/vm_power_manager/Makefile
+++ b/examples/vm_power_manager/Makefile
@@ -28,6 +28,7 @@ endif
 
 CFLAGS += -O3 -I$(RTE_SDK)/lib/librte_power/
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 LDLIBS += -lvirt
 
diff --git a/examples/vm_power_manager/meson.build b/examples/vm_power_manager/meson.build
index 20a4a05b3..54e2b584f 100644
--- a/examples/vm_power_manager/meson.build
+++ b/examples/vm_power_manager/meson.build
@@ -25,6 +25,7 @@ if dpdk_conf.has('RTE_LIBRTE_IXGBE_PMD')
 	deps += ['pmd_ixgbe']
 endif
 
+allow_experimental_apis = true
 sources = files(
 	'channel_manager.c', 'channel_monitor.c', 'main.c', 'parse.c', 'power_manager.c', 'vm_power_cli.c'
 )
diff --git a/examples/vmdq/Makefile b/examples/vmdq/Makefile
index 0767c715a..98e644fa7 100644
--- a/examples/vmdq/Makefile
+++ b/examples/vmdq/Makefile
@@ -50,6 +50,7 @@ RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.conf
 include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXTRA_CFLAGS += -O3
 
diff --git a/examples/vmdq/meson.build b/examples/vmdq/meson.build
index c34e11e36..2b0a25036 100644
--- a/examples/vmdq/meson.build
+++ b/examples/vmdq/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 sources = files(
 	'main.c'
 )
diff --git a/examples/vmdq_dcb/Makefile b/examples/vmdq_dcb/Makefile
index 2a9b04143..3eb7c9f43 100644
--- a/examples/vmdq_dcb/Makefile
+++ b/examples/vmdq_dcb/Makefile
@@ -50,6 +50,7 @@ RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.conf
 include $(RTE_SDK)/mk/rte.vars.mk
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # workaround for a gcc bug with noreturn attribute
 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
diff --git a/examples/vmdq_dcb/meson.build b/examples/vmdq_dcb/meson.build
index c34e11e36..2b0a25036 100644
--- a/examples/vmdq_dcb/meson.build
+++ b/examples/vmdq_dcb/meson.build
@@ -6,6 +6,7 @@
 # To build this example as a standalone application with an already-installed
 # DPDK instance, use 'make'
 
+allow_experimental_apis = true
 sources = files(
 	'main.c'
 )
diff --git a/lib/librte_bitratestats/Makefile b/lib/librte_bitratestats/Makefile
index 4862c44b8..6e717f2ed 100644
--- a/lib/librte_bitratestats/Makefile
+++ b/lib/librte_bitratestats/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_bitratestats.a
 
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_metrics -lrte_ethdev
 
 EXPORT_MAP := rte_bitratestats_version.map
diff --git a/lib/librte_bitratestats/meson.build b/lib/librte_bitratestats/meson.build
index ede7e0a57..78c2dd57a 100644
--- a/lib/librte_bitratestats/meson.build
+++ b/lib/librte_bitratestats/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_bitrate.c')
 headers = files('rte_bitrate.h')
 deps += ['ethdev', 'metrics']
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index b627e4e23..62d126a0c 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -23,6 +23,7 @@ SRCS-y += rte_flow.c
 SRCS-y += rte_tm.c
 SRCS-y += rte_mtr.c
 SRCS-y += ethdev_profile.c
+SRCS-y += ethdev_trace_points.c
 
 #
 # Export include files
@@ -40,5 +41,7 @@ SYMLINK-y-include += rte_tm.h
 SYMLINK-y-include += rte_tm_driver.h
 SYMLINK-y-include += rte_mtr.h
 SYMLINK-y-include += rte_mtr_driver.h
+SYMLINK-y-include += rte_trace_ethdev.h
+SYMLINK-y-include += rte_trace_ethdev_fp.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ethdev/ethdev_trace_points.c b/lib/librte_ethdev/ethdev_trace_points.c
new file mode 100644
index 000000000..b08d247b4
--- /dev/null
+++ b/lib/librte_ethdev/ethdev_trace_points.c
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#define RTE_TRACE_POINT_REGISTER_SELECT /* Select trace point register macros */
+
+#include <rte_trace_ethdev.h>
+
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_ethdev_configure);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_ethdev_rxq_setup);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_ethdev_txq_setup);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_ethdev_start);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_ethdev_stop);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_ethdev_close);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_ethdev_rx_burst);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_ethdev_tx_burst);
+
+RTE_INIT(ethdev_trace_init)
+{
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_ethdev_configure,
+				 lib.ethdev.configure, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_ethdev_rxq_setup,
+				 lib.ethdev.rxq.setup, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_ethdev_txq_setup,
+				 lib.ethdev.txq.setup, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_ethdev_start,
+				 lib.ethdev.start, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_ethdev_stop,
+				 lib.ethdev.stop, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_ethdev_close,
+				 lib.ethdev.close, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_ethdev_rx_burst,
+				 lib.ethdev.rx.burst, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_ethdev_tx_burst,
+				 lib.ethdev.tx.burst, INFO);
+}
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 3537f22f5..84dabfb80 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -5,6 +5,7 @@ name = 'ethdev'
 allow_experimental_apis = true
 sources = files('ethdev_private.c',
 	'ethdev_profile.c',
+	'ethdev_trace_points.c',
 	'rte_class_eth.c',
 	'rte_ethdev.c',
 	'rte_flow.c',
@@ -23,6 +24,8 @@ headers = files('rte_ethdev.h',
 	'rte_mtr.h',
 	'rte_mtr_driver.h',
 	'rte_tm.h',
-	'rte_tm_driver.h')
+	'rte_tm_driver.h',
+	'rte_trace_ethdev.h',
+	'rte_trace_ethdev_fp.h')
 
 deps += ['net', 'kvargs', 'meter']
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 774c721b3..f5dbd6e41 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -39,6 +39,7 @@
 #include <rte_class.h>
 #include <rte_ether.h>
 
+#include "rte_trace_ethdev.h"
 #include "rte_ethdev.h"
 #include "rte_ethdev_driver.h"
 #include "ethdev_profile.h"
@@ -1470,6 +1471,7 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		goto reset_queues;
 	}
 
+	rte_trace_lib_ethdev_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, 0);
 	return 0;
 reset_queues:
 	rte_eth_dev_rx_queue_config(dev, 0);
@@ -1477,6 +1479,8 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 rollback:
 	memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf));
 
+	rte_trace_lib_ethdev_configure(port_id, nb_rx_q, nb_tx_q, dev_conf,
+				       ret);
 	return ret;
 }
 
@@ -1647,6 +1651,8 @@ rte_eth_dev_start(uint16_t port_id)
 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
 		(*dev->dev_ops->link_update)(dev, 0);
 	}
+
+	rte_trace_lib_ethdev_start(port_id);
 	return 0;
 }
 
@@ -1669,6 +1675,7 @@ rte_eth_dev_stop(uint16_t port_id)
 
 	dev->data->dev_started = 0;
 	(*dev->dev_ops->dev_stop)(dev);
+	rte_trace_lib_ethdev_stop(port_id);
 }
 
 int
@@ -1709,6 +1716,7 @@ rte_eth_dev_close(uint16_t port_id)
 	dev->data->dev_started = 0;
 	(*dev->dev_ops->dev_close)(dev);
 
+	rte_trace_lib_ethdev_close(port_id);
 	/* check behaviour flag - temporary for PMD migration */
 	if ((dev->data->dev_flags & RTE_ETH_DEV_CLOSE_REMOVE) != 0) {
 		/* new behaviour: send event + reset state + free all data */
@@ -1918,6 +1926,8 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 			dev->data->min_rx_buf_size = mbp_buf_size;
 	}
 
+	rte_trace_lib_ethdev_rxq_setup(port_id, rx_queue_id, nb_rx_desc, mp,
+				       rx_conf, ret);
 	return eth_err(port_id, ret);
 }
 
@@ -2088,6 +2098,8 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 		return -EINVAL;
 	}
 
+	rte_trace_lib_ethdev_txq_setup(port_id, tx_queue_id, nb_tx_desc,
+				       tx_conf);
 	return eth_err(port_id, (*dev->dev_ops->tx_queue_setup)(dev,
 		       tx_queue_id, nb_tx_desc, socket_id, &local_conf));
 }
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index d1a593ad1..17cd1dda3 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -158,6 +158,7 @@ extern "C" {
 #include <rte_config.h>
 #include <rte_ether.h>
 
+#include "rte_trace_ethdev_fp.h"
 #include "rte_dev_info.h"
 
 extern int rte_eth_dev_logtype;
@@ -4400,6 +4401,8 @@ rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id,
 	}
 #endif
 
+	rte_trace_lib_ethdev_rx_burst(port_id, queue_id, (void **)rx_pkts,
+				      nb_rx);
 	return nb_rx;
 }
 
@@ -4663,6 +4666,8 @@ rte_eth_tx_burst(uint16_t port_id, uint16_t queue_id,
 	}
 #endif
 
+	rte_trace_lib_ethdev_tx_burst(port_id, queue_id, (void **)tx_pkts,
+				      nb_pkts);
 	return (*dev->tx_pkt_burst)(dev->data->tx_queues[queue_id], tx_pkts, nb_pkts);
 }
 
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 3f32fdecf..28c07117c 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -230,4 +230,14 @@ EXPERIMENTAL {
 
 	# added in 20.02
 	rte_flow_dev_dump;
+
+	# added in 20.05
+	__rte_trace_lib_ethdev_configure;
+	__rte_trace_lib_ethdev_rxq_setup;
+	__rte_trace_lib_ethdev_txq_setup;
+	__rte_trace_lib_ethdev_start;
+	__rte_trace_lib_ethdev_stop;
+	__rte_trace_lib_ethdev_close;
+	__rte_trace_lib_ethdev_rx_burst;
+	__rte_trace_lib_ethdev_tx_burst;
 };
diff --git a/lib/librte_ethdev/rte_trace_ethdev.h b/lib/librte_ethdev/rte_trace_ethdev.h
new file mode 100644
index 000000000..060779a1d
--- /dev/null
+++ b/lib/librte_ethdev/rte_trace_ethdev.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_ETHDEV_H_
+#define _RTE_TRACE_ETHDEV_H_
+
+/**
+ * @file
+ *
+ * API for ethdev trace support
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "rte_ethdev.h"
+
+#include <rte_trace.h>
+
+RTE_TRACE_POINT(
+	rte_trace_lib_ethdev_configure,
+	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t nb_rx_q,
+			     uint16_t nb_tx_q,
+			     const struct rte_eth_conf *dev_conf,
+			     int rc),
+	rte_trace_ctf_u16(port_id); rte_trace_ctf_u16(nb_rx_q);
+	rte_trace_ctf_u16(nb_tx_q); rte_trace_ctf_u32(dev_conf->link_speeds);
+	rte_trace_ctf_u32(dev_conf->rxmode.mq_mode);
+	rte_trace_ctf_u32(dev_conf->rxmode.max_rx_pkt_len);
+	rte_trace_ctf_u64(dev_conf->rxmode.offloads);
+	rte_trace_ctf_u32(dev_conf->txmode.mq_mode);
+	rte_trace_ctf_u64(dev_conf->txmode.offloads);
+	rte_trace_ctf_u32(dev_conf->lpbk_mode); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_ethdev_rxq_setup,
+	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t rx_queue_id,
+			     uint16_t nb_rx_desc, void *mp,
+			     const struct rte_eth_rxconf *rx_conf, int rc),
+	rte_trace_ctf_u16(port_id); rte_trace_ctf_u16(rx_queue_id);
+	rte_trace_ctf_u16(nb_rx_desc); rte_trace_ctf_ptr(mp);
+	rte_trace_ctf_u8(rx_conf->rx_thresh.pthresh);
+	rte_trace_ctf_u8(rx_conf->rx_thresh.hthresh);
+	rte_trace_ctf_u8(rx_conf->rx_thresh.wthresh);
+	rte_trace_ctf_u8(rx_conf->rx_drop_en);
+	rte_trace_ctf_u8(rx_conf->rx_deferred_start);
+	rte_trace_ctf_u64(rx_conf->offloads); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_ethdev_txq_setup,
+	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t tx_queue_id,
+			     uint16_t nb_tx_desc,
+			     const struct rte_eth_txconf *tx_conf),
+	rte_trace_ctf_u16(port_id); rte_trace_ctf_u16(tx_queue_id);
+	rte_trace_ctf_u16(nb_tx_desc);
+	rte_trace_ctf_u8(tx_conf->tx_thresh.pthresh);
+	rte_trace_ctf_u8(tx_conf->tx_thresh.hthresh);
+	rte_trace_ctf_u8(tx_conf->tx_thresh.wthresh);
+	rte_trace_ctf_u8(tx_conf->tx_deferred_start);
+	rte_trace_ctf_u16(tx_conf->tx_free_thresh);
+	rte_trace_ctf_u64(tx_conf->offloads);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_ethdev_start,
+	RTE_TRACE_POINT_ARGS(uint16_t port_id),
+	rte_trace_ctf_u16(port_id);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_ethdev_stop,
+	RTE_TRACE_POINT_ARGS(uint16_t port_id),
+	rte_trace_ctf_u16(port_id);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_ethdev_close,
+	RTE_TRACE_POINT_ARGS(uint16_t port_id),
+	rte_trace_ctf_u16(port_id);
+)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TRACE_ETHDEV_H_ */
diff --git a/lib/librte_ethdev/rte_trace_ethdev_fp.h b/lib/librte_ethdev/rte_trace_ethdev_fp.h
new file mode 100644
index 000000000..c34e7af66
--- /dev/null
+++ b/lib/librte_ethdev/rte_trace_ethdev_fp.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_ETHDEV_FP_H_
+#define _RTE_TRACE_ETHDEV_FP_H_
+
+/**
+ * @file
+ *
+ * API for ethdev trace support
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_trace.h>
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_ethdev_rx_burst,
+	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t queue_id,
+			     void **pkt_tbl, uint16_t nb_rx),
+	rte_trace_ctf_u16(port_id); rte_trace_ctf_u16(queue_id);
+	rte_trace_ctf_ptr(pkt_tbl); rte_trace_ctf_u16(nb_rx);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_ethdev_tx_burst,
+	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t queue_id,
+			     void **pkts_tbl, uint16_t nb_pkts),
+	rte_trace_ctf_u16(port_id); rte_trace_ctf_u16(queue_id);
+	rte_trace_ctf_ptr(pkts_tbl); rte_trace_ctf_u16(nb_pkts);
+)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TRACE_ETHDEV_FP_H_ */
diff --git a/lib/librte_gro/Makefile b/lib/librte_gro/Makefile
index e848687ac..c5ec134a4 100644
--- a/lib/librte_gro/Makefile
+++ b/lib/librte_gro/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_gro.a
 
 CFLAGS += -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_ethdev -lrte_net
 
diff --git a/lib/librte_gro/meson.build b/lib/librte_gro/meson.build
index 501668c8a..da68e70dd 100644
--- a/lib/librte_gro/meson.build
+++ b/lib/librte_gro/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_gro.c', 'gro_tcp4.c', 'gro_vxlan_tcp4.c')
 headers = files('rte_gro.h')
 deps += ['ethdev']
diff --git a/lib/librte_gso/Makefile b/lib/librte_gso/Makefile
index a34846e92..78005bc13 100644
--- a/lib/librte_gso/Makefile
+++ b/lib/librte_gso/Makefile
@@ -6,6 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 # library name
 LIB = librte_gso.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_ethdev -lrte_net
 LDLIBS += -lrte_mempool
diff --git a/lib/librte_gso/meson.build b/lib/librte_gso/meson.build
index ad8dd8583..c2b628bb2 100644
--- a/lib/librte_gso/meson.build
+++ b/lib/librte_gso/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('gso_common.c', 'gso_tcp4.c', 'gso_udp4.c',
  		'gso_tunnel_tcp4.c', 'rte_gso.c')
 headers = files('rte_gso.h')
diff --git a/lib/librte_kni/Makefile b/lib/librte_kni/Makefile
index 9d440aa13..dbccdc2ba 100644
--- a/lib/librte_kni/Makefile
+++ b/lib/librte_kni/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_kni.a
 
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3 -fno-strict-aliasing
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev
 
 EXPORT_MAP := rte_kni_version.map
diff --git a/lib/librte_kni/meson.build b/lib/librte_kni/meson.build
index 963eae6fe..8c1c7407e 100644
--- a/lib/librte_kni/meson.build
+++ b/lib/librte_kni/meson.build
@@ -5,6 +5,7 @@ if not is_linux or not dpdk_conf.get('RTE_ARCH_64')
 	build = false
 	reason = 'only supported on 64-bit linux'
 endif
+allow_experimental_apis = true
 sources = files('rte_kni.c')
 headers = files('rte_kni.h')
 deps += ['ethdev', 'pci']
diff --git a/lib/librte_latencystats/Makefile b/lib/librte_latencystats/Makefile
index b19e0b178..ad6b9fb22 100644
--- a/lib/librte_latencystats/Makefile
+++ b/lib/librte_latencystats/Makefile
@@ -6,6 +6,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 # library name
 LIB = librte_latencystats.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
 LDLIBS += -lm
 LDLIBS += -lpthread
diff --git a/lib/librte_latencystats/meson.build b/lib/librte_latencystats/meson.build
index 286558dd7..578d26554 100644
--- a/lib/librte_latencystats/meson.build
+++ b/lib/librte_latencystats/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_latencystats.c')
 headers = files('rte_latencystats.h')
 deps += ['metrics', 'ethdev']
diff --git a/lib/librte_port/Makefile b/lib/librte_port/Makefile
index 57d2aedbc..34d5b04c1 100644
--- a/lib/librte_port/Makefile
+++ b/lib/librte_port/Makefile
@@ -18,6 +18,7 @@ endif
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_port_version.map
 
diff --git a/lib/librte_port/meson.build b/lib/librte_port/meson.build
index 0d5ede44a..e15b69b38 100644
--- a/lib/librte_port/meson.build
+++ b/lib/librte_port/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files(
 	'rte_port_ethdev.c',
 	'rte_port_fd.c',
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 29/32] eventdev: add tracepoints
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (27 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 28/32] ethdev: add tracepoints jerinj
@ 2020-03-18 19:02 ` " jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 30/32] cryptodev: " jerinj
                   ` (3 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Thomas Monjalon, Jerin Jacob, Sunil Kumar Kori,
	Abhinandan Gujjar, Nikhil Rao, Erik Gabriel Carrillo
  Cc: dev, bruce.richardson, david.marchand, mattias.ronnblom

From: Sunil Kumar Kori <skori@marvell.com>

Add tracepoints at important and mandatory APIs for tracing support.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 MAINTAINERS                                   |   2 +
 drivers/event/skeleton/Makefile               |   1 +
 drivers/event/skeleton/meson.build            |   1 +
 lib/librte_eventdev/Makefile                  |   3 +
 lib/librte_eventdev/eventdev_trace_points.c   | 173 +++++++++++
 lib/librte_eventdev/meson.build               |   3 +
 .../rte_event_crypto_adapter.c                |  10 +
 .../rte_event_eth_rx_adapter.c                |  11 +
 .../rte_event_eth_tx_adapter.c                |  13 +-
 .../rte_event_eth_tx_adapter.h                |   2 +
 lib/librte_eventdev/rte_event_timer_adapter.c |   8 +-
 lib/librte_eventdev/rte_event_timer_adapter.h |   8 +
 lib/librte_eventdev/rte_eventdev.c            |   9 +
 lib/librte_eventdev/rte_eventdev.h            |   5 +-
 lib/librte_eventdev/rte_eventdev_version.map  |  42 +++
 lib/librte_eventdev/rte_trace_eventdev.h      | 278 ++++++++++++++++++
 lib/librte_eventdev/rte_trace_eventdev_fp.h   |  75 +++++
 17 files changed, 640 insertions(+), 4 deletions(-)
 create mode 100644 lib/librte_eventdev/eventdev_trace_points.c
 create mode 100644 lib/librte_eventdev/rte_trace_eventdev.h
 create mode 100644 lib/librte_eventdev/rte_trace_eventdev_fp.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a1d3e3746..7e2d42da3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -204,6 +204,8 @@ F: lib/librte_eal/common/eal_common_trace*.c
 F: lib/librte_eal/common/eal_trace.h
 F: lib/librte_ethdev/ethdev_trace_points.c
 F: lib/librte_ethdev/rte_trace_ethdev*.h
+F: lib/librte_eventdev/eventdev_trace_points.c
+F: lib/librte_eventdev/rte_trace_eventdev*.h
 
 Memory Allocation
 M: Anatoly Burakov <anatoly.burakov@intel.com>
diff --git a/drivers/event/skeleton/Makefile b/drivers/event/skeleton/Makefile
index dc85ad3c4..8c561fff0 100644
--- a/drivers/event/skeleton/Makefile
+++ b/drivers/event/skeleton/Makefile
@@ -10,6 +10,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_pmd_skeleton_event.a
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_eventdev
 LDLIBS += -lrte_pci -lrte_bus_pci
 LDLIBS += -lrte_bus_vdev
diff --git a/drivers/event/skeleton/meson.build b/drivers/event/skeleton/meson.build
index acfe15653..ebe3259f9 100644
--- a/drivers/event/skeleton/meson.build
+++ b/drivers/event/skeleton/meson.build
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('skeleton_eventdev.c')
 deps += ['bus_pci', 'bus_vdev']
diff --git a/lib/librte_eventdev/Makefile b/lib/librte_eventdev/Makefile
index 1052ccdbb..97193a1d5 100644
--- a/lib/librte_eventdev/Makefile
+++ b/lib/librte_eventdev/Makefile
@@ -22,6 +22,7 @@ LDLIBS += -lrte_mbuf -lrte_cryptodev -lpthread
 # library source files
 SRCS-y += rte_eventdev.c
 SRCS-y += rte_event_ring.c
+SRCS-y += eventdev_trace_points.c
 SRCS-y += rte_event_eth_rx_adapter.c
 SRCS-y += rte_event_timer_adapter.c
 SRCS-y += rte_event_crypto_adapter.c
@@ -30,6 +31,8 @@ SRCS-y += rte_event_eth_tx_adapter.c
 # export include files
 SYMLINK-y-include += rte_eventdev.h
 SYMLINK-y-include += rte_eventdev_pmd.h
+SYMLINK-y-include += rte_trace_eventdev.h
+SYMLINK-y-include += rte_trace_eventdev_fp.h
 SYMLINK-y-include += rte_eventdev_pmd_pci.h
 SYMLINK-y-include += rte_eventdev_pmd_vdev.h
 SYMLINK-y-include += rte_event_ring.h
diff --git a/lib/librte_eventdev/eventdev_trace_points.c b/lib/librte_eventdev/eventdev_trace_points.c
new file mode 100644
index 000000000..be9ce5ffe
--- /dev/null
+++ b/lib/librte_eventdev/eventdev_trace_points.c
@@ -0,0 +1,173 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#define RTE_TRACE_POINT_REGISTER_SELECT /* Select trace point register macros */
+
+#include "rte_trace_eventdev.h"
+
+/* Eventdev trace points */
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eventdev_configure);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_queue_setup);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_port_setup);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_port_link);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_port_unlink);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eventdev_start);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eventdev_stop);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eventdev_close);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_enq_burst);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_deq_burst);
+
+/* Eventdev Rx adapter trace points */
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_rx_adapter_create);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_rx_adapter_free);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_rx_adapter_queue_add);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_rx_adapter_queue_del);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_rx_adapter_start);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_rx_adapter_stop);
+
+/* Eventdev Tx adapter trace points */
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_tx_adapter_create);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_tx_adapter_free);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_tx_adapter_queue_add);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_tx_adapter_queue_del);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_tx_adapter_start);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_tx_adapter_stop);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_eth_tx_adapter_enqueue);
+
+/* Eventdev Timer adapter trace points */
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_timer_adapter_create);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_timer_adapter_start);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_timer_adapter_stop);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_timer_adapter_free);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_timer_arm_burst);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_timer_arm_tmo_tick_burst);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_timer_cancel_burst);
+
+/* Eventdev Crypto adapter trace points */
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_crypto_adapter_create);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_crypto_adapter_free);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_crypto_adapter_queue_pair_add);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_crypto_adapter_queue_pair_del);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_crypto_adapter_start);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_event_crypto_adapter_stop);
+
+RTE_INIT(eventdev_trace_init)
+{
+	/* Eventdev trace points */
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eventdev_configure,
+				 lib.eventdev.configure, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_queue_setup,
+				 lib.eventdev.queue.setup, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_port_setup,
+				 lib.eventdev.port.setup, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_port_link,
+				 lib.eventdev.port.link, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_port_unlink,
+				 lib.eventdev.port.unlink, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eventdev_start,
+				 lib.eventdev.start, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eventdev_stop,
+				 lib.eventdev.stop, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eventdev_close,
+				 lib.eventdev.close, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_enq_burst,
+				 lib.eventdev.enq.burst, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_deq_burst,
+				 lib.eventdev.deq.burst, INFO);
+
+
+	/* Eventdev Rx adapter trace points */
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_rx_adapter_create,
+				 lib.eventdev.rx.adapter.create, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_rx_adapter_free,
+				 lib.eventdev.rx.adapter.free, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_rx_adapter_queue_add,
+				 lib.eventdev.rx.adapter.queue.add, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_rx_adapter_queue_del,
+				 lib.eventdev.rx.adapter.queue.del, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_rx_adapter_start,
+				 lib.eventdev.rx.adapter.start, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_rx_adapter_stop,
+				 lib.eventdev.rx.adapter.stop, INFO);
+
+	/* Eventdev Tx adapter trace points */
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_tx_adapter_create,
+				 lib.eventdev.tx.adapter.create, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_tx_adapter_free,
+				 lib.eventdev.tx.adapter.free, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_tx_adapter_queue_add,
+				 lib.eventdev.tx.adapter.queue.add, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_tx_adapter_queue_del,
+				 lib.eventdev.tx.adapter.queue.del, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_tx_adapter_start,
+				 lib.eventdev.tx.adapter.start, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_tx_adapter_stop,
+				 lib.eventdev.tx.adapter.stop, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_eth_tx_adapter_enqueue,
+				 lib.eventdev.tx.adapter.enq, INFO);
+
+
+	/* Eventdev Timer adapter trace points */
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_timer_adapter_create,
+				 lib.eventdev.timer.create, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_timer_adapter_start,
+				 lib.eventdev.timer.start, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_timer_adapter_stop,
+				 lib.eventdev.timer.stop, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_timer_adapter_free,
+				 lib.eventdev.timer.free, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_timer_arm_burst,
+				 lib.eventdev.timer.burst, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_timer_arm_tmo_tick_burst,
+				 lib.eventdev.timer.tick.burst, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_timer_cancel_burst,
+				 lib.eventdev.timer.cancel, INFO);
+
+	/* Eventdev Crypto adapter trace points */
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_crypto_adapter_create,
+				 lib.eventdev.crypto.create, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_crypto_adapter_free,
+				 lib.eventdev.crypto.free, INFO);
+
+	RTE_TRACE_POINT_REGISTER(
+			rte_trace_lib_event_crypto_adapter_queue_pair_add,
+			lib.eventdev.crypto.queue.add, INFO);
+
+	RTE_TRACE_POINT_REGISTER(
+			rte_trace_lib_event_crypto_adapter_queue_pair_del,
+			lib.eventdev.crypto.queue.del, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_crypto_adapter_start,
+				 lib.eventdev.crypto.start, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_event_crypto_adapter_stop,
+				 lib.eventdev.crypto.stop, INFO);
+}
diff --git a/lib/librte_eventdev/meson.build b/lib/librte_eventdev/meson.build
index 02ac61ad2..7aeb0a097 100644
--- a/lib/librte_eventdev/meson.build
+++ b/lib/librte_eventdev/meson.build
@@ -11,12 +11,15 @@ endif
 
 sources = files('rte_eventdev.c',
 		'rte_event_ring.c',
+		'eventdev_trace_points.c',
 		'rte_event_eth_rx_adapter.c',
 		'rte_event_timer_adapter.c',
 		'rte_event_crypto_adapter.c',
 		'rte_event_eth_tx_adapter.c')
 headers = files('rte_eventdev.h',
 		'rte_eventdev_pmd.h',
+		'rte_trace_eventdev.h',
+		'rte_trace_eventdev_fp.h',
 		'rte_eventdev_pmd_pci.h',
 		'rte_eventdev_pmd_vdev.h',
 		'rte_event_ring.h',
diff --git a/lib/librte_eventdev/rte_event_crypto_adapter.c b/lib/librte_eventdev/rte_event_crypto_adapter.c
index 22d910816..5fbc75093 100644
--- a/lib/librte_eventdev/rte_event_crypto_adapter.c
+++ b/lib/librte_eventdev/rte_event_crypto_adapter.c
@@ -16,6 +16,7 @@
 
 #include "rte_eventdev.h"
 #include "rte_eventdev_pmd.h"
+#include "rte_trace_eventdev.h"
 #include "rte_event_crypto_adapter.h"
 
 #define BATCH_SIZE 32
@@ -267,6 +268,8 @@ rte_event_crypto_adapter_create_ext(uint8_t id, uint8_t dev_id,
 
 	event_crypto_adapter[id] = adapter;
 
+	rte_trace_lib_event_crypto_adapter_create(id, dev_id, adapter, conf_arg,
+						  mode);
 	return 0;
 }
 
@@ -314,6 +317,7 @@ rte_event_crypto_adapter_free(uint8_t id)
 		return -EBUSY;
 	}
 
+	rte_trace_lib_event_crypto_adapter_free(id, adapter);
 	if (adapter->default_cb_arg)
 		rte_free(adapter->conf_arg);
 	rte_free(adapter->cdevs);
@@ -874,6 +878,8 @@ rte_event_crypto_adapter_queue_pair_add(uint8_t id,
 		rte_service_component_runstate_set(adapter->service_id, 1);
 	}
 
+	rte_trace_lib_event_crypto_adapter_queue_pair_add(id, cdev_id, event,
+							  queue_pair_id);
 	return 0;
 }
 
@@ -959,6 +965,8 @@ rte_event_crypto_adapter_queue_pair_del(uint8_t id, uint8_t cdev_id,
 				adapter->nb_qps);
 	}
 
+	rte_trace_lib_event_crypto_adapter_queue_pair_del(id, cdev_id,
+							  queue_pair_id, ret);
 	return ret;
 }
 
@@ -1014,12 +1022,14 @@ rte_event_crypto_adapter_start(uint8_t id)
 	if (adapter == NULL)
 		return -EINVAL;
 
+	rte_trace_lib_event_crypto_adapter_start(id, adapter);
 	return eca_adapter_ctrl(id, 1);
 }
 
 int
 rte_event_crypto_adapter_stop(uint8_t id)
 {
+	rte_trace_lib_event_crypto_adapter_stop(id);
 	return eca_adapter_ctrl(id, 0);
 }
 
diff --git a/lib/librte_eventdev/rte_event_eth_rx_adapter.c b/lib/librte_eventdev/rte_event_eth_rx_adapter.c
index 95dd47820..aca4f9d8a 100644
--- a/lib/librte_eventdev/rte_event_eth_rx_adapter.c
+++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.c
@@ -20,6 +20,7 @@
 
 #include "rte_eventdev.h"
 #include "rte_eventdev_pmd.h"
+#include "rte_trace_eventdev.h"
 #include "rte_event_eth_rx_adapter.h"
 
 #define BATCH_SIZE		32
@@ -1998,6 +1999,8 @@ rte_event_eth_rx_adapter_create_ext(uint8_t id, uint8_t dev_id,
 	event_eth_rx_adapter[id] = rx_adapter;
 	if (conf_cb == rxa_default_conf_cb)
 		rx_adapter->default_cb_arg = 1;
+	rte_trace_lib_event_eth_rx_adapter_create(id, dev_id, conf_cb,
+						  conf_arg);
 	return 0;
 }
 
@@ -2047,6 +2050,7 @@ rte_event_eth_rx_adapter_free(uint8_t id)
 	rte_free(rx_adapter);
 	event_eth_rx_adapter[id] = NULL;
 
+	rte_trace_lib_event_eth_rx_adapter_free(id);
 	return 0;
 }
 
@@ -2142,6 +2146,9 @@ rte_event_eth_rx_adapter_queue_add(uint8_t id,
 		rte_spinlock_unlock(&rx_adapter->rx_lock);
 	}
 
+	rte_trace_lib_event_eth_rx_adapter_queue_add(id, eth_dev_id,
+						     rx_queue_id, queue_conf,
+						     ret);
 	if (ret)
 		return ret;
 
@@ -2263,18 +2270,22 @@ rte_event_eth_rx_adapter_queue_del(uint8_t id, uint16_t eth_dev_id,
 				rxa_sw_adapter_queue_count(rx_adapter));
 	}
 
+	rte_trace_lib_event_eth_rx_adapter_queue_del(id, eth_dev_id,
+						     rx_queue_id, ret);
 	return ret;
 }
 
 int
 rte_event_eth_rx_adapter_start(uint8_t id)
 {
+	rte_trace_lib_event_eth_rx_adapter_start(id);
 	return rxa_ctrl(id, 1);
 }
 
 int
 rte_event_eth_rx_adapter_stop(uint8_t id)
 {
+	rte_trace_lib_event_eth_rx_adapter_stop(id);
 	return rxa_ctrl(id, 0);
 }
 
diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.c b/lib/librte_eventdev/rte_event_eth_tx_adapter.c
index d02ef57f4..a6dbc655e 100644
--- a/lib/librte_eventdev/rte_event_eth_tx_adapter.c
+++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.c
@@ -6,6 +6,7 @@
 #include <rte_ethdev.h>
 
 #include "rte_eventdev_pmd.h"
+#include "rte_trace_eventdev.h"
 #include "rte_event_eth_tx_adapter.h"
 
 #define TXA_BATCH_SIZE		32
@@ -942,7 +943,8 @@ rte_event_eth_tx_adapter_create(uint8_t id, uint8_t dev_id,
 		txa_dev_id_array[id] = TXA_INVALID_DEV_ID;
 		return ret;
 	}
-
+	rte_trace_lib_event_eth_tx_adapter_create(id, dev_id, NULL, port_conf,
+						  ret);
 	txa_dev_id_array[id] = dev_id;
 	return 0;
 }
@@ -984,6 +986,8 @@ rte_event_eth_tx_adapter_create_ext(uint8_t id, uint8_t dev_id,
 		return ret;
 	}
 
+	rte_trace_lib_event_eth_tx_adapter_create(id, dev_id, conf_cb, conf_arg,
+						  ret);
 	txa_dev_id_array[id] = dev_id;
 	return 0;
 }
@@ -1012,6 +1016,7 @@ rte_event_eth_tx_adapter_free(uint8_t id)
 		ret = txa_service_adapter_free(id);
 	txa_dev_id_array[id] = TXA_INVALID_DEV_ID;
 
+	rte_trace_lib_event_eth_tx_adapter_free(id, ret);
 	return ret;
 }
 
@@ -1043,6 +1048,8 @@ rte_event_eth_tx_adapter_queue_add(uint8_t id,
 	else
 		ret = txa_service_queue_add(id, txa_evdev(id), eth_dev, queue);
 
+	rte_trace_lib_event_eth_tx_adapter_queue_add(id, eth_dev_id, queue,
+						     ret);
 	return ret;
 }
 
@@ -1073,6 +1080,8 @@ rte_event_eth_tx_adapter_queue_del(uint8_t id,
 	else
 		ret = txa_service_queue_del(id, eth_dev, queue);
 
+	rte_trace_lib_event_eth_tx_adapter_queue_del(id, eth_dev_id, queue,
+						     ret);
 	return ret;
 }
 
@@ -1094,6 +1103,7 @@ rte_event_eth_tx_adapter_start(uint8_t id)
 	ret = txa_dev_start(id) ? txa_dev_start(id)(id, txa_evdev(id)) : 0;
 	if (ret == 0)
 		ret = txa_service_start(id);
+	rte_trace_lib_event_eth_tx_adapter_start(id, ret);
 	return ret;
 }
 
@@ -1154,5 +1164,6 @@ rte_event_eth_tx_adapter_stop(uint8_t id)
 	ret = txa_dev_stop(id) ? txa_dev_stop(id)(id,  txa_evdev(id)) : 0;
 	if (ret == 0)
 		ret = txa_service_stop(id);
+	rte_trace_lib_event_eth_tx_adapter_stop(id, ret);
 	return ret;
 }
diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
index 93b717af9..f2154c01a 100644
--- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
+++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
@@ -369,6 +369,8 @@ rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
 		return 0;
 	}
 #endif
+	rte_trace_lib_event_eth_tx_adapter_enqueue(dev_id, port_id, ev,
+						   nb_events, flags);
 	if (flags)
 		return dev->txa_enqueue_same_dest(dev->data->ports[port_id],
 						  ev, nb_events);
diff --git a/lib/librte_eventdev/rte_event_timer_adapter.c b/lib/librte_eventdev/rte_event_timer_adapter.c
index 161e21a68..700e10afd 100644
--- a/lib/librte_eventdev/rte_event_timer_adapter.c
+++ b/lib/librte_eventdev/rte_event_timer_adapter.c
@@ -22,6 +22,7 @@
 
 #include "rte_eventdev.h"
 #include "rte_eventdev_pmd.h"
+#include "rte_trace_eventdev.h"
 #include "rte_event_timer_adapter.h"
 #include "rte_event_timer_adapter_pmd.h"
 
@@ -228,6 +229,8 @@ rte_event_timer_adapter_create_ext(
 
 	adapter->allocated = 1;
 
+	rte_trace_lib_event_timer_adapter_create(adapter_id, adapter, conf,
+						 conf_cb);
 	return adapter;
 
 free_memzone:
@@ -272,7 +275,7 @@ rte_event_timer_adapter_start(const struct rte_event_timer_adapter *adapter)
 		return ret;
 
 	adapter->data->started = 1;
-
+	rte_trace_lib_event_timer_adapter_start(adapter);
 	return 0;
 }
 
@@ -295,7 +298,7 @@ rte_event_timer_adapter_stop(const struct rte_event_timer_adapter *adapter)
 		return ret;
 
 	adapter->data->started = 0;
-
+	rte_trace_lib_event_timer_adapter_stop(adapter);
 	return 0;
 }
 
@@ -379,6 +382,7 @@ rte_event_timer_adapter_free(struct rte_event_timer_adapter *adapter)
 	adapter->data = NULL;
 	adapter->allocated = 0;
 
+	rte_trace_lib_event_timer_adapter_free(adapter);
 	return 0;
 }
 
diff --git a/lib/librte_eventdev/rte_event_timer_adapter.h b/lib/librte_eventdev/rte_event_timer_adapter.h
index 7f6dc5c29..d338b7738 100644
--- a/lib/librte_eventdev/rte_event_timer_adapter.h
+++ b/lib/librte_eventdev/rte_event_timer_adapter.h
@@ -115,6 +115,7 @@ extern "C" {
 #include <rte_memory.h>
 
 #include "rte_eventdev.h"
+#include "rte_trace_eventdev_fp.h"
 
 /**
  * Timer adapter clock source
@@ -579,6 +580,8 @@ rte_event_timer_arm_burst(const struct rte_event_timer_adapter *adapter,
 	ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
 	FUNC_PTR_OR_ERR_RET(adapter->arm_burst, -EINVAL);
 #endif
+	rte_trace_lib_event_timer_arm_burst(adapter, (void **)evtims,
+					    nb_evtims);
 	return adapter->arm_burst(adapter, evtims, nb_evtims);
 }
 
@@ -622,6 +625,9 @@ rte_event_timer_arm_tmo_tick_burst(
 	ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
 	FUNC_PTR_OR_ERR_RET(adapter->arm_tmo_tick_burst, -EINVAL);
 #endif
+	rte_trace_lib_event_timer_arm_tmo_tick_burst(adapter, timeout_ticks,
+						     (void **)evtims,
+						     nb_evtims);
 	return adapter->arm_tmo_tick_burst(adapter, evtims, timeout_ticks,
 					   nb_evtims);
 }
@@ -655,6 +661,8 @@ rte_event_timer_cancel_burst(const struct rte_event_timer_adapter *adapter,
 	ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
 	FUNC_PTR_OR_ERR_RET(adapter->cancel_burst, -EINVAL);
 #endif
+	rte_trace_lib_event_timer_cancel_burst(adapter, (void **)evtims,
+					       nb_evtims);
 	return adapter->cancel_burst(adapter, evtims, nb_evtims);
 }
 
diff --git a/lib/librte_eventdev/rte_eventdev.c b/lib/librte_eventdev/rte_eventdev.c
index b987e0745..d0a3bdd7f 100644
--- a/lib/librte_eventdev/rte_eventdev.c
+++ b/lib/librte_eventdev/rte_eventdev.c
@@ -35,6 +35,7 @@
 
 #include "rte_eventdev.h"
 #include "rte_eventdev_pmd.h"
+#include "rte_trace_eventdev.h"
 
 static struct rte_eventdev rte_event_devices[RTE_EVENT_MAX_DEVS];
 
@@ -524,6 +525,7 @@ rte_event_dev_configure(uint8_t dev_id,
 	}
 
 	dev->data->event_dev_cap = info.event_dev_cap;
+	rte_trace_lib_eventdev_configure(dev_id, dev_conf, diag);
 	return diag;
 }
 
@@ -650,6 +652,7 @@ rte_event_queue_setup(uint8_t dev_id, uint8_t queue_id,
 	}
 
 	dev->data->queues_cfg[queue_id] = *queue_conf;
+	rte_trace_lib_event_queue_setup(dev_id, queue_id, queue_conf);
 	return (*dev->dev_ops->queue_setup)(dev, queue_id, queue_conf);
 }
 
@@ -766,6 +769,7 @@ rte_event_port_setup(uint8_t dev_id, uint8_t port_id,
 	if (!diag)
 		diag = rte_event_port_unlink(dev_id, port_id, NULL, 0);
 
+	rte_trace_lib_event_port_setup(dev_id, port_id, port_conf, diag);
 	if (diag < 0)
 		return diag;
 
@@ -936,6 +940,7 @@ rte_event_port_link(uint8_t dev_id, uint8_t port_id,
 	for (i = 0; i < diag; i++)
 		links_map[queues[i]] = (uint8_t)priorities[i];
 
+	rte_trace_lib_event_port_link(dev_id, port_id, nb_links, diag);
 	return diag;
 }
 
@@ -1001,6 +1006,7 @@ rte_event_port_unlink(uint8_t dev_id, uint8_t port_id,
 	for (i = 0; i < diag; i++)
 		links_map[queues[i]] = EVENT_QUEUE_SERVICE_PRIORITY_INVALID;
 
+	rte_trace_lib_event_port_unlink(dev_id, port_id, nb_unlinks, diag);
 	return diag;
 }
 
@@ -1213,6 +1219,7 @@ rte_event_dev_start(uint8_t dev_id)
 	}
 
 	diag = (*dev->dev_ops->dev_start)(dev);
+	rte_trace_lib_eventdev_start(dev_id, diag);
 	if (diag == 0)
 		dev->data->dev_started = 1;
 	else
@@ -1257,6 +1264,7 @@ rte_event_dev_stop(uint8_t dev_id)
 
 	dev->data->dev_started = 0;
 	(*dev->dev_ops->dev_stop)(dev);
+	rte_trace_lib_eventdev_stop(dev_id);
 }
 
 int
@@ -1275,6 +1283,7 @@ rte_event_dev_close(uint8_t dev_id)
 		return -EBUSY;
 	}
 
+	rte_trace_lib_eventdev_close(dev_id);
 	return (*dev->dev_ops->dev_close)(dev);
 }
 
diff --git a/lib/librte_eventdev/rte_eventdev.h b/lib/librte_eventdev/rte_eventdev.h
index 226f352ad..71d4fa6f1 100644
--- a/lib/librte_eventdev/rte_eventdev.h
+++ b/lib/librte_eventdev/rte_eventdev.h
@@ -215,6 +215,8 @@ extern "C" {
 #include <rte_memory.h>
 #include <rte_errno.h>
 
+#include "rte_trace_eventdev_fp.h"
+
 struct rte_mbuf; /* we just use mbuf pointers; no need to include rte_mbuf.h */
 struct rte_event;
 
@@ -1343,6 +1345,7 @@ __rte_event_enqueue_burst(uint8_t dev_id, uint8_t port_id,
 		return 0;
 	}
 #endif
+	rte_trace_lib_event_enq_burst(dev_id, port_id, ev, nb_events, fn);
 	/*
 	 * Allow zero cost non burst mode routine invocation if application
 	 * requests nb_events as const one
@@ -1620,7 +1623,7 @@ rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[],
 		return 0;
 	}
 #endif
-
+	rte_trace_lib_event_deq_burst(dev_id, port_id, ev, nb_events);
 	/*
 	 * Allow zero cost non burst mode routine invocation if application
 	 * requests nb_events as const one
diff --git a/lib/librte_eventdev/rte_eventdev_version.map b/lib/librte_eventdev/rte_eventdev_version.map
index edfc15282..25023d9c2 100644
--- a/lib/librte_eventdev/rte_eventdev_version.map
+++ b/lib/librte_eventdev/rte_eventdev_version.map
@@ -93,3 +93,45 @@ DPDK_20.0 {
 
 	local: *;
 };
+
+EXPERIMENTAL {
+	global:
+
+	# added in 20.05
+	__rte_trace_lib_eventdev_configure;
+	__rte_trace_lib_event_queue_setup;
+	__rte_trace_lib_event_port_setup;
+	__rte_trace_lib_event_port_link;
+	__rte_trace_lib_event_port_unlink;
+	__rte_trace_lib_eventdev_start;
+	__rte_trace_lib_eventdev_stop;
+	__rte_trace_lib_eventdev_close;
+	__rte_trace_lib_event_deq_burst;
+	__rte_trace_lib_event_enq_burst;
+	__rte_trace_lib_event_eth_rx_adapter_create;
+	__rte_trace_lib_event_eth_rx_adapter_free;
+	__rte_trace_lib_event_eth_rx_adapter_queue_add;
+	__rte_trace_lib_event_eth_rx_adapter_queue_del;
+	__rte_trace_lib_event_eth_rx_adapter_start;
+	__rte_trace_lib_event_eth_rx_adapter_stop;
+	__rte_trace_lib_event_eth_tx_adapter_create;
+	__rte_trace_lib_event_eth_tx_adapter_free;
+	__rte_trace_lib_event_eth_tx_adapter_queue_add;
+	__rte_trace_lib_event_eth_tx_adapter_queue_del;
+	__rte_trace_lib_event_eth_tx_adapter_start;
+	__rte_trace_lib_event_eth_tx_adapter_stop;
+	__rte_trace_lib_event_eth_tx_adapter_enqueue;
+	__rte_trace_lib_event_timer_adapter_create;
+	__rte_trace_lib_event_timer_adapter_start;
+	__rte_trace_lib_event_timer_adapter_stop;
+	__rte_trace_lib_event_timer_adapter_free;
+	__rte_trace_lib_event_timer_arm_burst;
+	__rte_trace_lib_event_timer_arm_tmo_tick_burst;
+	__rte_trace_lib_event_timer_cancel_burst;
+	__rte_trace_lib_event_crypto_adapter_create;
+	__rte_trace_lib_event_crypto_adapter_free;
+	__rte_trace_lib_event_crypto_adapter_queue_pair_add;
+	__rte_trace_lib_event_crypto_adapter_queue_pair_del;
+	__rte_trace_lib_event_crypto_adapter_start;
+	__rte_trace_lib_event_crypto_adapter_stop;
+};
diff --git a/lib/librte_eventdev/rte_trace_eventdev.h b/lib/librte_eventdev/rte_trace_eventdev.h
new file mode 100644
index 000000000..f5b0fb158
--- /dev/null
+++ b/lib/librte_eventdev/rte_trace_eventdev.h
@@ -0,0 +1,278 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_EVENTDEV_H_
+#define _RTE_TRACE_EVENTDEV_H_
+
+/**
+ * @file
+ *
+ * API for ethdev trace support
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "rte_eventdev.h"
+#include "rte_event_eth_rx_adapter.h"
+#include "rte_event_timer_adapter.h"
+
+#include <rte_trace.h>
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eventdev_configure,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id,
+			     const struct rte_event_dev_config *dev_conf,
+			     int rc),
+	rte_trace_ctf_u8(dev_id);
+	rte_trace_ctf_u32(dev_conf->dequeue_timeout_ns);
+	rte_trace_ctf_i32(dev_conf->nb_events_limit);
+	rte_trace_ctf_u8(dev_conf->nb_event_queues);
+	rte_trace_ctf_u8(dev_conf->nb_event_ports);
+	rte_trace_ctf_u32(dev_conf->nb_event_queue_flows);
+	rte_trace_ctf_u32(dev_conf->nb_event_port_dequeue_depth);
+	rte_trace_ctf_u32(dev_conf->nb_event_port_enqueue_depth);
+	rte_trace_ctf_u32(dev_conf->event_dev_cfg);
+	rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_queue_setup,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t queue_id,
+			     const struct rte_event_queue_conf *queue_conf),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_u8(queue_id);
+	rte_trace_ctf_u32(queue_conf->nb_atomic_flows);
+	rte_trace_ctf_u32(queue_conf->nb_atomic_order_sequences);
+	rte_trace_ctf_u32(queue_conf->event_queue_cfg);
+	rte_trace_ctf_u8(queue_conf->schedule_type);
+	rte_trace_ctf_u8(queue_conf->priority);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_port_setup,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id,
+			     const struct rte_event_port_conf *port_conf,
+			     int rc),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_u8(port_id);
+	rte_trace_ctf_i32(port_conf->new_event_threshold);
+	rte_trace_ctf_u16(port_conf->dequeue_depth);
+	rte_trace_ctf_u16(port_conf->enqueue_depth);
+	rte_trace_ctf_u8(port_conf->disable_implicit_release);
+	rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_port_link,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id,
+			     uint16_t nb_links, int rc),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_u8(port_id);
+	rte_trace_ctf_u16(nb_links); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_port_unlink,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id,
+			     uint16_t nb_unlinks, int rc),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_u8(port_id);
+	rte_trace_ctf_u16(nb_unlinks); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eventdev_start,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, int rc),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eventdev_stop,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id),
+	rte_trace_ctf_u8(dev_id);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eventdev_close,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id),
+	rte_trace_ctf_u8(dev_id);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_eth_rx_adapter_create,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, uint8_t dev_id,
+			     void *conf_cb, void *conf_arg),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_u8(dev_id);
+	rte_trace_ctf_ptr(conf_cb); rte_trace_ctf_ptr(conf_arg);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_eth_rx_adapter_free,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id),
+	rte_trace_ctf_u8(adptr_id);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_eth_rx_adapter_queue_add,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, uint16_t eth_dev_id,
+			     int32_t rx_queue_id,
+			     const struct rte_event_eth_rx_adapter_queue_conf
+			     *queue_conf, int rc),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_u16(eth_dev_id);
+	rte_trace_ctf_i32(rx_queue_id);
+	rte_trace_ctf_u32(queue_conf->rx_queue_flags);
+	rte_trace_ctf_u16(queue_conf->servicing_weight);
+	rte_trace_ctf_u8(queue_conf->ev.queue_id);
+	rte_trace_ctf_u8(queue_conf->ev.priority);
+	rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_eth_rx_adapter_queue_del,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, uint16_t eth_dev_id,
+			     int32_t rx_queue_id, int rc),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_u16(eth_dev_id);
+	rte_trace_ctf_i32(rx_queue_id); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_eth_rx_adapter_start,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id),
+	rte_trace_ctf_u8(adptr_id);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_eth_rx_adapter_stop,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id),
+	rte_trace_ctf_u8(adptr_id);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_eth_tx_adapter_create,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, uint8_t dev_id, void *conf_cb,
+			     struct rte_event_port_conf *port_conf,
+			     int rc),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_u8(dev_id);
+	rte_trace_ctf_i32(port_conf->new_event_threshold);
+	rte_trace_ctf_u16(port_conf->dequeue_depth);
+	rte_trace_ctf_u16(port_conf->enqueue_depth);
+	rte_trace_ctf_u8(port_conf->disable_implicit_release);
+	rte_trace_ctf_ptr(conf_cb); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_eth_tx_adapter_free,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, int rc),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_eth_tx_adapter_queue_add,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, uint16_t eth_dev_id,
+			     int32_t queue, int rc),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_u16(eth_dev_id);
+	rte_trace_ctf_i32(queue); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_eth_tx_adapter_queue_del,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, uint16_t eth_dev_id,
+			     int32_t queue, int rc),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_u16(eth_dev_id);
+	rte_trace_ctf_i32(queue); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_eth_tx_adapter_start,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, int rc),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_eth_tx_adapter_stop,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, int rc),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_timer_adapter_create,
+	RTE_TRACE_POINT_ARGS(uint16_t adapter_id, void *adapter,
+			     const struct rte_event_timer_adapter_conf *conf,
+			     void *conf_cb),
+	rte_trace_ctf_u16(adapter_id); rte_trace_ctf_ptr(adapter);
+	rte_trace_ctf_ptr(conf); rte_trace_ctf_u8(conf->event_dev_id);
+	rte_trace_ctf_u16(conf->timer_adapter_id);
+	rte_trace_ctf_u64(conf->timer_tick_ns);
+	rte_trace_ctf_u64(conf->max_tmo_ns); rte_trace_ctf_u64(conf->nb_timers);
+	rte_trace_ctf_u64(conf->flags); rte_trace_ctf_ptr(conf_cb);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_timer_adapter_start,
+	RTE_TRACE_POINT_ARGS(const void *adapter),
+	rte_trace_ctf_ptr(adapter);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_timer_adapter_stop,
+	RTE_TRACE_POINT_ARGS(const void *adapter),
+	rte_trace_ctf_ptr(adapter);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_timer_adapter_free,
+	RTE_TRACE_POINT_ARGS(void *adapter),
+	rte_trace_ctf_ptr(adapter);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_crypto_adapter_create,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, uint8_t dev_id, void *adapter,
+			     struct rte_event_port_conf *port_conf,
+			     uint8_t mode),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_u8(dev_id);
+	rte_trace_ctf_ptr(adapter); rte_trace_ctf_u8(mode);
+	rte_trace_ctf_i32(port_conf->new_event_threshold);
+	rte_trace_ctf_u16(port_conf->dequeue_depth);
+	rte_trace_ctf_u16(port_conf->enqueue_depth);
+	rte_trace_ctf_u8(port_conf->disable_implicit_release);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_crypto_adapter_free,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, void *adapter),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_ptr(adapter);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_crypto_adapter_queue_pair_add,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, uint8_t cdev_id,
+			     const void *event, int32_t queue_pair_id),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_u8(cdev_id);
+	rte_trace_ctf_i32(queue_pair_id); rte_trace_ctf_ptr(event);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_crypto_adapter_queue_pair_del,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, uint8_t cdev_id,
+			     int32_t queue_pair_id, int rc),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_u8(cdev_id);
+	rte_trace_ctf_i32(queue_pair_id); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_crypto_adapter_start,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id, void *adapter),
+	rte_trace_ctf_u8(adptr_id); rte_trace_ctf_ptr(adapter);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_event_crypto_adapter_stop,
+	RTE_TRACE_POINT_ARGS(uint8_t adptr_id),
+	rte_trace_ctf_u8(adptr_id);
+)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TRACE_EVENTDEV_H_ */
diff --git a/lib/librte_eventdev/rte_trace_eventdev_fp.h b/lib/librte_eventdev/rte_trace_eventdev_fp.h
new file mode 100644
index 000000000..71da9f6ba
--- /dev/null
+++ b/lib/librte_eventdev/rte_trace_eventdev_fp.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_EVENTDEV_FP_H_
+#define _RTE_TRACE_EVENTDEV_FP_H_
+
+/**
+ * @file
+ *
+ * API for ethdev trace support
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_trace.h>
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_event_deq_burst,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id, void *ev_table,
+			     uint16_t nb_events),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_u8(port_id);
+	rte_trace_ctf_ptr(ev_table); rte_trace_ctf_u16(nb_events);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_event_enq_burst,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id,
+			     const void *ev_table, uint16_t nb_events,
+			     void *enq_mode_cb),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_u8(port_id);
+	rte_trace_ctf_ptr(ev_table); rte_trace_ctf_u16(nb_events);
+	rte_trace_ctf_ptr(enq_mode_cb);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_event_eth_tx_adapter_enqueue,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id, void *ev_table,
+			     uint16_t nb_events, const uint8_t flags),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_u8(port_id);
+	rte_trace_ctf_ptr(ev_table); rte_trace_ctf_u16(nb_events);
+	rte_trace_ctf_u8(flags);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_event_timer_arm_burst,
+	RTE_TRACE_POINT_ARGS(const void *adapter, void **evtims_table,
+			     uint16_t nb_evtims),
+	rte_trace_ctf_ptr(adapter); rte_trace_ctf_ptr(evtims_table);
+	rte_trace_ctf_u16(nb_evtims);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_event_timer_arm_tmo_tick_burst,
+	RTE_TRACE_POINT_ARGS(const void *adapter, const uint64_t timeout_ticks,
+			     void **evtims_table, const uint16_t nb_evtims),
+	rte_trace_ctf_ptr(adapter); rte_trace_ctf_u64(timeout_ticks);
+	rte_trace_ctf_ptr(evtims_table); rte_trace_ctf_u16(nb_evtims);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_event_timer_cancel_burst,
+	RTE_TRACE_POINT_ARGS(const void *adapter, void **evtims_table,
+			     uint16_t nb_evtims),
+	rte_trace_ctf_ptr(adapter); rte_trace_ctf_ptr(evtims_table);
+	rte_trace_ctf_u16(nb_evtims);
+)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TRACE_EVENTDEV_FP_H_ */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 30/32] cryptodev: add tracepoints
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (28 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 29/32] eventdev: " jerinj
@ 2020-03-18 19:02 ` " jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 31/32] mempool: " jerinj
                   ` (2 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Thomas Monjalon, Ravi Kumar, Tomasz Duszynski, Michael Shamis,
	Liron Himi, Declan Doherty, Fan Zhang, Jay Zhou, Jerin Jacob,
	Sunil Kumar Kori
  Cc: dev, bruce.richardson, david.marchand, mattias.ronnblom

From: Sunil Kumar Kori <skori@marvell.com>

Add tracepoints at important and mandatory APIs for tracing support.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 MAINTAINERS                                   |   2 +
 drivers/crypto/ccp/Makefile                   |   1 +
 drivers/crypto/ccp/meson.build                |   2 +
 drivers/crypto/mvsam/Makefile                 |   1 +
 drivers/crypto/mvsam/meson.build              |   1 +
 drivers/crypto/null/Makefile                  |   1 +
 drivers/crypto/null/meson.build               |   1 +
 drivers/crypto/scheduler/Makefile             |   1 +
 drivers/crypto/scheduler/meson.build          |   1 +
 drivers/crypto/virtio/Makefile                |   1 +
 drivers/crypto/virtio/meson.build             |   1 +
 lib/librte_cryptodev/Makefile                 |   4 +-
 lib/librte_cryptodev/cryptodev_trace_points.c |  70 +++++++++
 lib/librte_cryptodev/meson.build              |   7 +-
 lib/librte_cryptodev/rte_cryptodev.c          |  18 +++
 lib/librte_cryptodev/rte_cryptodev.h          |   6 +
 .../rte_cryptodev_version.map                 |  18 +++
 lib/librte_cryptodev/rte_trace_cryptodev.h    | 133 ++++++++++++++++++
 lib/librte_cryptodev/rte_trace_cryptodev_fp.h |  34 +++++
 19 files changed, 300 insertions(+), 3 deletions(-)
 create mode 100644 lib/librte_cryptodev/cryptodev_trace_points.c
 create mode 100644 lib/librte_cryptodev/rte_trace_cryptodev.h
 create mode 100644 lib/librte_cryptodev/rte_trace_cryptodev_fp.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 7e2d42da3..0a549cc05 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -206,6 +206,8 @@ F: lib/librte_ethdev/ethdev_trace_points.c
 F: lib/librte_ethdev/rte_trace_ethdev*.h
 F: lib/librte_eventdev/eventdev_trace_points.c
 F: lib/librte_eventdev/rte_trace_eventdev*.h
+F: lib/librte_cryptodev/cryptodev_trace_points.c
+F: lib/librte_cryptodev/rte_trace_cryptodev*.h
 
 Memory Allocation
 M: Anatoly Burakov <anatoly.burakov@intel.com>
diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index 3f5da2adf..df064fbdc 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -10,6 +10,7 @@ LIB = librte_pmd_ccp.a
 CFLAGS += -O3
 CFLAGS += -I$(SRCDIR)
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 # external library include paths
 LDLIBS += -lcrypto
diff --git a/drivers/crypto/ccp/meson.build b/drivers/crypto/ccp/meson.build
index 6f7217adb..996ede283 100644
--- a/drivers/crypto/ccp/meson.build
+++ b/drivers/crypto/ccp/meson.build
@@ -5,6 +5,8 @@ if not is_linux
 	build = false
 	reason = 'only supported on linux'
 endif
+
+allow_experimental_apis = true
 dep = dependency('libcrypto', required: false)
 if not dep.found()
 	build = false
diff --git a/drivers/crypto/mvsam/Makefile b/drivers/crypto/mvsam/Makefile
index f0641ae7d..0cd2029ba 100644
--- a/drivers/crypto/mvsam/Makefile
+++ b/drivers/crypto/mvsam/Makefile
@@ -22,6 +22,7 @@ CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/common/mvep
 CFLAGS += -I$(LIBMUSDK_PATH)/include
 CFLAGS += -DMVCONF_TYPES_PUBLIC
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -DMVCONF_DMA_PHYS_ADDR_T_PUBLIC
 
 # versioning export map
diff --git a/drivers/crypto/mvsam/meson.build b/drivers/crypto/mvsam/meson.build
index 6d97dc8a2..28f1f27b0 100644
--- a/drivers/crypto/mvsam/meson.build
+++ b/drivers/crypto/mvsam/meson.build
@@ -17,6 +17,7 @@ else
 	cflags += ['-DMVCONF_TYPES_PUBLIC', '-DMVCONF_DMA_PHYS_ADDR_T_PUBLIC']
 endif
 
+allow_experimental_apis = true
 sources = files('rte_mrvl_pmd.c', 'rte_mrvl_pmd_ops.c')
 
 deps += ['bus_vdev', 'common_mvep']
diff --git a/drivers/crypto/null/Makefile b/drivers/crypto/null/Makefile
index 4595055f0..c5eb34aed 100644
--- a/drivers/crypto/null/Makefile
+++ b/drivers/crypto/null/Makefile
@@ -10,6 +10,7 @@ LIB = librte_pmd_null_crypto.a
 # build flags
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev
 LDLIBS += -lrte_bus_vdev
diff --git a/drivers/crypto/null/meson.build b/drivers/crypto/null/meson.build
index 502336da2..429000fd7 100644
--- a/drivers/crypto/null/meson.build
+++ b/drivers/crypto/null/meson.build
@@ -3,4 +3,5 @@
 
 deps += 'bus_vdev'
 name = 'null_crypto'
+allow_experimental_apis = true
 sources = files('null_crypto_pmd.c', 'null_crypto_pmd_ops.c')
diff --git a/drivers/crypto/scheduler/Makefile b/drivers/crypto/scheduler/Makefile
index 67aac024c..53eeccdea 100644
--- a/drivers/crypto/scheduler/Makefile
+++ b/drivers/crypto/scheduler/Makefile
@@ -9,6 +9,7 @@ LIB = librte_pmd_crypto_scheduler.a
 # build flags
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev -lrte_kvargs -lrte_reorder
 LDLIBS += -lrte_bus_vdev
diff --git a/drivers/crypto/scheduler/meson.build b/drivers/crypto/scheduler/meson.build
index c5ba2d680..49c9e63d7 100644
--- a/drivers/crypto/scheduler/meson.build
+++ b/drivers/crypto/scheduler/meson.build
@@ -3,6 +3,7 @@
 
 deps += ['bus_vdev', 'reorder']
 name = 'crypto_scheduler'
+allow_experimental_apis = true
 sources = files(
 	'rte_cryptodev_scheduler.c',
 	'scheduler_failover.c',
diff --git a/drivers/crypto/virtio/Makefile b/drivers/crypto/virtio/Makefile
index 32e2e4d5e..841131ceb 100644
--- a/drivers/crypto/virtio/Makefile
+++ b/drivers/crypto/virtio/Makefile
@@ -14,6 +14,7 @@ LIB = librte_pmd_virtio_crypto.a
 CFLAGS += -I$(RTE_SDK)/lib/librte_vhost
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_pmd_virtio_crypto_version.map
 
diff --git a/drivers/crypto/virtio/meson.build b/drivers/crypto/virtio/meson.build
index b15b3f9fa..7e408676d 100644
--- a/drivers/crypto/virtio/meson.build
+++ b/drivers/crypto/virtio/meson.build
@@ -4,5 +4,6 @@
 includes += include_directories('../../../lib/librte_vhost')
 deps += 'bus_pci'
 name = 'virtio_crypto'
+allow_experimental_apis = true
 sources = files('virtio_cryptodev.c', 'virtio_pci.c',
 		'virtio_rxtx.c', 'virtqueue.c')
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index 7fac49afa..da096603c 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -14,7 +14,7 @@ LDLIBS += -lrte_eal -lrte_mempool -lrte_ring -lrte_mbuf
 LDLIBS += -lrte_kvargs
 
 # library source files
-SRCS-y += rte_cryptodev.c rte_cryptodev_pmd.c
+SRCS-y += rte_cryptodev.c rte_cryptodev_pmd.c cryptodev_trace_points.c
 
 # export include files
 SYMLINK-y-include += rte_crypto.h
@@ -22,6 +22,8 @@ SYMLINK-y-include += rte_crypto_sym.h
 SYMLINK-y-include += rte_cryptodev.h
 SYMLINK-y-include += rte_cryptodev_pmd.h
 SYMLINK-y-include += rte_crypto_asym.h
+SYMLINK-y-include += rte_trace_cryptodev.h
+SYMLINK-y-include += rte_trace_cryptodev_fp.h
 
 # versioning export map
 EXPORT_MAP := rte_cryptodev_version.map
diff --git a/lib/librte_cryptodev/cryptodev_trace_points.c b/lib/librte_cryptodev/cryptodev_trace_points.c
new file mode 100644
index 000000000..712080666
--- /dev/null
+++ b/lib/librte_cryptodev/cryptodev_trace_points.c
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#define RTE_TRACE_POINT_REGISTER_SELECT /* Select trace point register macros */
+
+#include "rte_trace_cryptodev.h"
+
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_configure);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_start);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_stop);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_close);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_queue_pair_setup);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_sym_session_pool_create);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_sym_session_create);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_asym_session_create);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_sym_session_free);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_asym_session_free);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_sym_session_init);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_asym_session_init);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_sym_session_clear);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_asym_session_clear);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_enqueue_burst);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_cryptodev_dequeue_burst);
+
+RTE_INIT(cryptodev_trace_init)
+{
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_configure,
+				 lib.cryptodev.configure, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_start,
+				 lib.cryptodev.start, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_stop,
+				 lib.cryptodev.stop, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_close,
+				 lib.cryptodev.close, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_queue_pair_setup,
+				 lib.cryptodev.queue.pair.setup, INFO);
+
+	RTE_TRACE_POINT_REGISTER(
+			rte_trace_lib_cryptodev_sym_session_pool_create,
+			lib.cryptodev.sym.pool.create, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_sym_session_create,
+				 lib.cryptodev.sym.create, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_asym_session_create,
+				 lib.cryptodev.asym.create, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_sym_session_free,
+				 lib.cryptodev.sym.free, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_asym_session_free,
+				 lib.cryptodev.asym.free, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_sym_session_init,
+				 lib.cryptodev.sym.init, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_asym_session_init,
+				 lib.cryptodev.asym.init, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_enqueue_burst,
+				 lib.cryptodev.enq.burst, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_cryptodev_dequeue_burst,
+				 lib.cryptodev.deq.burst, INFO);
+}
diff --git a/lib/librte_cryptodev/meson.build b/lib/librte_cryptodev/meson.build
index 49bae03a8..5c405cdfb 100644
--- a/lib/librte_cryptodev/meson.build
+++ b/lib/librte_cryptodev/meson.build
@@ -2,10 +2,13 @@
 # Copyright(c) 2017-2019 Intel Corporation
 
 allow_experimental_apis = true
-sources = files('rte_cryptodev.c', 'rte_cryptodev_pmd.c')
+sources = files('rte_cryptodev.c', 'rte_cryptodev_pmd.c',
+	'cryptodev_trace_points.c')
 headers = files('rte_cryptodev.h',
 	'rte_cryptodev_pmd.h',
 	'rte_crypto.h',
 	'rte_crypto_sym.h',
-	'rte_crypto_asym.h')
+	'rte_crypto_asym.h',
+	'rte_trace_cryptodev.h',
+	'rte_trace_cryptodev_fp.h')
 deps += ['kvargs', 'mbuf']
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 6d1d0e9d3..66ab7a694 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -40,6 +40,7 @@
 #include "rte_crypto.h"
 #include "rte_cryptodev.h"
 #include "rte_cryptodev_pmd.h"
+#include "rte_trace_cryptodev.h"
 
 static uint8_t nb_drivers;
 
@@ -905,6 +906,7 @@ rte_cryptodev_configure(uint8_t dev_id, struct rte_cryptodev_config *config)
 		return diag;
 	}
 
+	rte_trace_lib_cryptodev_configure(dev_id, config);
 	return (*dev->dev_ops->dev_configure)(dev, config);
 }
 
@@ -933,6 +935,7 @@ rte_cryptodev_start(uint8_t dev_id)
 	}
 
 	diag = (*dev->dev_ops->dev_start)(dev);
+	rte_trace_lib_cryptodev_start(dev_id, diag);
 	if (diag == 0)
 		dev->data->dev_started = 1;
 	else
@@ -962,6 +965,7 @@ rte_cryptodev_stop(uint8_t dev_id)
 	}
 
 	(*dev->dev_ops->dev_stop)(dev);
+	rte_trace_lib_cryptodev_stop(dev_id);
 	dev->data->dev_started = 0;
 }
 
@@ -998,6 +1002,7 @@ rte_cryptodev_close(uint8_t dev_id)
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
 	retval = (*dev->dev_ops->dev_close)(dev);
+	rte_trace_lib_cryptodev_close(dev_id, retval);
 
 	if (retval < 0)
 		return retval;
@@ -1067,6 +1072,8 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_setup, -ENOTSUP);
 
+	rte_trace_lib_cryptodev_queue_pair_setup(dev_id, queue_pair_id,
+						 qp_conf);
 	return (*dev->dev_ops->queue_pair_setup)(dev, queue_pair_id, qp_conf,
 			socket_id);
 }
@@ -1283,6 +1290,7 @@ rte_cryptodev_sym_session_init(uint8_t dev_id,
 		}
 	}
 
+	rte_trace_lib_cryptodev_sym_session_init(dev_id, sess, xforms, mp);
 	sess->sess_data[index].refcnt++;
 	return 0;
 }
@@ -1319,6 +1327,7 @@ rte_cryptodev_asym_session_init(uint8_t dev_id,
 		}
 	}
 
+	rte_trace_lib_cryptodev_asym_session_init(dev_id, sess, xforms, mp);
 	return 0;
 }
 
@@ -1359,6 +1368,9 @@ rte_cryptodev_sym_session_pool_create(const char *name, uint32_t nb_elts,
 	pool_priv->nb_drivers = nb_drivers;
 	pool_priv->user_data_sz = user_data_size;
 
+	rte_trace_lib_cryptodev_sym_session_pool_create(name, nb_elts,
+							elt_size, cache_size,
+							user_data_size, mp);
 	return mp;
 }
 
@@ -1403,6 +1415,7 @@ rte_cryptodev_sym_session_create(struct rte_mempool *mp)
 	memset(sess->sess_data, 0,
 			rte_cryptodev_sym_session_data_size(sess));
 
+	rte_trace_lib_cryptodev_sym_session_create(mp, sess);
 	return sess;
 }
 
@@ -1422,6 +1435,7 @@ rte_cryptodev_asym_session_create(struct rte_mempool *mp)
 	 */
 	memset(sess, 0, (sizeof(void *) * nb_drivers) + sizeof(uint8_t));
 
+	rte_trace_lib_cryptodev_asym_session_create(mp, sess);
 	return sess;
 }
 
@@ -1447,6 +1461,7 @@ rte_cryptodev_sym_session_clear(uint8_t dev_id,
 
 	dev->dev_ops->sym_session_clear(dev, sess);
 
+	rte_trace_lib_cryptodev_sym_session_clear(dev_id, sess);
 	return 0;
 }
 
@@ -1465,6 +1480,7 @@ rte_cryptodev_asym_session_clear(uint8_t dev_id,
 
 	dev->dev_ops->asym_session_clear(dev, sess);
 
+	rte_trace_lib_cryptodev_sym_session_clear(dev_id, sess);
 	return 0;
 }
 
@@ -1487,6 +1503,7 @@ rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess)
 	sess_mp = rte_mempool_from_obj(sess);
 	rte_mempool_put(sess_mp, sess);
 
+	rte_trace_lib_cryptodev_sym_session_free(sess);
 	return 0;
 }
 
@@ -1511,6 +1528,7 @@ rte_cryptodev_asym_session_free(struct rte_cryptodev_asym_session *sess)
 	sess_mp = rte_mempool_from_obj(sess);
 	rte_mempool_put(sess_mp, sess);
 
+	rte_trace_lib_cryptodev_asym_session_free(sess);
 	return 0;
 }
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 437b8a9b3..9008b70b6 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -24,6 +24,8 @@ extern "C" {
 #include <rte_common.h>
 #include <rte_config.h>
 
+#include "rte_trace_cryptodev_fp.h"
+
 extern const char **rte_cyptodev_names;
 
 /* Logging Macros */
@@ -924,6 +926,8 @@ rte_cryptodev_dequeue_burst(uint8_t dev_id, uint16_t qp_id,
 	nb_ops = (*dev->dequeue_burst)
 			(dev->data->queue_pairs[qp_id], ops, nb_ops);
 
+	rte_trace_lib_cryptodev_dequeue_burst(dev_id, qp_id, (void **)ops,
+					      nb_ops);
 	return nb_ops;
 }
 
@@ -964,6 +968,8 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
 {
 	struct rte_cryptodev *dev = &rte_cryptodevs[dev_id];
 
+	rte_trace_lib_cryptodev_enqueue_burst(dev_id, qp_id, (void **)ops,
+					      nb_ops);
 	return (*dev->enqueue_burst)(
 			dev->data->queue_pairs[qp_id], ops, nb_ops);
 }
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 6e41b4be5..d023de7aa 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -78,4 +78,22 @@ EXPERIMENTAL {
 	rte_cryptodev_sym_session_set_user_data;
 	rte_crypto_asym_op_strings;
 	rte_crypto_asym_xform_strings;
+
+	# added in 20.05
+	__rte_trace_lib_cryptodev_configure;
+	__rte_trace_lib_cryptodev_start;
+	__rte_trace_lib_cryptodev_stop;
+	__rte_trace_lib_cryptodev_close;
+	__rte_trace_lib_cryptodev_queue_pair_setup;
+	__rte_trace_lib_cryptodev_sym_session_pool_create;
+	__rte_trace_lib_cryptodev_sym_session_create;
+	__rte_trace_lib_cryptodev_asym_session_create;
+	__rte_trace_lib_cryptodev_sym_session_free;
+	__rte_trace_lib_cryptodev_asym_session_free;
+	__rte_trace_lib_cryptodev_sym_session_init;
+	__rte_trace_lib_cryptodev_asym_session_init;
+	__rte_trace_lib_cryptodev_sym_session_clear;
+	__rte_trace_lib_cryptodev_asym_session_clear;
+	__rte_trace_lib_cryptodev_dequeue_burst;
+	__rte_trace_lib_cryptodev_enqueue_burst;
 };
diff --git a/lib/librte_cryptodev/rte_trace_cryptodev.h b/lib/librte_cryptodev/rte_trace_cryptodev.h
new file mode 100644
index 000000000..fd031b63f
--- /dev/null
+++ b/lib/librte_cryptodev/rte_trace_cryptodev.h
@@ -0,0 +1,133 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_CRYPTODEV_H_
+#define _RTE_TRACE_CRYPTODEV_H_
+
+/**
+ * @file
+ *
+ * API for cryptodev trace support
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "rte_cryptodev.h"
+
+#include <rte_trace.h>
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_configure,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, struct rte_cryptodev_config *conf),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_u16(conf->nb_queue_pairs);
+	rte_trace_ctf_i64(conf->ff_disable);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_start,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, int rc),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_stop,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id),
+	rte_trace_ctf_u8(dev_id);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_close,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, int rc),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_queue_pair_setup,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, uint16_t queue_pair_id,
+			     const struct rte_cryptodev_qp_conf *conf),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_u16(queue_pair_id);
+	rte_trace_ctf_u32(conf->nb_descriptors);
+	rte_trace_ctf_ptr(conf->mp_session);
+	rte_trace_ctf_ptr(conf->mp_session_private);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_sym_session_pool_create,
+	RTE_TRACE_POINT_ARGS(const char *name, uint32_t nb_elts,
+			     uint32_t elt_size, uint32_t cache_size,
+			     uint16_t user_data_size, void *mempool),
+	rte_trace_ctf_string(name); rte_trace_ctf_u32(nb_elts);
+	rte_trace_ctf_u32(elt_size); rte_trace_ctf_u32(cache_size);
+	rte_trace_ctf_u16(user_data_size); rte_trace_ctf_ptr(mempool);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_sym_session_create,
+	RTE_TRACE_POINT_ARGS(void *mempool,
+			     struct rte_cryptodev_sym_session *sess),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_ptr(sess);
+	rte_trace_ctf_u64(sess->opaque_data);
+	rte_trace_ctf_u16(sess->nb_drivers);
+	rte_trace_ctf_u16(sess->user_data_sz);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_asym_session_create,
+	RTE_TRACE_POINT_ARGS(void *mempool,
+			     struct rte_cryptodev_asym_session *sess),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_ptr(sess);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_sym_session_free,
+	RTE_TRACE_POINT_ARGS(struct rte_cryptodev_sym_session *sess),
+	rte_trace_ctf_ptr(sess);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_asym_session_free,
+	RTE_TRACE_POINT_ARGS(struct rte_cryptodev_asym_session *sess),
+	rte_trace_ctf_ptr(sess);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_sym_session_init,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id,
+			     struct rte_cryptodev_sym_session *sess,
+			     void *xforms, void *mempool),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_ptr(sess);
+	rte_trace_ctf_u64(sess->opaque_data);
+	rte_trace_ctf_u16(sess->nb_drivers);
+	rte_trace_ctf_u16(sess->user_data_sz);
+	rte_trace_ctf_ptr(xforms); rte_trace_ctf_ptr(mempool);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_asym_session_init,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id,
+			     struct rte_cryptodev_asym_session *sess,
+			     void *xforms, void *mempool),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_ptr(sess);
+	rte_trace_ctf_ptr(xforms); rte_trace_ctf_ptr(mempool);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_sym_session_clear,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, void *sess),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_ptr(sess);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_cryptodev_asym_session_clear,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, void *sess),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_ptr(sess);
+)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TRACE_CRYPTODEV_H_ */
diff --git a/lib/librte_cryptodev/rte_trace_cryptodev_fp.h b/lib/librte_cryptodev/rte_trace_cryptodev_fp.h
new file mode 100644
index 000000000..aea7fb352
--- /dev/null
+++ b/lib/librte_cryptodev/rte_trace_cryptodev_fp.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_CRYPTODEV_FP_H_
+#define _RTE_TRACE_CRYPTODEV_FP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_trace.h>
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_cryptodev_enqueue_burst,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, uint16_t qp_id, void **ops,
+			     uint16_t nb_ops),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_u16(qp_id);
+	rte_trace_ctf_ptr(ops); rte_trace_ctf_u16(nb_ops);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_cryptodev_dequeue_burst,
+	RTE_TRACE_POINT_ARGS(uint8_t dev_id, uint16_t qp_id, void **ops,
+			     uint16_t nb_ops),
+	rte_trace_ctf_u8(dev_id); rte_trace_ctf_u16(qp_id);
+	rte_trace_ctf_ptr(ops); rte_trace_ctf_u16(nb_ops);
+)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TRACE_CRYPTODEV_FP_H_ */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 31/32] mempool: add tracepoints
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (29 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 30/32] cryptodev: " jerinj
@ 2020-03-18 19:02 ` " jerinj
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 32/32] doc: add trace library guide jerinj
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: Thomas Monjalon, Anoob Joseph, Olivier Matz, Andrew Rybchenko,
	Bruce Richardson, Satha Rao, Vamsi Attunuru, Mahipal Challa,
	Shreyansh Jain, Hemant Agrawal, David Hunt, Konstantin Ananyev,
	Jerin Jacob, Sunil Kumar Kori, Reshma Pattan,
	Cristian Dumitrescu, Jasvinder Singh, Akhil Goyal,
	Declan Doherty
  Cc: dev, david.marchand, mattias.ronnblom

From: Sunil Kumar Kori <skori@marvell.com>

Add tracepoints at important and mandatory APIs for tracing support.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 MAINTAINERS                                |   2 +
 drivers/common/cpt/Makefile                |   1 +
 drivers/mempool/ring/Makefile              |   1 +
 drivers/mempool/ring/meson.build           |   1 +
 drivers/raw/ioat/Makefile                  |   1 +
 drivers/raw/ioat/meson.build               |   1 +
 drivers/raw/octeontx2_dma/Makefile         |   1 +
 drivers/raw/octeontx2_dma/meson.build      |   1 +
 drivers/raw/octeontx2_ep/Makefile          |   1 +
 drivers/raw/octeontx2_ep/meson.build       |   1 +
 drivers/raw/skeleton/Makefile              |   1 +
 drivers/raw/skeleton/meson.build           |   1 +
 lib/librte_distributor/Makefile            |   1 +
 lib/librte_distributor/meson.build         |   1 +
 lib/librte_ip_frag/Makefile                |   1 +
 lib/librte_ip_frag/meson.build             |   1 +
 lib/librte_mempool/Makefile                |   3 +
 lib/librte_mempool/mempool_trace_points.c  | 108 +++++++++++++++
 lib/librte_mempool/meson.build             |   7 +-
 lib/librte_mempool/rte_mempool.c           |  16 +++
 lib/librte_mempool/rte_mempool.h           |  13 ++
 lib/librte_mempool/rte_mempool_ops.c       |   7 +
 lib/librte_mempool/rte_mempool_version.map |  26 ++++
 lib/librte_mempool/rte_trace_mempool.h     | 148 +++++++++++++++++++++
 lib/librte_mempool/rte_trace_mempool_fp.h  | 102 ++++++++++++++
 lib/librte_reorder/Makefile                |   1 +
 lib/librte_reorder/meson.build             |   1 +
 lib/librte_sched/Makefile                  |   1 +
 lib/librte_sched/meson.build               |   1 +
 lib/librte_security/Makefile               |   1 +
 lib/librte_security/meson.build            |   1 +
 lib/librte_table/Makefile                  |   1 +
 lib/librte_table/meson.build               |   1 +
 33 files changed, 451 insertions(+), 4 deletions(-)
 create mode 100644 lib/librte_mempool/mempool_trace_points.c
 create mode 100644 lib/librte_mempool/rte_trace_mempool.h
 create mode 100644 lib/librte_mempool/rte_trace_mempool_fp.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 0a549cc05..8c42e7ce4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -208,6 +208,8 @@ F: lib/librte_eventdev/eventdev_trace_points.c
 F: lib/librte_eventdev/rte_trace_eventdev*.h
 F: lib/librte_cryptodev/cryptodev_trace_points.c
 F: lib/librte_cryptodev/rte_trace_cryptodev*.h
+F: lib/librte_mempool/mempool_trace_points.c
+F: lib/librte_mempool/rte_trace_mempool*.h
 
 Memory Allocation
 M: Anatoly Burakov <anatoly.burakov@intel.com>
diff --git a/drivers/common/cpt/Makefile b/drivers/common/cpt/Makefile
index cab9da73c..9e4cab166 100644
--- a/drivers/common/cpt/Makefile
+++ b/drivers/common/cpt/Makefile
@@ -10,6 +10,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_common_cpt.a
 
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -I$(RTE_SDK)/drivers/bus/pci
 EXPORT_MAP := rte_common_cpt_version.map
 
diff --git a/drivers/mempool/ring/Makefile b/drivers/mempool/ring/Makefile
index 8624502da..0b8b64598 100644
--- a/drivers/mempool/ring/Makefile
+++ b/drivers/mempool/ring/Makefile
@@ -10,6 +10,7 @@ LIB = librte_mempool_ring.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_mempool -lrte_ring
 
 EXPORT_MAP := rte_mempool_ring_version.map
diff --git a/drivers/mempool/ring/meson.build b/drivers/mempool/ring/meson.build
index a021e908c..ec07b186e 100644
--- a/drivers/mempool/ring/meson.build
+++ b/drivers/mempool/ring/meson.build
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_mempool_ring.c')
diff --git a/drivers/raw/ioat/Makefile b/drivers/raw/ioat/Makefile
index 1609fe5e6..5c8c02bee 100644
--- a/drivers/raw/ioat/Makefile
+++ b/drivers/raw/ioat/Makefile
@@ -9,6 +9,7 @@ LIB = librte_rawdev_ioat.a
 # build flags
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 LDLIBS += -lrte_eal -lrte_rawdev
 LDLIBS += -lrte_pci -lrte_bus_pci
diff --git a/drivers/raw/ioat/meson.build b/drivers/raw/ioat/meson.build
index 0878418ae..b59847387 100644
--- a/drivers/raw/ioat/meson.build
+++ b/drivers/raw/ioat/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright 2019 Intel Corporation
 
+allow_experimental_apis = true
 build = dpdk_conf.has('RTE_ARCH_X86')
 reason = 'only supported on x86'
 sources = files('ioat_rawdev.c',
diff --git a/drivers/raw/octeontx2_dma/Makefile b/drivers/raw/octeontx2_dma/Makefile
index c64ca3497..180b23516 100644
--- a/drivers/raw/octeontx2_dma/Makefile
+++ b/drivers/raw/octeontx2_dma/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_rawdev_octeontx2_dma.a
 
 CFLAGS += -O3 $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -I$(RTE_SDK)/drivers/common/octeontx2/
 CFLAGS += -I$(RTE_SDK)/drivers/mempool/octeontx2/
 CFLAGS += -I$(RTE_SDK)/drivers/raw/octeontx2_dma/
diff --git a/drivers/raw/octeontx2_dma/meson.build b/drivers/raw/octeontx2_dma/meson.build
index 11f74680a..b1862a7d3 100644
--- a/drivers/raw/octeontx2_dma/meson.build
+++ b/drivers/raw/octeontx2_dma/meson.build
@@ -2,6 +2,7 @@
 # Copyright(C) 2019 Marvell International Ltd.
 #
 
+allow_experimental_apis = true
 deps += ['bus_pci', 'common_octeontx2', 'rawdev']
 sources = files('otx2_dpi_rawdev.c', 'otx2_dpi_msg.c', 'otx2_dpi_test.c')
 
diff --git a/drivers/raw/octeontx2_ep/Makefile b/drivers/raw/octeontx2_ep/Makefile
index 1a54bf56f..08aab53b5 100644
--- a/drivers/raw/octeontx2_ep/Makefile
+++ b/drivers/raw/octeontx2_ep/Makefile
@@ -10,6 +10,7 @@ LIB = librte_rawdev_octeontx2_ep.a
 # Build flags
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 CFLAGS += -I$(RTE_SDK)/drivers/common/octeontx2/
 CFLAGS += -I$(RTE_SDK)/drivers/raw/octeontx2_ep/
diff --git a/drivers/raw/octeontx2_ep/meson.build b/drivers/raw/octeontx2_ep/meson.build
index 0e6338f76..633292f57 100644
--- a/drivers/raw/octeontx2_ep/meson.build
+++ b/drivers/raw/octeontx2_ep/meson.build
@@ -2,6 +2,7 @@
 # Copyright(C) 2019 Marvell International Ltd.
 #
 
+allow_experimental_apis = true
 deps += ['bus_pci', 'common_octeontx2', 'rawdev']
 sources = files('otx2_ep_rawdev.c',
 		'otx2_ep_enqdeq.c',
diff --git a/drivers/raw/skeleton/Makefile b/drivers/raw/skeleton/Makefile
index 2ac66fbd4..9c7018992 100644
--- a/drivers/raw/skeleton/Makefile
+++ b/drivers/raw/skeleton/Makefile
@@ -10,6 +10,7 @@ LIB = librte_rawdev_skeleton.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal
 LDLIBS += -lrte_rawdev
 LDLIBS += -lrte_bus_vdev
diff --git a/drivers/raw/skeleton/meson.build b/drivers/raw/skeleton/meson.build
index b4a6ed08a..993ea332c 100644
--- a/drivers/raw/skeleton/meson.build
+++ b/drivers/raw/skeleton/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright 2018 NXP
 
+allow_experimental_apis = true
 deps += ['rawdev', 'kvargs', 'mbuf', 'bus_vdev']
 sources = files('skeleton_rawdev.c',
                'skeleton_rawdev_test.c')
diff --git a/lib/librte_distributor/Makefile b/lib/librte_distributor/Makefile
index fc32fb3a8..f6b5f12de 100644
--- a/lib/librte_distributor/Makefile
+++ b/lib/librte_distributor/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_distributor.a
 
 CFLAGS += -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_ethdev
 
diff --git a/lib/librte_distributor/meson.build b/lib/librte_distributor/meson.build
index 266af6434..01dd56597 100644
--- a/lib/librte_distributor/meson.build
+++ b/lib/librte_distributor/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_distributor.c', 'rte_distributor_single.c')
 if arch_subdir == 'x86'
 	sources += files('rte_distributor_match_sse.c')
diff --git a/lib/librte_ip_frag/Makefile b/lib/librte_ip_frag/Makefile
index 6b80d9f1f..ae50762d2 100644
--- a/lib/librte_ip_frag/Makefile
+++ b/lib/librte_ip_frag/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_ip_frag.a
 
 CFLAGS += -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
 LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev
 LDLIBS += -lrte_hash
diff --git a/lib/librte_ip_frag/meson.build b/lib/librte_ip_frag/meson.build
index c5b9a4596..68bc2491a 100644
--- a/lib/librte_ip_frag/meson.build
+++ b/lib/librte_ip_frag/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_ipv4_fragmentation.c',
 		'rte_ipv6_fragmentation.c',
 		'rte_ipv4_reassembly.c',
diff --git a/lib/librte_mempool/Makefile b/lib/librte_mempool/Makefile
index a5649050b..91d181103 100644
--- a/lib/librte_mempool/Makefile
+++ b/lib/librte_mempool/Makefile
@@ -19,7 +19,10 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  rte_mempool.c
 SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  rte_mempool_ops.c
 SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  rte_mempool_ops_default.c
+SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  mempool_trace_points.c
 # install includes
 SYMLINK-$(CONFIG_RTE_LIBRTE_MEMPOOL)-include := rte_mempool.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_MEMPOOL)-include += rte_trace_mempool.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_MEMPOOL)-include += rte_trace_mempool_fp.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_mempool/mempool_trace_points.c b/lib/librte_mempool/mempool_trace_points.c
new file mode 100644
index 000000000..fbe23b93a
--- /dev/null
+++ b/lib/librte_mempool/mempool_trace_points.c
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#define RTE_TRACE_POINT_REGISTER_SELECT /* Select trace point register macros */
+
+#include "rte_trace_mempool.h"
+
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_ops_dequeue_bulk);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_ops_dequeue_contig_blocks);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_ops_enqueue_bulk);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_generic_put);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_put_bulk);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_generic_get);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_get_bulk);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_get_contig_blocks);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_create);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_create_empty);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_free);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_populate_iova);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_populate_virt);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_populate_default);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_populate_anon);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_cache_create);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_cache_free);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_default_cache);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_get_page_size);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_cache_flush);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_ops_populate);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_ops_alloc);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_ops_free);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_mempool_set_ops_byname);
+
+RTE_INIT(mempool_trace_init)
+{
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_ops_dequeue_bulk,
+				 lib.mempool.ops.deq.bulk, INFO);
+
+	RTE_TRACE_POINT_REGISTER(
+		rte_trace_lib_mempool_ops_dequeue_contig_blocks,
+				 lib.mempool.ops.deq.contig, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_ops_enqueue_bulk,
+				 lib.mempool.ops.enq.bulk, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_generic_put,
+				 lib.mempool.generic.put, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_put_bulk,
+				 lib.mempool.put.bulk, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_generic_get,
+				 lib.mempool.generic.get, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_get_bulk,
+				 lib.mempool.get.bulk, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_get_contig_blocks,
+				 lib.mempool.get.blocks, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_create,
+				 lib.mempool.create, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_create_empty,
+				 lib.mempool.create.empty, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_free,
+				 lib.mempool.free, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_populate_iova,
+				 lib.mempool.populate.iova, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_populate_virt,
+				 lib.mempool.populate.virt, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_populate_default,
+				 lib.mempool.populate.default, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_populate_anon,
+				 lib.mempool.populate.anon, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_cache_create,
+				 lib.mempool.cache_create, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_cache_free,
+				 lib.mempool.cache.free, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_default_cache,
+				 lib.mempool.default.cache, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_get_page_size,
+				 lib.mempool.get.page.size, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_cache_flush,
+				 lib.mempool.cache.flush, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_ops_populate,
+				 lib.mempool.ops.populate, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_ops_alloc,
+				 lib.mempool.ops.alloc, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_ops_free,
+				 lib.mempool.ops.free, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_mempool_set_ops_byname,
+				 lib.mempool.set.ops.byname, INFO);
+}
diff --git a/lib/librte_mempool/meson.build b/lib/librte_mempool/meson.build
index f8710b61b..903e923c3 100644
--- a/lib/librte_mempool/meson.build
+++ b/lib/librte_mempool/meson.build
@@ -1,8 +1,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
-allow_experimental_apis = true
-
 extra_flags = []
 
 foreach flag: extra_flags
@@ -12,8 +10,9 @@ foreach flag: extra_flags
 endforeach
 
 sources = files('rte_mempool.c', 'rte_mempool_ops.c',
-		'rte_mempool_ops_default.c')
-headers = files('rte_mempool.h')
+		'rte_mempool_ops_default.c', 'mempool_trace_points.c')
+headers = files('rte_mempool.h', 'rte_trace_mempool.h',
+		'rte_trace_mempool_fp.h')
 deps += ['ring']
 
 # memseg walk is not yet part of stable API
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 712c839a0..6cc0c7209 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -33,6 +33,7 @@
 #include <rte_tailq.h>
 
 #include "rte_mempool.h"
+#include "rte_trace_mempool.h"
 
 TAILQ_HEAD(rte_mempool_list, rte_tailq_entry);
 
@@ -377,6 +378,8 @@ rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
 	if (ret == 0)
 		ret = -EINVAL;
 
+	rte_trace_lib_mempool_populate_iova(mp, vaddr, iova, len, free_cb,
+					    opaque);
 	return ret;
 }
 
@@ -444,6 +447,8 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
 	if (cnt == 0)
 		return -EINVAL;
 
+	rte_trace_lib_mempool_populate_virt(mp, addr, len, pg_sz, free_cb,
+					    opaque);
 	return cnt;
 
  fail:
@@ -473,6 +478,7 @@ rte_mempool_get_page_size(struct rte_mempool *mp, size_t *pg_sz)
 	else
 		*pg_sz = getpagesize();
 
+	rte_trace_lib_mempool_get_page_size(mp, *pg_sz);
 	return 0;
 }
 
@@ -611,6 +617,7 @@ rte_mempool_populate_default(struct rte_mempool *mp)
 		}
 	}
 
+	rte_trace_lib_mempool_populate_default(mp);
 	return mp->size;
 
  fail:
@@ -701,6 +708,7 @@ rte_mempool_populate_anon(struct rte_mempool *mp)
 		goto fail;
 	}
 
+	rte_trace_lib_mempool_populate_anon(mp);
 	return mp->populated_size;
 
  fail:
@@ -732,6 +740,7 @@ rte_mempool_free(struct rte_mempool *mp)
 	}
 	rte_mcfg_tailq_write_unlock();
 
+	rte_trace_lib_mempool_free(mp);
 	rte_mempool_free_memchunks(mp);
 	rte_mempool_ops_free(mp);
 	rte_memzone_free(mp->mz);
@@ -770,6 +779,7 @@ rte_mempool_cache_create(uint32_t size, int socket_id)
 
 	mempool_cache_init(cache, size);
 
+	rte_trace_lib_mempool_cache_create(size, socket_id, cache);
 	return cache;
 }
 
@@ -781,6 +791,7 @@ rte_mempool_cache_create(uint32_t size, int socket_id)
 void
 rte_mempool_cache_free(struct rte_mempool_cache *cache)
 {
+	rte_trace_lib_mempool_cache_free(cache);
 	rte_free(cache);
 }
 
@@ -911,6 +922,8 @@ rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size,
 	rte_mcfg_tailq_write_unlock();
 	rte_mcfg_mempool_write_unlock();
 
+	rte_trace_lib_mempool_create_empty(name, n, elt_size, cache_size,
+					   private_data_size, flags, mp);
 	return mp;
 
 exit_unlock:
@@ -963,6 +976,9 @@ rte_mempool_create(const char *name, unsigned n, unsigned elt_size,
 	if (obj_init)
 		rte_mempool_obj_iter(mp, obj_init, obj_init_arg);
 
+	rte_trace_lib_mempool_create(name, n, elt_size, cache_size,
+				     private_data_size, mp_init, mp_init_arg,
+				     obj_init, obj_init_arg, flags, mp);
 	return mp;
 
  fail:
diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index c90cf3146..2d0b5ad46 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -51,6 +51,8 @@
 #include <rte_memcpy.h>
 #include <rte_common.h>
 
+#include "rte_trace_mempool_fp.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -736,6 +738,7 @@ rte_mempool_ops_dequeue_bulk(struct rte_mempool *mp,
 {
 	struct rte_mempool_ops *ops;
 
+	rte_trace_lib_mempool_ops_dequeue_bulk(mp, obj_table, n);
 	ops = rte_mempool_get_ops(mp->ops_index);
 	return ops->dequeue(mp, obj_table, n);
 }
@@ -761,6 +764,7 @@ rte_mempool_ops_dequeue_contig_blocks(struct rte_mempool *mp,
 
 	ops = rte_mempool_get_ops(mp->ops_index);
 	RTE_ASSERT(ops->dequeue_contig_blocks != NULL);
+	rte_trace_lib_mempool_ops_dequeue_contig_blocks(mp, first_obj_table, n);
 	return ops->dequeue_contig_blocks(mp, first_obj_table, n);
 }
 
@@ -783,6 +787,7 @@ rte_mempool_ops_enqueue_bulk(struct rte_mempool *mp, void * const *obj_table,
 {
 	struct rte_mempool_ops *ops;
 
+	rte_trace_lib_mempool_ops_enqueue_bulk(mp, obj_table, n);
 	ops = rte_mempool_get_ops(mp->ops_index);
 	return ops->enqueue(mp, obj_table, n);
 }
@@ -1264,6 +1269,8 @@ rte_mempool_default_cache(struct rte_mempool *mp, unsigned lcore_id)
 	if (lcore_id >= RTE_MAX_LCORE)
 		return NULL;
 
+	rte_trace_lib_mempool_default_cache(mp, lcore_id,
+					    &mp->local_cache[lcore_id]);
 	return &mp->local_cache[lcore_id];
 }
 
@@ -1283,6 +1290,7 @@ rte_mempool_cache_flush(struct rte_mempool_cache *cache,
 		cache = rte_mempool_default_cache(mp, rte_lcore_id());
 	if (cache == NULL || cache->len == 0)
 		return;
+	rte_trace_lib_mempool_cache_flush(cache, mp);
 	rte_mempool_ops_enqueue_bulk(mp, cache->objs, cache->len);
 	cache->len = 0;
 }
@@ -1362,6 +1370,7 @@ static __rte_always_inline void
 rte_mempool_generic_put(struct rte_mempool *mp, void * const *obj_table,
 			unsigned int n, struct rte_mempool_cache *cache)
 {
+	rte_trace_lib_mempool_generic_put(mp, obj_table, n, cache);
 	__mempool_check_cookies(mp, obj_table, n, 0);
 	__mempool_generic_put(mp, obj_table, n, cache);
 }
@@ -1386,6 +1395,7 @@ rte_mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
 {
 	struct rte_mempool_cache *cache;
 	cache = rte_mempool_default_cache(mp, rte_lcore_id());
+	rte_trace_lib_mempool_put_bulk(mp, obj_table, n, cache);
 	rte_mempool_generic_put(mp, obj_table, n, cache);
 }
 
@@ -1507,6 +1517,7 @@ rte_mempool_generic_get(struct rte_mempool *mp, void **obj_table,
 	ret = __mempool_generic_get(mp, obj_table, n, cache);
 	if (ret == 0)
 		__mempool_check_cookies(mp, obj_table, n, 1);
+	rte_trace_lib_mempool_generic_get(mp, obj_table, n, cache);
 	return ret;
 }
 
@@ -1537,6 +1548,7 @@ rte_mempool_get_bulk(struct rte_mempool *mp, void **obj_table, unsigned int n)
 {
 	struct rte_mempool_cache *cache;
 	cache = rte_mempool_default_cache(mp, rte_lcore_id());
+	rte_trace_lib_mempool_get_bulk(mp, obj_table, n, cache);
 	return rte_mempool_generic_get(mp, obj_table, n, cache);
 }
 
@@ -1606,6 +1618,7 @@ rte_mempool_get_contig_blocks(struct rte_mempool *mp,
 		__MEMPOOL_CONTIG_BLOCKS_STAT_ADD(mp, get_fail, n);
 	}
 
+	rte_trace_lib_mempool_get_contig_blocks(mp, first_obj_table, n);
 	return ret;
 }
 
diff --git a/lib/librte_mempool/rte_mempool_ops.c b/lib/librte_mempool/rte_mempool_ops.c
index 22c5251eb..c1b24a1f3 100644
--- a/lib/librte_mempool/rte_mempool_ops.c
+++ b/lib/librte_mempool/rte_mempool_ops.c
@@ -11,6 +11,8 @@
 #include <rte_errno.h>
 #include <rte_dev.h>
 
+#include "rte_trace_mempool.h"
+
 /* indirect jump table to support external memory pools. */
 struct rte_mempool_ops_table rte_mempool_ops_table = {
 	.sl =  RTE_SPINLOCK_INITIALIZER,
@@ -74,6 +76,7 @@ rte_mempool_ops_alloc(struct rte_mempool *mp)
 {
 	struct rte_mempool_ops *ops;
 
+	rte_trace_lib_mempool_ops_alloc(mp);
 	ops = rte_mempool_get_ops(mp->ops_index);
 	return ops->alloc(mp);
 }
@@ -84,6 +87,7 @@ rte_mempool_ops_free(struct rte_mempool *mp)
 {
 	struct rte_mempool_ops *ops;
 
+	rte_trace_lib_mempool_ops_free(mp);
 	ops = rte_mempool_get_ops(mp->ops_index);
 	if (ops->free == NULL)
 		return;
@@ -130,6 +134,8 @@ rte_mempool_ops_populate(struct rte_mempool *mp, unsigned int max_objs,
 
 	ops = rte_mempool_get_ops(mp->ops_index);
 
+	rte_trace_lib_mempool_ops_populate(mp, max_objs, vaddr, iova, len,
+					   obj_cb, obj_cb_arg);
 	if (ops->populate == NULL)
 		return rte_mempool_op_populate_default(mp, max_objs, vaddr,
 						       iova, len, obj_cb,
@@ -178,5 +184,6 @@ rte_mempool_set_ops_byname(struct rte_mempool *mp, const char *name,
 
 	mp->ops_index = i;
 	mp->pool_config = pool_config;
+	rte_trace_lib_mempool_set_ops_byname(mp, name, pool_config);
 	return 0;
 }
diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
index d002dfc46..2d2594635 100644
--- a/lib/librte_mempool/rte_mempool_version.map
+++ b/lib/librte_mempool/rte_mempool_version.map
@@ -45,4 +45,30 @@ EXPERIMENTAL {
 	rte_mempool_get_page_size;
 	rte_mempool_op_calc_mem_size_helper;
 	rte_mempool_op_populate_helper;
+
+	# added in 20.05
+	__rte_trace_lib_mempool_ops_dequeue_bulk;
+	__rte_trace_lib_mempool_ops_dequeue_contig_blocks;
+	__rte_trace_lib_mempool_ops_enqueue_bulk;
+	__rte_trace_lib_mempool_generic_put;
+	__rte_trace_lib_mempool_put_bulk;
+	__rte_trace_lib_mempool_generic_get;
+	__rte_trace_lib_mempool_get_bulk;
+	__rte_trace_lib_mempool_get_contig_blocks;
+	__rte_trace_lib_mempool_create;
+	__rte_trace_lib_mempool_create_empty;
+	__rte_trace_lib_mempool_free;
+	__rte_trace_lib_mempool_populate_iova;
+	__rte_trace_lib_mempool_populate_virt;
+	__rte_trace_lib_mempool_populate_default;
+	__rte_trace_lib_mempool_populate_anon;
+	__rte_trace_lib_mempool_cache_create;
+	__rte_trace_lib_mempool_cache_free;
+	__rte_trace_lib_mempool_default_cache;
+	__rte_trace_lib_mempool_get_page_size;
+	__rte_trace_lib_mempool_cache_flush;
+	__rte_trace_lib_mempool_ops_populate;
+	__rte_trace_lib_mempool_ops_alloc;
+	__rte_trace_lib_mempool_ops_free;
+	__rte_trace_lib_mempool_set_ops_byname;
 };
diff --git a/lib/librte_mempool/rte_trace_mempool.h b/lib/librte_mempool/rte_trace_mempool.h
new file mode 100644
index 000000000..12af2e301
--- /dev/null
+++ b/lib/librte_mempool/rte_trace_mempool.h
@@ -0,0 +1,148 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_MEMPOOL_H_
+#define _RTE_TRACE_MEMPOOL_H_
+
+/**
+ * @file
+ *
+ * APIs for mempool trace support
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "rte_mempool.h"
+
+#include <rte_trace.h>
+#include <rte_memzone.h>
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_create,
+	RTE_TRACE_POINT_ARGS(const char *name, uint32_t nb_elts,
+			     uint32_t elt_size, uint32_t cache_size,
+			     uint32_t private_data_size, void *mp_init,
+			     void *mp_init_arg, void *obj_init,
+			     void *obj_init_arg, uint32_t flags,
+			     struct rte_mempool *mempool),
+	rte_trace_ctf_string(name); rte_trace_ctf_u32(nb_elts);
+	rte_trace_ctf_u32(elt_size); rte_trace_ctf_u32(cache_size);
+	rte_trace_ctf_u32(private_data_size); rte_trace_ctf_ptr(mp_init);
+	rte_trace_ctf_ptr(mp_init_arg); rte_trace_ctf_ptr(obj_init);
+	rte_trace_ctf_ptr(obj_init_arg); rte_trace_ctf_u32(flags);
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_i32(mempool->ops_index);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_create_empty,
+	RTE_TRACE_POINT_ARGS(const char *name, uint32_t nb_elts,
+			     uint32_t elt_size, uint32_t cache_size,
+			     uint32_t private_data_size, uint32_t flags,
+			     struct rte_mempool *mempool),
+	rte_trace_ctf_string(name); rte_trace_ctf_u32(nb_elts);
+	rte_trace_ctf_u32(elt_size); rte_trace_ctf_u32(cache_size);
+	rte_trace_ctf_u32(private_data_size); rte_trace_ctf_u32(flags);
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_i32(mempool->ops_index);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_free,
+	RTE_TRACE_POINT_ARGS(struct rte_mempool *mempool),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_string(mempool->name);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_populate_iova,
+	RTE_TRACE_POINT_ARGS(struct rte_mempool *mempool, void *vaddr,
+			     rte_iova_t iova, size_t len, void *free_cb,
+			     void *opaque),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_string(mempool->name);
+	rte_trace_ctf_ptr(vaddr); rte_trace_ctf_u64(iova);
+	rte_trace_ctf_long(len); rte_trace_ctf_ptr(free_cb);
+	rte_trace_ctf_ptr(opaque);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_populate_virt,
+	RTE_TRACE_POINT_ARGS(struct rte_mempool *mempool, void *addr,
+			     size_t len, size_t pg_sz, void *free_cb,
+			     void *opaque),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_string(mempool->name);
+	rte_trace_ctf_ptr(addr); rte_trace_ctf_long(len);
+	rte_trace_ctf_long(pg_sz); rte_trace_ctf_ptr(free_cb);
+	rte_trace_ctf_ptr(opaque);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_populate_default,
+	RTE_TRACE_POINT_ARGS(struct rte_mempool *mempool),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_string(mempool->name);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_populate_anon,
+	RTE_TRACE_POINT_ARGS(struct rte_mempool *mempool),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_string(mempool->name);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_cache_create,
+	RTE_TRACE_POINT_ARGS(uint32_t size, int socket_id,
+			     struct rte_mempool_cache *cache),
+	rte_trace_ctf_u32(size); rte_trace_ctf_i32(socket_id);
+	rte_trace_ctf_ptr(cache); rte_trace_ctf_u32(cache->len);
+	rte_trace_ctf_u32(cache->flushthresh);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_cache_free,
+	RTE_TRACE_POINT_ARGS(void *cache),
+	rte_trace_ctf_ptr(cache);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_get_page_size,
+	RTE_TRACE_POINT_ARGS(struct rte_mempool *mempool, size_t pg_sz),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_string(mempool->name);
+	rte_trace_ctf_long(pg_sz);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_ops_populate,
+	RTE_TRACE_POINT_ARGS(struct rte_mempool *mempool, uint32_t max_objs,
+			     void *vaddr, uint64_t iova, size_t len,
+			     void *obj_cb, void *obj_cb_arg),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_string(mempool->name);
+	rte_trace_ctf_u32(max_objs); rte_trace_ctf_ptr(vaddr);
+	rte_trace_ctf_u64(iova); rte_trace_ctf_long(len);
+	rte_trace_ctf_ptr(obj_cb); rte_trace_ctf_ptr(obj_cb_arg);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_ops_alloc,
+	RTE_TRACE_POINT_ARGS(struct rte_mempool *mempool),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_string(mempool->name);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_ops_free,
+	RTE_TRACE_POINT_ARGS(struct rte_mempool *mempool),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_string(mempool->name);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_mempool_set_ops_byname,
+	RTE_TRACE_POINT_ARGS(struct rte_mempool *mempool, const char *name,
+			     void *pool_config),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_string(mempool->name);
+	rte_trace_ctf_string(name); rte_trace_ctf_ptr(pool_config);
+)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TRACE_MEMPOOL_H_ */
diff --git a/lib/librte_mempool/rte_trace_mempool_fp.h b/lib/librte_mempool/rte_trace_mempool_fp.h
new file mode 100644
index 000000000..7aad5e3c2
--- /dev/null
+++ b/lib/librte_mempool/rte_trace_mempool_fp.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_MEMPOOL_FP_H_
+#define _RTE_TRACE_MEMPOOL_FP_H_
+
+/**
+ * @file
+ *
+ * Mempool fast path API for trace support
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_trace.h>
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_mempool_ops_dequeue_bulk,
+	RTE_TRACE_POINT_ARGS(void *mempool, void **obj_table,
+			     uint32_t nb_objs),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_ptr(obj_table);
+	rte_trace_ctf_u32(nb_objs);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_mempool_ops_dequeue_contig_blocks,
+	RTE_TRACE_POINT_ARGS(void *mempool, void **first_obj_table,
+			     uint32_t nb_objs),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_ptr(first_obj_table);
+	rte_trace_ctf_u32(nb_objs);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_mempool_ops_enqueue_bulk,
+	RTE_TRACE_POINT_ARGS(void *mempool, void * const *obj_table,
+			     uint32_t nb_objs),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_ptr(obj_table);
+	rte_trace_ctf_u32(nb_objs);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_mempool_generic_put,
+	RTE_TRACE_POINT_ARGS(void *mempool, void * const *obj_table,
+			     uint32_t nb_objs, void *cache),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_ptr(obj_table);
+	rte_trace_ctf_u32(nb_objs); rte_trace_ctf_ptr(cache);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_mempool_put_bulk,
+	RTE_TRACE_POINT_ARGS(void *mempool, void * const *obj_table,
+			     uint32_t nb_objs, void *cache),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_ptr(obj_table);
+	rte_trace_ctf_u32(nb_objs); rte_trace_ctf_ptr(cache);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_mempool_generic_get,
+	RTE_TRACE_POINT_ARGS(void *mempool, void * const *obj_table,
+			     uint32_t nb_objs, void *cache),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_ptr(obj_table);
+	rte_trace_ctf_u32(nb_objs); rte_trace_ctf_ptr(cache);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_mempool_get_bulk,
+	RTE_TRACE_POINT_ARGS(void *mempool, void **obj_table,
+			     uint32_t nb_objs, void *cache),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_ptr(obj_table);
+	rte_trace_ctf_u32(nb_objs); rte_trace_ctf_ptr(cache);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_mempool_get_contig_blocks,
+	RTE_TRACE_POINT_ARGS(void *mempool, void **first_obj_table,
+			     uint32_t nb_objs),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_ptr(first_obj_table);
+	rte_trace_ctf_u32(nb_objs);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_mempool_default_cache,
+	RTE_TRACE_POINT_ARGS(void *mempool, uint32_t lcore_id,
+			     void *default_cache),
+	rte_trace_ctf_ptr(mempool); rte_trace_ctf_u32(lcore_id);
+	rte_trace_ctf_ptr(default_cache);
+)
+
+RTE_TRACE_POINT_DP(
+	rte_trace_lib_mempool_cache_flush,
+	RTE_TRACE_POINT_ARGS(void *cache, void *mempool),
+	rte_trace_ctf_ptr(cache); rte_trace_ctf_ptr(mempool);
+)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TRACE_MEMPOOL_FP_H_ */
diff --git a/lib/librte_reorder/Makefile b/lib/librte_reorder/Makefile
index 1914411d5..26e7bbfbc 100644
--- a/lib/librte_reorder/Makefile
+++ b/lib/librte_reorder/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_reorder.a
 
 CFLAGS += -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
 LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf
 
diff --git a/lib/librte_reorder/meson.build b/lib/librte_reorder/meson.build
index 03aed53d9..964f01d9b 100644
--- a/lib/librte_reorder/meson.build
+++ b/lib/librte_reorder/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_reorder.c')
 headers = files('rte_reorder.h')
 deps += ['mbuf']
diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile
index aee93a120..4ad7a18cd 100644
--- a/lib/librte_sched/Makefile
+++ b/lib/librte_sched/Makefile
@@ -10,6 +10,7 @@ LIB = librte_sched.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 LDLIBS += -lm
 LDLIBS += -lrt
diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build
index f85d64df8..ba178a126 100644
--- a/lib/librte_sched/meson.build
+++ b/lib/librte_sched/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c')
 headers = files('rte_sched.h', 'rte_sched_common.h',
 		'rte_red.h', 'rte_approx.h')
diff --git a/lib/librte_security/Makefile b/lib/librte_security/Makefile
index 825eaeff8..bf530e99a 100644
--- a/lib/librte_security/Makefile
+++ b/lib/librte_security/Makefile
@@ -9,6 +9,7 @@ LIB = librte_security.a
 # build flags
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_mempool
 
 # library source files
diff --git a/lib/librte_security/meson.build b/lib/librte_security/meson.build
index 5679c8b5c..ada46b0c6 100644
--- a/lib/librte_security/meson.build
+++ b/lib/librte_security/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017-2019 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_security.c')
 headers = files('rte_security.h', 'rte_security_driver.h')
 deps += ['mempool', 'cryptodev']
diff --git a/lib/librte_table/Makefile b/lib/librte_table/Makefile
index 6ad8a6b17..88cb909be 100644
--- a/lib/librte_table/Makefile
+++ b/lib/librte_table/Makefile
@@ -10,6 +10,7 @@ LIB = librte_table.a
 
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_port
 LDLIBS += -lrte_lpm -lrte_hash
 ifeq ($(CONFIG_RTE_LIBRTE_ACL),y)
diff --git a/lib/librte_table/meson.build b/lib/librte_table/meson.build
index 71d134768..05703e67c 100644
--- a/lib/librte_table/meson.build
+++ b/lib/librte_table/meson.build
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
+allow_experimental_apis = true
 sources = files('rte_table_acl.c',
 		'rte_table_lpm.c',
 		'rte_table_lpm_ipv6.c',
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v1 32/32] doc: add trace library guide
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (30 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 31/32] mempool: " jerinj
@ 2020-03-18 19:02 ` jerinj
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-18 19:02 UTC (permalink / raw)
  To: John McNamara, Marko Kovacevic
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Sunil Kumar Kori <skori@marvell.com>

Add programmar's guide for trace library support.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 doc/guides/prog_guide/index.rst        |   1 +
 doc/guides/prog_guide/trace_lib.rst    | 264 +++++++++++++++++++++++++
 doc/guides/rel_notes/release_20_05.rst |   4 +
 3 files changed, 269 insertions(+)
 create mode 100644 doc/guides/prog_guide/trace_lib.rst

diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index fb250abf5..0daa08acc 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -35,6 +35,7 @@ Programmer's Guide
     lpm_lib
     lpm6_lib
     flow_classify_lib
+    trace_lib
     packet_distrib_lib
     reorder_lib
     ip_fragment_reassembly_lib
diff --git a/doc/guides/prog_guide/trace_lib.rst b/doc/guides/prog_guide/trace_lib.rst
new file mode 100644
index 000000000..9e3308736
--- /dev/null
+++ b/doc/guides/prog_guide/trace_lib.rst
@@ -0,0 +1,264 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(C) 2020 Marvell International Ltd.
+
+Trace Library
+=============
+
+DPDK provides a tracing library that gives the ability to add tracepoints
+in application to get runtime trace/debug information for control and fast
+APIs with minimum impact on fast path performance.
+
+Library mainly caters below mentioned use cases:
+
+- The DPDK provider will not have access to the DPDK customer applications.
+  Inbuilt tracer support will us enable to debug/analyze the slow path and
+  fast path DPDK API usage.
+
+- Provides a low overhead fast path multi-core PMD driver's debugging/analysis
+  infrastructure to fix the functional and performance issue(s).
+
+- Post trace analysis tools can provide various status across the system such
+  as cpu_idle() using the timestamp added in the trace.
+
+Below sections will provide detailed information about:
+
+ - Trace a user application
+ - View and analyze the recorded events
+
+Trace a user application
+------------------------
+
+This section steps you through a simple example to trace an application.
+A trace can be achieved using below mentioned steps:
+
+Define and register a tracepoint
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The application can define and register tracepoints either existing C file or
+create a new file (say xyz_app_trace_point.c). Also, all the tracepoints must be
+resolved before rte_eal_init i.e. tracepoints must be registered as constructor
+using RTE_INIT interface.
+
+Following are the MACRO definition exposed by the trace Library to define and
+register a tracepoint.
+
+.. code-block:: c
+
+ #define RTE_TRACE_POINT_DEFINE(tp)\
+        uint64_t __attribute__((section("__rte_trace_point"))) __##tp
+
+ #define RTE_TRACE_POINT_REGISTER(trace, name, level)\
+       __rte_trace_point_register(&__##trace, RTE_STR(name), RTE_LOG_ ## level,\
+                                  (void (*)(void)) trace)
+
+Example tracepoint definition and registration
+
+.. code-block:: c
+
+ RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_str); /* Definition */
+
+ RTE_INIT(eal_trace_init)
+ {
+     /* Registration */
+     RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_str,
+                              lib.eal.generic.str, INFO);
+ }
+
+For more details refer trace API documentation.
+Defined tracepoint must be exported into corresponding .map file.
+
+.. Note::
+
+    A tracepoint is defined like __##tp i.e. __rte_trace_lib_eal_generic_str
+    for above example. Same must be updated into corresponding .map file.
+
+Define trace function to write events
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+After a successful tracepoint registration, the application must define a
+trace function which solves three purposes:
+
+ - Calculates the size of the event.
+ - Generate CTF metadata field string for the event.
+ - Emit the event to trace memory.
+
+A tracepoint can be classified as either a data path or a slow path tracepoint.
+So based on that, the application must define tracepoint function using one of
+the mentioned MACRO
+
+.. code-block:: c
+
+ /* Define tracepoint function for slow path */
+ #define RTE_TRACE_POINT(tp, args, ...)\
+        __RTE_TRACE_POINT(generic, tp, args, __VA_ARGS__)
+
+ /* Define tracepoint function for data path */
+ #define RTE_TRACE_POINT_DP(tp, args, ...)\
+        __RTE_TRACE_POINT(dp, tp, args, __VA_ARGS__)
+
+RTE_TRACE_POINT_DP is compiled out by default and can be enabled using
+CONFIG_RTE_ENABLE_TRACE_DP configuration parameter. Also application can use
+``rte_trace_is_dp_enabled`` to get current status of RTE_TRACE_POINT_DP.
+For more details, refer DPDK Trace API documentation.
+
+Example tracepoint function definition
+
+.. code-block:: c
+
+ /* Slow path tracepoint */
+ RTE_TRACE_POINT(
+        rte_trace_lib_eal_generic_str,
+        RTE_TRACE_POINT_ARGS(const char *str),
+        rte_trace_ctf_string(str);
+ )
+
+ /* Data path tracepoint */
+ RTE_TRACE_POINT_DP(
+        rte_trace_lib_eal_generic_str,
+        RTE_TRACE_POINT_ARGS(const char *str),
+        rte_trace_ctf_string(str);
+ )
+
+Emit events to trace memory
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+After trace function definition is ready to emit tracepoints.
+To emit the event application needs to invoke tracepoint function, as defined
+in the above steps, at the desired location.
+
+Below examples emit tracepoints in ``rte_eth_dev_configure`` to print a test
+string:
+
+.. code-block:: c
+
+ int
+ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
+        const struct rte_eth_conf *dev_conf)
+ {
+        struct rte_eth_dev *dev;
+        struct rte_eth_dev_info dev_info;
+        struct rte_eth_conf orig_conf;
+        int diag;
+        int ret;
+
+        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+
+        dev = &rte_eth_devices[port_id];
+
+        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
+
+        ...
+
+        rte_trace_lib_eal_generic_str("tp_test_string");
+        return ret;
+ }
+
+Generate CTF formatted metadata
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+As of now emitted events just specify the debug information written by the
+application but to view/analyze these events must be formatted into Common Trace
+Format(CTF) so that any CTF compliant trace analysis tool can view those traces.
+
+Trace library exposes below API to write events to CTF formatted metadata file.
+
+.. code-block:: c
+
+ int rte_trace_save(void);
+
+Currently library invokes this API implicitly during tear down and metadata file
+is generated at either ``/root/dpdk-traces/rte-yyyy-mm-dd-[AP]M-hh-mm-ss/`` or
+at location if user has passed during command line(``say /tmp``) then
+``/tmp/rte-yyyy-mm-dd-[AP]M-hh-mm-ss/``
+
+For more information, refer :doc:`../linux_gsg/linux_eal_parameters` for trace.
+
+View and analyze the recorded events
+------------------------------------
+Once ``Trace a user application`` is completed, the user can view/inspect the
+recorded events.
+
+There are many tools you can use to read DPDK traces:
+
+ - ``babeltrace`` is a command-line utility that converts trace formats; it
+   supports the format that DPDK trace library produces, CTF, as well as a
+   basic text output that can be grep ed. The babeltrace command is part of the
+   opensource ``Babeltrace`` project.
+
+ - ``Trace Compass`` is a graphical user interface for viewing and analyzing any
+   type of logs or traces, including DPDK traces.
+
+.. Note::
+
+   This section assumes that the trace library saved the traces, it recorded
+   during the previous tutorials, to their specified location.
+
+
+Use the babeltrace command-line tool
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The simplest way to list all the recorded events of a trace is to pass its path
+to babeltrace with no options::
+
+    babeltrace </path-to-trace-events/rte-yyyy-mm-dd-[AP]M-hh-mm-ss/>
+
+``babeltrace`` finds all traces recursively within the given path and prints all
+their events, merging them in chronological order.
+
+You can pipe the output of the babeltrace into a tool like grep(1) for further
+filtering. Below example grep the events for ``ethdev`` only::
+
+    babeltrace /tmp/my-dpdk-trace | grep ethdev
+
+You can pipe the output of babeltrace into a tool like wc(1) to count the
+recorded events. Below example count the number of ``ethdev`` events::
+
+    babeltrace /tmp/my-dpdk-trace | grep ethdev | wc --lines
+
+Use the tracecompass GUI tool
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+``Tracecompass`` is another tool to view/analyze the DPDK traces which gives
+a graphical view of events. Like ``babeltrace``, tracecompass also provides
+an interface to search for a particular event. To use ``tracecompass``, following are
+the minimum required steps:
+
+ - Install ``tracecompass`` to the localhost. Variants are available for Linux,
+   Windows, and OS-X.
+ - Launch ``tracecompass`` which will open a graphical window with trace
+   management interfaces.
+ - Open a trace using ``File->Open Trace`` option and select metadata file
+   which is to be viewed/analyzed.
+
+For more details, refer `Trace Compass <https://www.eclipse.org/tracecompass/>`_
+
+Core Concepts
+-------------
+As DPDK trace library is designed to generate traces that uses Common Trace
+Format(CTF). CTF specification consist of following units to create a trace.
+
+ - ``Stream`` Sequence of packets.
+ - ``Packet`` Header and one or more events.
+ - ``Event`` Header and payload.
+
+For detailed information, refer `Common Trace Format <https://diamon.org/ctf/>`_
+
+Channel and trace memory
+~~~~~~~~~~~~~~~~~~~~~~~~
+A channel is an object which is responsible for holding the trace memory.
+The trace library creates the trace memory per thread to enable the lock-less
+scheme to emit the event. When a DPDK tracer emits an event, it will be recorded
+to the trace buffers that associated with that thread.
+
+Event record mode
+~~~~~~~~~~~~~~~~~
+Event record mode is an attribute of trace buffers. Trace library exposes two
+modes:
+
+ - ``Overwrite`` This mode enables trace buffers to wrap around when trace buffer memory is full.
+ - ``Discard`` This mode enables trace buffers to discard when trace buffer memory is full.
+
+This mode can be enabled/disabled either using eal command line parameters or
+DPDK trace library API to configure the mode.
+Refer :doc:`../linux_gsg/linux_eal_parameters` and trace API documentation more
+details.
+
+Metadata
+~~~~~~~~
+Metadata defines the layout of event records so that trace analysis tool can
+read the streams and show into the relevant format.
+For more details, refer `Common Trace Format <https://diamon.org/ctf/>`_.
diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
index 2190eaf85..fbceed245 100644
--- a/doc/guides/rel_notes/release_20_05.rst
+++ b/doc/guides/rel_notes/release_20_05.rst
@@ -56,6 +56,10 @@ New Features
      Also, make sure to start the actual text at the margin.
      =========================================================
 
+* **Added Trace Library.**
+
+  A new library is added to record CTF based trace events to debug/analyze
+  DPDK application for slow and fast path APIs at run time.
 
 Removed Items
 -------------
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 02/32] eal: define the public API for trace support
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 02/32] eal: define the public API for trace support jerinj
@ 2020-03-18 20:58   ` Mattias Rönnblom
  2020-03-23 14:29     ` Jerin Jacob
  0 siblings, 1 reply; 142+ messages in thread
From: Mattias Rönnblom @ 2020-03-18 20:58 UTC (permalink / raw)
  To: jerinj, Thomas Monjalon, Bruce Richardson, John McNamara,
	Marko Kovacevic, Sunil Kumar Kori
  Cc: dev, david.marchand

On 2020-03-18 20:02, jerinj@marvell.com wrote:
> From: Jerin Jacob <jerinj@marvell.com>
>
> Define the public API for trace support.
> This patch also adds support for the build infrastructure and
> update the MAINTAINERS file for the trace subsystem.
>
> Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> ---
>   MAINTAINERS                               |   6 +
>   config/common_base                        |   1 +
>   config/rte_config.h                       |   1 +
>   doc/api/doxy-api-index.md                 |   3 +-
>   lib/librte_eal/common/Makefile            |   1 +
>   lib/librte_eal/common/eal_common_trace.c  |   6 +
>   lib/librte_eal/common/include/rte_trace.h | 525 ++++++++++++++++++++++
>   lib/librte_eal/common/meson.build         |   2 +
>   lib/librte_eal/freebsd/eal/Makefile       |   1 +
>   lib/librte_eal/linux/eal/Makefile         |   1 +
>   10 files changed, 546 insertions(+), 1 deletion(-)
>   create mode 100644 lib/librte_eal/common/eal_common_trace.c
>   create mode 100644 lib/librte_eal/common/include/rte_trace.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c3785554f..63d85c7da 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -196,6 +196,12 @@ F: app/test/test_string_fns.c
>   F: app/test/test_tailq.c
>   F: app/test/test_version.c
>   
> +Trace
> +M: Jerin Jacob <jerinj@marvell.com>
> +M: Sunil Kumar Kori <skori@marvell.com>
> +F: lib/librte_eal/common/include/rte_trace*.h
> +F: lib/librte_eal/common/eal_common_trace*.c
> +
>   Memory Allocation
>   M: Anatoly Burakov <anatoly.burakov@intel.com>
>   F: lib/librte_eal/common/include/rte_fbarray.h
> diff --git a/config/common_base b/config/common_base
> index 7ca2f28b1..efc195af2 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -99,6 +99,7 @@ CONFIG_RTE_MAX_MEMZONE=2560
>   CONFIG_RTE_MAX_TAILQ=32
>   CONFIG_RTE_ENABLE_ASSERT=n
>   CONFIG_RTE_LOG_DP_LEVEL=RTE_LOG_INFO
> +CONFIG_RTE_ENABLE_TRACE_DP=n
>   CONFIG_RTE_LOG_HISTORY=256
>   CONFIG_RTE_BACKTRACE=y
>   CONFIG_RTE_LIBEAL_USE_HPET=n
> diff --git a/config/rte_config.h b/config/rte_config.h
> index d30786bc0..6b250288c 100644
> --- a/config/rte_config.h
> +++ b/config/rte_config.h
> @@ -42,6 +42,7 @@
>   #define RTE_MAX_MEMZONE 2560
>   #define RTE_MAX_TAILQ 32
>   #define RTE_LOG_DP_LEVEL RTE_LOG_INFO
> +#define RTE_ENABLE_TRACE_DP 0
>   #define RTE_BACKTRACE 1
>   #define RTE_MAX_VFIO_CONTAINERS 64
>   
> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> index dff496be0..190f0ccc2 100644
> --- a/doc/api/doxy-api-index.md
> +++ b/doc/api/doxy-api-index.md
> @@ -174,7 +174,8 @@ The public API headers are grouped by topics:
>     [hexdump]            (@ref rte_hexdump.h),
>     [debug]              (@ref rte_debug.h),
>     [log]                (@ref rte_log.h),
> -  [errno]              (@ref rte_errno.h)
> +  [errno]              (@ref rte_errno.h),
> +  [trace]              (@ref rte_trace.h)
>   
>   - **misc**:
>     [EAL config]         (@ref rte_eal.h),
> diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
> index c2c6d92cd..9384d6f6e 100644
> --- a/lib/librte_eal/common/Makefile
> +++ b/lib/librte_eal/common/Makefile
> @@ -9,6 +9,7 @@ INC += rte_debug.h rte_eal.h rte_eal_interrupts.h
>   INC += rte_errno.h rte_launch.h rte_lcore.h
>   INC += rte_log.h rte_memory.h rte_memzone.h
>   INC += rte_per_lcore.h rte_random.h
> +INC += rte_trace.h
>   INC += rte_tailq.h rte_interrupts.h rte_alarm.h
>   INC += rte_string_fns.h rte_version.h
>   INC += rte_eal_memconfig.h
> diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
> new file mode 100644
> index 000000000..e18ba1c95
> --- /dev/null
> +++ b/lib/librte_eal/common/eal_common_trace.c
> @@ -0,0 +1,6 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2020 Marvell International Ltd.
> + */
> +
> +#include <rte_trace.h>
> +
> diff --git a/lib/librte_eal/common/include/rte_trace.h b/lib/librte_eal/common/include/rte_trace.h
> new file mode 100644
> index 000000000..d008b64f1
> --- /dev/null
> +++ b/lib/librte_eal/common/include/rte_trace.h
> @@ -0,0 +1,525 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2020 Marvell International Ltd.
> + */
> +
> +#ifndef _RTE_TRACE_H_
> +#define _RTE_TRACE_H_
> +
> +/**
> + * @file
> + *
> + * RTE Trace API
> + *
> + * This file provides the trace API to RTE applications.
> + *
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <stdbool.h>
> +#include <stdio.h>
> +
> +#include <rte_common.h>
> +#include <rte_compat.h>
> +
> +/** The trace object. The trace APIs are based on this opaque object. */
> +typedef uint64_t *rte_trace_t;

Wouldn't a forward-declared struct, with the definition hidden from the 
user, be more appropriate? As a bonus, you'll get some type checking.

"struct rte_trace;" here and "struct rte_trace*" in all the APIs. 
"struct rte_trace { uint64_t val; }; in the implementation. Or just cast 
it to a uint64_t *.

typdef:ing pointers is generally considered a no-no, at least if you 
follow the Linux kernel coding conventions.

> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Enumerate trace mode operation.
> + */
> +enum rte_trace_mode_e {
> +	/**
> +	 * In this mode, When no space left in trace buffer, the subsequent
> +	 * events overwrite the old events in the trace buffer.
> +	 */
> +	RTE_TRACE_MODE_OVERWRITE,
> +	/**
> +	 * In this mode, When no space left on trace buffer, the subsequent
> +	 * events shall not be recorded in the trace buffer.
> +	 */
> +	RTE_TRACE_MODE_DISCARD,
> +};

Have you considered having a blocking mode as well, where the thread 
will just wait for space to be freed?

Remove the "_e" from the name. "enum" already tells us it's an enumeration.

> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Test if global trace is enabled.
> + *
> + * @return
> + *    true if global trace is enabled, false otherwise.
> + */
> +__rte_experimental
> +bool rte_trace_global_is_enabled(void);

My impression is that DPDK does:


__rte_experimental bool

rte_trace_global_is_enabled(void);


Now when I check the coding conventions, that's only for function 
definition. Why declaration and definition should be different, I don't 
know.

> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Test if global trace is disabled.
> + *
> + * @return
> + *    true if global trace is disabled, false otherwise.
> + */
> +__rte_experimental
> +bool rte_trace_global_is_disabled(void);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Test if a given trace is invalid.
> + * @param trace
> + *    The trace object.
> + * @return
> + *    true if global trace is invalid, false otherwise.
> + */
> +__rte_experimental
> +bool rte_trace_is_id_invalid(rte_trace_t trace);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Set the global trace level.
> + *
> + * After this call, trace with a level lower or equal than the level
> + * passed as argument will be captured in the trace buffer.
> + *
> + * @param level
> + *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
> + */
> +__rte_experimental
> +void rte_trace_global_level_set(uint32_t level);

uint32_t means a lot of levels.

> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Get the global trace level.
> + *
> + * @return
> + *   The current global trace level.
> + */
> +__rte_experimental
> +uint32_t rte_trace_global_level_get(void);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Set the global trace mode.
> + *
> + * After this call, All tracepoints will be switched to new mode.
> + *
> + * @param mode
> + *   Trace mode.
> + */
> +__rte_experimental
> +void rte_trace_global_mode_set(enum rte_trace_mode_e mode);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Get the global trace mode.
> + *
> + * @return
> + *   The current global trace mode.
> + */
> +__rte_experimental
> +enum rte_trace_mode_e rte_trace_global_mode_get(void);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Enable recording of the given tracepoint in the trace buffer.
> + *
> + * @param trace
> + *   The tracepoint object to enable.
> + * @return
> + *   - 0: Success.
> + *   - (-ERANGE): Trace object is not registered.
> + *   - (-EACCES): Trace object level is less than the global trace level.
> + */
> +__rte_experimental
> +int rte_trace_enable(rte_trace_t trace);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Disable recording of the given tracepoint in the trace buffer.
> + *
> + * @param trace
> + *   The tracepoint object to disable.
> + * @return
> + *   - 0: Success.
> + *   - (-ERANGE): Trace object is not registered.
> + */
> +__rte_experimental
> +int rte_trace_disable(rte_trace_t trace);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Test if given trace is enabled.
> + *
> + * @param trace
> + *    The trace object.
> + * @return
> + *    true if trace is enabled, false otherwise.
> + */
> +__rte_experimental
> +bool rte_trace_is_enabled(rte_trace_t trace);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Test if given trace is disabled.
> + *
> + * @param trace
> + *    The trace object.
> + * @return
> + *    true if trace is disabled, false otherwise.
> + */
> +__rte_experimental
> +bool rte_trace_is_disabled(rte_trace_t trace);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Set the trace level for the given tracepoint.
> + *
> + * After this call, if passed trace level lower or equal than the global trace
> + * level and this trace is enabled then trace will be captured in the
> + * trace buffer.
> + *
> + * @param trace
> + *    The trace object.
> + * @param level
> + *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
> + * @return
> + *   - 0: Success.
> + *   - (-EINVAL): Trace object is not registered or invalid trace level.
> + */
> +__rte_experimental
> +int rte_trace_level_set(rte_trace_t trace, uint32_t level);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Get the trace level for the given tracepoint.
> + *
> + * @param trace
> + *    The trace object.
> + * @return
> + *   - A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
> + *   - 0: Trace object is not registered.
> + */
> +__rte_experimental
> +uint32_t rte_trace_level_get(rte_trace_t trace);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Set the trace mode for the given tracepoint.
> + *
> + * @param trace
> + *    The trace object.
> + * @param mode
> + *   Trace mode.
> + * @return
> + *   - 0: Success.
> + *   - (-EINVAL): Trace object is not registered or invalid trace level.
> + */
> +__rte_experimental
> +int rte_trace_mode_set(rte_trace_t trace, enum rte_trace_mode_e mode);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Get the trace mode for the given tracepoint.
> + *
> + * @param trace
> + *    The trace object.
> + * @return
> + *   - Zero or positive: Mode encoded as enum rte_trace_mode_e.
> + *   - (-EINVAL): Trace object is not registered.
> + */
> +__rte_experimental
> +int rte_trace_mode_get(rte_trace_t trace);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Enable/Disable a set of tracepoints based on shell pattern.
Shell pattern means what I think is usually referred to as a glob?
> + *
> + * @param pattern
> + *   The match pattern identifying the tracepoint.
> + * @param enable
> + *    true to enable tracepoint, false to disable the tracepoint, upon match.
> + * @param[out] found
> + *    NULL value allowed, if not NULL, true if match found, false otherwise.
> + * @return
> + *   - 0: Success.
> + *   - (-ERANGE): Trace object is not registered.
> + */
> +__rte_experimental
> +int rte_trace_pattern(const char *pattern, bool enable, bool *found);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Enable/Disable a set of tracepoints based on regular expression.
> + *
> + * @param regex
> + *   A regular expression identifying the tracepoint.
> + * @param enable
> + *    true to enable tracepoint, false to disable the tracepoint, upon match.
> + * @param[out] found
> + *    NULL value allowed, if not NULL, true if match found, false otherwise.
What's the reason of having this output parameter, as opposed to coding 
the information into the return code?
> + * @return
> + *   - 0: Success.
> + *   - (-ERANGE): Trace object is not registered.
> + *   - (-EINVAL): Invalid regular expression rule.
> + */
> +__rte_experimental
> +int rte_trace_regexp(const char *regex, bool enable, bool *found);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Save the trace buffer to the trace directory.
> + *
> + * By default, trace directory will be created at HOME directory and this can be
> + * overridden by --trace-dir EAL parameter.
> + *
> + * @return
> + *   - 0: Success.
> + *   - <0 : Failure.
> + */
> +__rte_experimental
> +int rte_trace_save(void);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Search a trace object from its name.
> + *
> + * @param name
> + *   The name of the tracepoint.
> + * @return
> + *   The tracepoint object or NULL if not found.
> + */
> +__rte_experimental
> +rte_trace_t rte_trace_from_name(const char *name);

Would "rte_trace_by_name" be a better name?

> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Dump the trace metadata to a file.
> + *
> + * @param f
> + *   A pointer to a file for output
> + * @return
> + *   - 0: Success.
> + *   - <0 : Failure.
> + */
> +__rte_experimental
> +int rte_trace_metadata_dump(FILE *f);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + * Dump the trace subsystem status to a file.
> + *
> + * @param f
> + *   A pointer to a file for output
> + */
> +__rte_experimental
> +void rte_trace_dump(FILE *f);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Test if the trace datapath compile-time option is enabled.
> + *
> + * @return
> + *   A positive value if trace datapath enabled, value zero otherwise.
Switch to a bool return type.
> + */
> +static __rte_always_inline int
> +rte_trace_is_dp_enabled(void)
> +{
> +#ifdef RTE_ENABLE_TRACE_DP
> +	return RTE_ENABLE_TRACE_DP;
> +#else
> +	return 0;
> +#endif
> +}
> +
> +/** Macro to define the tracepoint. */
> +#define RTE_TRACE_POINT_DEFINE(tp)\
> +uint64_t __attribute__((section("__rte_trace_point"))) __##tp
> +
> +/**
> + * Macro to define the tracepoint arguments in RTE_TRACE_POINT macro.
> +
> + * @see RTE_TRACE_POINT RTE_TRACE_POINT_DP
> + */
> +#define RTE_TRACE_POINT_ARGS
> +
> +/** @internal Helper Macro to support RTE_TRACE_POINT and RTE_TRACE_POINT_DP */
> +#define __RTE_TRACE_POINT(_mode, _tp, _args, ...)\
> +extern uint64_t __##_tp;\
> +static __rte_always_inline void \
> +_tp _args \
> +{\
> +	__rte_trace_emit_header_##_mode(&__##_tp);\
> +	__VA_ARGS__\
> +}
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Create a tracepoint definition.
> + *
> + * A tracepoint definition defines, for a given tracepoint:
> + * - Its input arguments. They are the C function style parameters to define
> + * the arguments of tracepoint function. These input arguments embedded using
> + * RTE_TRACE_POINT_ARGS macro.
> + * - Its output event fields. They are the sources of event fields that form
> + * the payload of any event that the execution of the tracepoint macro emits
> + * for this particular tracepoint. The application uses rte_trace_ctf_* macros
> + * to emit the output event fields.
> + *
> + * @param tp
> + *   Tracepoint object. Before using the tracepoint, an application needs to
> + * define the tracepoint using RTE_TRACE_POINT_DEFINE() macro.
> + * @param args
> + *   C function style input arguments to define the arguments to tracepoint
> + * function.
> + * @param ...
> + *   Define the payload of trace function. The payload will be formed using
> + * rte_trace_ctf_* macros, Use ";" delimiter between two payloads.
> + *
> + * @see RTE_TRACE_POINT_ARGS, RTE_TRACE_POINT_DEFINE, rte_trace_ctf_*
> + */
> +#define RTE_TRACE_POINT(tp, args, ...)\
> +	__RTE_TRACE_POINT(generic, tp, args, __VA_ARGS__)
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Create a tracepoint definition for the data path.
> + *
> + * Similar to RTE_TRACE_POINT(), except that it is removed at compilation time
> + * using RTE_ENABLE_TRACE_DP configuration parameter.
> + *
> + * @param tp
> + *   Tracepoint object. Before using the tracepoint, an application needs to
> + * define the tracepoint using RTE_TRACE_POINT_DEFINE() macro.
> + * @param args
> + *   C function style input arguments to define the arguments to tracepoint
> + * function.
> + * @param ...
> + *   Define the payload of trace function. The payload will be formed using
> + * rte_trace_ctf_* macros, Use ";" delimiter between two payloads.
> + *
> + * @see rte_trace_is_dp_enabled, RTE_TRACE_POINT()
> + */
> +#define RTE_TRACE_POINT_DP(tp, args, ...)\
> +	__RTE_TRACE_POINT(dp, tp, args, __VA_ARGS__)
> +
> +#ifdef __DOXYGEN__
> +
> +/**
> + * Macro to select rte_trace_ctf_* definition for trace register function.
> + *
> + * rte_trace_ctf_* emits different definitions for trace function.
> + * Application must define RTE_TRACE_POINT_REGISTER_SELECT before including
> + * rte_trace.h in the C file where RTE_TRACE_POINT_REGISTER() used.
> + *
> + * @see RTE_TRACE_POINT_REGISTER()
> + */
> +#define RTE_TRACE_POINT_REGISTER_SELECT
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Register a dynamic tracepoint.
> + *
> + * @param trace
> + *   The tracepoint object created using RTE_TRACE_POINT_DEFINE().
> + * @param name
> + *   The name of the tracepoint object.
> + * @param level
> + *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
> + * @return
> + *   - 0: Successfully registered the tracepoint.
> + *   - <0: Failure to register the tracepoint.
> + *
> + * @see RTE_TRACE_POINT_REGISTER_SELECT
> + */
> +#define RTE_TRACE_POINT_REGISTER(trace, name, level)
> +
> +/** Tracepoint function payload for uint64_t datatype */
> +#define rte_trace_ctf_u64(val)
> +/** Tracepoint function payload for int64_t datatype */
> +#define rte_trace_ctf_i64(val)
> +/** Tracepoint function payload for uint32_t datatype */
> +#define rte_trace_ctf_u32(val)
> +/** Tracepoint function payload for int32_t datatype */
> +#define rte_trace_ctf_i32(val)
> +/** Tracepoint function payload for uint16_t datatype */
> +#define rte_trace_ctf_u16(val)
> +/** Tracepoint function payload for int16_t datatype */
> +#define rte_trace_ctf_i16(val)
> +/** Tracepoint function payload for uint8_t datatype */
> +#define rte_trace_ctf_u8(val)
> +/** Tracepoint function payload for int8_t datatype */
> +#define rte_trace_ctf_i8(val)
> +/** Tracepoint function payload for int datatype */
> +#define rte_trace_ctf_int(val)
> +/** Tracepoint function payload for long datatype */
> +#define rte_trace_ctf_long(val)
> +/** Tracepoint function payload for float datatype */
> +#define rte_trace_ctf_float(val)
> +/** Tracepoint function payload for double datatype */
> +#define rte_trace_ctf_double(val)
> +/** Tracepoint function payload for pointer datatype */
> +#define rte_trace_ctf_ptr(val)
> +/** Tracepoint function payload for string datatype */
> +#define rte_trace_ctf_string(val)
> +
> +#endif /* __DOXYGEN__ */
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_TRACE_H_ */
> diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
> index 2b97715a2..30fb9b85f 100644
> --- a/lib/librte_eal/common/meson.build
> +++ b/lib/librte_eal/common/meson.build
> @@ -28,6 +28,7 @@ common_sources = files(
>   	'eal_common_tailqs.c',
>   	'eal_common_thread.c',
>   	'eal_common_timer.c',
> +	'eal_common_trace.c',
>   	'eal_common_uuid.c',
>   	'hotplug_mp.c',
>   	'malloc_elem.c',
> @@ -84,6 +85,7 @@ common_headers = files(
>   	'include/rte_service_component.h',
>   	'include/rte_string_fns.h',
>   	'include/rte_tailq.h',
> +	'include/rte_trace.h',
>   	'include/rte_time.h',
>   	'include/rte_uuid.h',
>   	'include/rte_version.h',
> diff --git a/lib/librte_eal/freebsd/eal/Makefile b/lib/librte_eal/freebsd/eal/Makefile
> index b160b5790..b2fcc4212 100644
> --- a/lib/librte_eal/freebsd/eal/Makefile
> +++ b/lib/librte_eal/freebsd/eal/Makefile
> @@ -60,6 +60,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_thread.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_proc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c
> +SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += malloc_elem.c
> diff --git a/lib/librte_eal/linux/eal/Makefile b/lib/librte_eal/linux/eal/Makefile
> index e70cf104a..95470d3bb 100644
> --- a/lib/librte_eal/linux/eal/Makefile
> +++ b/lib/librte_eal/linux/eal/Makefile
> @@ -68,6 +68,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_thread.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_proc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c
> +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += malloc_elem.c



^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 03/32] eal/trace: implement trace register API
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 03/32] eal/trace: implement trace register API jerinj
@ 2020-03-19 10:02   ` Mattias Rönnblom
  2020-03-23 13:37     ` Jerin Jacob
  0 siblings, 1 reply; 142+ messages in thread
From: Mattias Rönnblom @ 2020-03-19 10:02 UTC (permalink / raw)
  To: jerinj, Thomas Monjalon, Sunil Kumar Kori
  Cc: dev, bruce.richardson, david.marchand

On 2020-03-18 20:02, jerinj@marvell.com wrote:
> From: Jerin Jacob <jerinj@marvell.com>
>
> The consumers of trace API defines the tracepoint and registers
> to eal. Internally these tracepoints will be stored in STAILQ
> for future use. This patch implements the tracepoint
> registration function.
>
> Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> ---
>   MAINTAINERS                                   |   1 +
>   lib/librte_eal/common/Makefile                |   2 +-
>   lib/librte_eal/common/eal_common_trace.c      | 107 +++++++++++++++++-
>   lib/librte_eal/common/eal_trace.h             |  36 ++++++
>   lib/librte_eal/common/include/rte_trace.h     |  29 +++++
>   .../common/include/rte_trace_provider.h       |  24 ++++
>   .../common/include/rte_trace_register.h       |  20 ++++
>   lib/librte_eal/common/meson.build             |   2 +
>   lib/librte_eal/rte_eal_version.map            |   1 +
>   9 files changed, 220 insertions(+), 2 deletions(-)
>   create mode 100644 lib/librte_eal/common/eal_trace.h
>   create mode 100644 lib/librte_eal/common/include/rte_trace_provider.h
>   create mode 100644 lib/librte_eal/common/include/rte_trace_register.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 63d85c7da..452fd2c4f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -201,6 +201,7 @@ M: Jerin Jacob <jerinj@marvell.com>
>   M: Sunil Kumar Kori <skori@marvell.com>
>   F: lib/librte_eal/common/include/rte_trace*.h
>   F: lib/librte_eal/common/eal_common_trace*.c
> +F: lib/librte_eal/common/eal_trace.h
>   
>   Memory Allocation
>   M: Anatoly Burakov <anatoly.burakov@intel.com>
> diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
> index 9384d6f6e..8f2f25c1d 100644
> --- a/lib/librte_eal/common/Makefile
> +++ b/lib/librte_eal/common/Makefile
> @@ -9,7 +9,7 @@ INC += rte_debug.h rte_eal.h rte_eal_interrupts.h
>   INC += rte_errno.h rte_launch.h rte_lcore.h
>   INC += rte_log.h rte_memory.h rte_memzone.h
>   INC += rte_per_lcore.h rte_random.h
> -INC += rte_trace.h
> +INC += rte_trace.h rte_trace_provider.h rte_trace_register.h
>   INC += rte_tailq.h rte_interrupts.h rte_alarm.h
>   INC += rte_string_fns.h rte_version.h
>   INC += rte_eal_memconfig.h
> diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
> index e18ba1c95..ddde04de5 100644
> --- a/lib/librte_eal/common/eal_common_trace.c
> +++ b/lib/librte_eal/common/eal_common_trace.c
> @@ -2,5 +2,110 @@
>    * Copyright(C) 2020 Marvell International Ltd.
>    */
>   
> -#include <rte_trace.h>
> +#include <inttypes.h>
> +#include <sys/queue.h>
>   
> +#include <rte_common.h>
> +#include <rte_errno.h>
> +#include <rte_lcore.h>
> +#include <rte_per_lcore.h>
> +#include <rte_string_fns.h>
> +
> +#include "eal_trace.h"
> +
> +RTE_DEFINE_PER_LCORE(volatile int, trace_point_sz);
> +RTE_DEFINE_PER_LCORE(char, ctf_field[TRACE_CTF_FIELD_SIZE]);
> +RTE_DEFINE_PER_LCORE(int, ctf_count);
> +
> +static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
> +static struct trace trace;
> +
> +int
> +__rte_trace_point_register(rte_trace_t handle, const char *name, uint32_t level,
> +			 void (*fn)(void))
Maybe a more descriptive name than 'fn' would be in order.
> +{
> +	char *field = RTE_PER_LCORE(ctf_field);
> +	struct trace_point *tp;
> +	uint16_t sz;
> +
> +	/* Sanity checks of arguments */
> +	if (name == NULL || fn == NULL || handle == NULL) {
> +		trace_err("invalid arguments");
> +		rte_errno = EINVAL; goto fail;
> +	}
> +
> +	/* Sanity check of level */
> +	if (level > RTE_LOG_DEBUG || level > UINT8_MAX) {

Consider a #define for the max level. If the type was uint8_t, you 
wouldn't need to check max at all.

> +		trace_err("invalid log level=%d", level);
> +		rte_errno = EINVAL; goto fail;
> +
> +	}
> +
> +	/* Check the size of the trace point object */
> +	RTE_PER_LCORE(trace_point_sz) = 0;
> +	RTE_PER_LCORE(ctf_count) = 0;
> +	fn();
> +	if (RTE_PER_LCORE(trace_point_sz) == 0) {
> +		trace_err("missing rte_trace_emit_header() in register fn");
> +		rte_errno = EBADF; goto fail;
> +	}
> +
> +	/* Is size overflowed */
> +	if (RTE_PER_LCORE(trace_point_sz) > UINT16_MAX) {
> +		trace_err("trace point size overflowed");
> +		rte_errno = ENOSPC; goto fail;
> +	}
> +
> +	/* Are we running out of space to store trace points? */
> +	if (trace.nb_trace_points > UINT16_MAX) {
> +		trace_err("trace point exceeds the max count");
> +		rte_errno = ENOSPC; goto fail;
> +	}
> +
> +	/* Get the size of the trace point */
> +	sz = RTE_PER_LCORE(trace_point_sz);
> +	tp = calloc(1, sizeof(struct trace_point));
Not rte_zmalloc()? Are secondary processes accessing this memory?
> +	if (tp == NULL) {
> +		trace_err("fail to allocate trace point memory");
> +		rte_errno = ENOMEM; goto fail;
Missing newline.
> +	}
> +
> +	/* Initialize the trace point */
> +	if (rte_strscpy(tp->name, name, TRACE_POINT_NAME_SIZE) < 0) {
> +		trace_err("name is too long");
> +		rte_errno = E2BIG;
> +		goto free;
> +	}
> +
> +	/* Copy the field data for future use */
> +	if (rte_strscpy(tp->ctf_field, field, TRACE_CTF_FIELD_SIZE) < 0) {
> +		trace_err("CTF field size is too long");
> +		rte_errno = E2BIG;
> +		goto free;
> +	}
> +
> +	/* Clear field memory for the next event */
> +	memset(field, 0, TRACE_CTF_FIELD_SIZE);
> +
> +	/* Form the trace handle */
> +	*handle = sz;
> +	*handle |= trace.nb_trace_points << __RTE_TRACE_FIELD_ID_SHIFT;
> +	*handle |= (uint64_t)level << __RTE_TRACE_FIELD_LEVEL_SHIFT;
If *handle would be a struct, you could use a bitfield instead, and much 
simplify this code.
> +
> +	trace.nb_trace_points++;
> +	tp->handle = handle;
> +
> +	/* Add the trace point at tail */
> +	STAILQ_INSERT_TAIL(&tp_list, tp, next);
> +	__atomic_thread_fence(__ATOMIC_RELEASE);
> +
> +	/* All Good !!! */
> +	return 0;
> +free:
> +	free(tp);
> +fail:
> +	if (trace.register_errno == 0)
> +		trace.register_errno = rte_errno;
> +
> +	return -rte_errno;
> +}
> diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
> new file mode 100644
> index 000000000..9aef536a0
> --- /dev/null
> +++ b/lib/librte_eal/common/eal_trace.h
> @@ -0,0 +1,36 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2020 Marvell International Ltd.
> + */
> +
> +#ifndef __EAL_TRACE_H
> +#define __EAL_TRACE_H
> +
> +#include <rte_trace.h>
> +
> +#define trace_err(fmt, args...)\
> +	RTE_LOG(ERR, EAL, "%s():%u " fmt "\n",\
> +		__func__, __LINE__, ## args)
> +
> +#define trace_crit(fmt, args...)\
> +	RTE_LOG(CRIT, EAL, "%s():%u " fmt "\n",\
> +		__func__, __LINE__, ## args)
> +
> +#define TRACE_CTF_FIELD_SIZE 384
> +#define TRACE_POINT_NAME_SIZE 64
> +
> +struct trace_point {
> +	STAILQ_ENTRY(trace_point) next;
> +	rte_trace_t handle;
> +	char name[TRACE_POINT_NAME_SIZE];
> +	char ctf_field[TRACE_CTF_FIELD_SIZE];
> +};
> +
> +struct trace {
> +	int register_errno;
> +	uint32_t nb_trace_points;
> +};
> +
> +/* Trace point list functions */
> +STAILQ_HEAD(trace_point_head, trace_point);
> +
> +#endif /* __EAL_TRACE_H */
> diff --git a/lib/librte_eal/common/include/rte_trace.h b/lib/librte_eal/common/include/rte_trace.h
> index d008b64f1..da70dfdbb 100644
> --- a/lib/librte_eal/common/include/rte_trace.h
> +++ b/lib/librte_eal/common/include/rte_trace.h
> @@ -518,6 +518,35 @@ _tp _args \
>   
>   #endif /* __DOXYGEN__ */
>   
> +/**
> + * @internal @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Helper function to register a dynamic tracepoint.
> + * Use RTE_TRACE_POINT_REGISTER() macro for tracepoint registration.
> + *
> + * @param trace
> + *   The tracepoint object created using RTE_TRACE_POINT_DEFINE().
> + * @param name
> + *   The name of the tracepoint object.
> + * @param level
> + *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
> + * @param f
> + *   Trace registration function.
> + * @return
> + *   - 0: Successfully registered the tracepoint.
> + *   - <0: Failure to register the tracepoint.
> + */
> +__rte_experimental
> +int __rte_trace_point_register(rte_trace_t trace, const char *name,
> +			     uint32_t level, void (*fn)(void));
> +
> +#ifdef RTE_TRACE_POINT_REGISTER_SELECT
> +#include <rte_trace_register.h>
> +#else
> +#include <rte_trace_provider.h>
> +#endif
> +
>   #ifdef __cplusplus
>   }
>   #endif
> diff --git a/lib/librte_eal/common/include/rte_trace_provider.h b/lib/librte_eal/common/include/rte_trace_provider.h
> new file mode 100644
> index 000000000..b4da87ba1
> --- /dev/null
> +++ b/lib/librte_eal/common/include/rte_trace_provider.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2020 Marvell International Ltd.
> + */
> +
> +#ifndef _RTE_TRACE_H_
> +#error do not include this file directly, use <rte_trace.h> instead
> +#endif
> +
> +#ifndef _RTE_TRACE_PROVIDER_H_
> +#define _RTE_TRACE_PROVIDER_H_
> +
> +#define __RTE_TRACE_EVENT_HEADER_ID_SHIFT (48)
> +
> +#define __RTE_TRACE_FIELD_ENABLE_MASK (1ULL << 63)
> +#define __RTE_TRACE_FIELD_ENABLE_DISCARD (1ULL << 62)
> +#define __RTE_TRACE_FIELD_SIZE_SHIFT 0
> +#define __RTE_TRACE_FIELD_SIZE_MASK (0xffffULL << __RTE_TRACE_FIELD_SIZE_SHIFT)
> +#define __RTE_TRACE_FIELD_ID_SHIFT (16)
> +#define __RTE_TRACE_FIELD_ID_MASK (0xffffULL << __RTE_TRACE_FIELD_ID_SHIFT)
> +#define __RTE_TRACE_FIELD_LEVEL_SHIFT (32)
> +#define __RTE_TRACE_FIELD_LEVEL_MASK (0xffULL << __RTE_TRACE_FIELD_LEVEL_SHIFT)
> +
> +
> +#endif /* _RTE_TRACE_PROVIDER_H_ */
> diff --git a/lib/librte_eal/common/include/rte_trace_register.h b/lib/librte_eal/common/include/rte_trace_register.h
> new file mode 100644
> index 000000000..e9940b414
> --- /dev/null
> +++ b/lib/librte_eal/common/include/rte_trace_register.h
> @@ -0,0 +1,20 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2020 Marvell International Ltd.
> + */
> +
> +#ifndef _RTE_TRACE_H_
> +#error do not include this file directly, use <rte_trace.h> instead
> +#endif
> +
> +#ifndef _RTE_TRACE_REGISTER_H_
> +#define _RTE_TRACE_REGISTER_H_
> +
> +#include <rte_per_lcore.h>
> +
> +RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz);
> +
> +#define RTE_TRACE_POINT_REGISTER(trace, name, level)\
> +	__rte_trace_point_register(&__##trace, RTE_STR(name),\
> +			RTE_LOG_ ## level, (void (*)(void)) trace)
> +
> +#endif /* _RTE_TRACE_REGISTER_H_ */
> diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
> index 30fb9b85f..88c14ebe5 100644
> --- a/lib/librte_eal/common/meson.build
> +++ b/lib/librte_eal/common/meson.build
> @@ -86,6 +86,8 @@ common_headers = files(
>   	'include/rte_string_fns.h',
>   	'include/rte_tailq.h',
>   	'include/rte_trace.h',
> +	'include/rte_trace_provider.h',
> +	'include/rte_trace_register.h',
>   	'include/rte_time.h',
>   	'include/rte_uuid.h',
>   	'include/rte_version.h',
> diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
> index cadfa6465..d97d14845 100644
> --- a/lib/librte_eal/rte_eal_version.map
> +++ b/lib/librte_eal/rte_eal_version.map
> @@ -338,4 +338,5 @@ EXPERIMENTAL {
>   
>   	# added in 20.05
>   	rte_thread_getname;
> +	__rte_trace_point_register;
>   };



^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 04/32] eal/trace: implement trace operation APIs
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 04/32] eal/trace: implement trace operation APIs jerinj
@ 2020-03-19 10:16   ` Mattias Rönnblom
  2020-03-23 12:23     ` Jerin Jacob
  0 siblings, 1 reply; 142+ messages in thread
From: Mattias Rönnblom @ 2020-03-19 10:16 UTC (permalink / raw)
  To: jerinj, Sunil Kumar Kori; +Cc: dev, thomas, bruce.richardson, david.marchand

On 2020-03-18 20:02, jerinj@marvell.com wrote:
> From: Jerin Jacob <jerinj@marvell.com>
>
> This patch implements the following public trace APIs.
>
> - rte_trace_global_is_enabled()
> - rte_trace_global_is_disabled()
> - rte_trace_is_id_invalid()
> - rte_trace_global_level_set()
> - rte_trace_global_level_get()
> - rte_trace_global_mode_set()
> - rte_trace_global_mode_get()
> - rte_trace_enable()
> - rte_trace_disable()
> - rte_trace_is_enabled()
> - rte_trace_is_disabled()
> - rte_trace_level_set()
> - rte_trace_level_get()
> - rte_trace_mode_set()
> - rte_trace_mode_get()
> - rte_trace_pattern()
> - rte_trace_regexp()
> - rte_trace_from_name()
>
> Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> ---
>   lib/librte_eal/common/eal_common_trace.c | 249 +++++++++++++++++++++++
>   lib/librte_eal/common/eal_trace.h        |  11 +
>   lib/librte_eal/rte_eal_version.map       |  18 ++
>   3 files changed, 278 insertions(+)
>
> diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
> index ddde04de5..f8855e09b 100644
> --- a/lib/librte_eal/common/eal_common_trace.c
> +++ b/lib/librte_eal/common/eal_common_trace.c
> @@ -3,7 +3,9 @@
>    */
>   
>   #include <inttypes.h>
> +#include <fnmatch.h>
>   #include <sys/queue.h>
> +#include <regex.h>
>   
>   #include <rte_common.h>
>   #include <rte_errno.h>
> @@ -20,6 +22,253 @@ RTE_DEFINE_PER_LCORE(int, ctf_count);
>   static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
>   static struct trace trace;
>   
> +bool
> +rte_trace_global_is_enabled(void)
> +{
> +	return trace.global_status;
> +}
> +
> +bool
> +rte_trace_global_is_disabled(void)
> +{
> +	return !trace.global_status;
> +}
> +
> +void
> +rte_trace_global_level_set(uint32_t level)
> +{
> +	struct trace_point *tp;
> +
> +	trace.level = level;
> +
> +	if (rte_trace_global_is_disabled())
> +		return;
> +
> +	STAILQ_FOREACH(tp, &tp_list, next) {
> +		if (level >= rte_trace_level_get(tp->handle))
> +			rte_trace_enable(tp->handle);
> +		else
> +			rte_trace_disable(tp->handle);
> +	}
> +}
> +
> +uint32_t
> +rte_trace_global_level_get(void)
> +{
> +	return trace.level;
> +}
> +
> +void
> +rte_trace_global_mode_set(enum rte_trace_mode_e mode)
> +{
> +	struct trace_point *tp;
> +
> +	if (rte_trace_global_is_disabled())
> +		return;
> +
> +	STAILQ_FOREACH(tp, &tp_list, next)
> +		rte_trace_mode_set(tp->handle, mode);
> +
> +	trace.mode = mode;
> +}
> +
> +enum
> +rte_trace_mode_e rte_trace_global_mode_get(void)
> +{
> +	return trace.mode;
> +}
> +
> +bool
> +rte_trace_is_id_invalid(rte_trace_t t)
> +{
> +	if (trace_id_get(t) >= trace.nb_trace_points)
> +		return true;
> +
> +	return false;
> +}
> +
> +bool
> +rte_trace_is_enabled(rte_trace_t trace)
> +{
> +	uint64_t val;
> +
> +	if (rte_trace_is_id_invalid(trace))
> +		return false;
> +
> +	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
> +	return !!(val & __RTE_TRACE_FIELD_ENABLE_MASK);
The function has a bool return type, so no need to do a double negation.
> +}
> +
> +bool
> +rte_trace_is_disabled(rte_trace_t trace)
> +{
> +	uint64_t val;
> +
> +	if (rte_trace_is_id_invalid(trace))
> +		return true;
> +
> +	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
> +	return !!!(val & __RTE_TRACE_FIELD_ENABLE_MASK);
> +}
> +
Same here.
> +int
> +rte_trace_enable(rte_trace_t trace)
> +{
> +	if (rte_trace_is_id_invalid(trace))
> +		return -ERANGE;
> +
> +	if (rte_trace_level_get(trace) > rte_trace_global_level_get())
> +		return -EACCES;
> +
> +	__atomic_or_fetch(trace, __RTE_TRACE_FIELD_ENABLE_MASK,
> +			  __ATOMIC_RELEASE);
> +	return 0;
> +}
> +
> +int
> +rte_trace_disable(rte_trace_t trace)
> +{
> +	if (rte_trace_is_id_invalid(trace))
> +		return -ERANGE;
> +
> +	__atomic_and_fetch(trace, ~__RTE_TRACE_FIELD_ENABLE_MASK,
> +			   __ATOMIC_RELEASE);
> +	return 0;
> +}
> +
> +uint32_t
> +rte_trace_level_get(rte_trace_t trace)
> +{
> +	uint64_t val;
> +
> +	if (rte_trace_is_id_invalid(trace))
> +		return 0;
> +
> +	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
> +	val &= __RTE_TRACE_FIELD_LEVEL_MASK;
> +	val = val >> __RTE_TRACE_FIELD_LEVEL_SHIFT;
> +
> +	return val;
> +}
> +
> +int
> +rte_trace_level_set(rte_trace_t trace, uint32_t level)
> +{
> +	uint64_t val;
> +
> +	if (rte_trace_is_id_invalid(trace) || level > RTE_LOG_DEBUG)
> +		return -EINVAL;
> +
> +	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
> +	val &= ~__RTE_TRACE_FIELD_LEVEL_MASK;
> +	val |= (uint64_t)level << __RTE_TRACE_FIELD_LEVEL_SHIFT;
> +	__atomic_store_n(trace, val, __ATOMIC_RELEASE);
> +
> +	if (level <= rte_trace_global_level_get())
> +		rte_trace_enable(trace);
> +	else
> +		rte_trace_disable(trace);
> +
> +	return 0;
> +}
> +
> +int
> +rte_trace_mode_get(rte_trace_t trace)
> +{
> +	uint64_t val;
> +
> +	if (rte_trace_is_id_invalid(trace))
> +		return -EINVAL;
> +
> +	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
> +
> +	return !!(val & __RTE_TRACE_FIELD_ENABLE_DISCARD);
> +}
> +
> +int
> +rte_trace_mode_set(rte_trace_t trace, enum rte_trace_mode_e mode)
> +{
> +	if (rte_trace_is_id_invalid(trace) || mode >  RTE_TRACE_MODE_DISCARD)
> +		return -EINVAL;
> +
> +	if (mode == RTE_TRACE_MODE_OVERWRITE)
> +		__atomic_and_fetch(trace, ~__RTE_TRACE_FIELD_ENABLE_DISCARD,
> +				   __ATOMIC_RELEASE);
> +	else
> +		__atomic_or_fetch(trace, __RTE_TRACE_FIELD_ENABLE_DISCARD,
> +				   __ATOMIC_RELEASE);
> +
> +	return 0;
> +}
> +
> +int
> +rte_trace_pattern(const char *pattern, bool enable, bool *found)
> +{
> +	struct trace_point *tp;
> +	int rc;
> +
> +	if (found)
> +		*found = false;
> +
> +	STAILQ_FOREACH(tp, &tp_list, next) {
> +		if (fnmatch(pattern, tp->name, 0) == 0) {
> +			if (found)
> +				*found = true;
> +			if (enable)
> +				rc = rte_trace_enable(tp->handle);
> +			else
> +				rc = rte_trace_disable(tp->handle);
> +		}
> +		if (rc < 0)
> +			return rc;
> +	}
> +	return 0;
> +}
> +
> +int
> +rte_trace_regexp(const char *regex, bool enable, bool *found)
> +{
> +	struct trace_point *tp;
> +	regex_t r;
> +	int rc;
> +
> +	if (regcomp(&r, regex, 0) != 0)
> +		return -EINVAL;
> +
> +	if (found)
> +		*found = false;
> +
> +	STAILQ_FOREACH(tp, &tp_list, next) {
> +		if (regexec(&r, tp->name, 0, NULL, 0) == 0) {
> +			if (found)
> +				*found = true;
> +			if (enable)
> +				rc = rte_trace_enable(tp->handle);
> +			else
> +				rc = rte_trace_disable(tp->handle);
> +		}
> +		if (rc < 0)
> +			return rc;
In case of a non-match, rc may not be initialized.
> +	}
> +	regfree(&r);
> +	return 0;
> +}
> +
> +rte_trace_t
> +rte_trace_from_name(const char *name)
> +{
> +	struct trace_point *tp;
> +
> +	if (name == NULL)
> +		return NULL;
> +
> +	STAILQ_FOREACH(tp, &tp_list, next)
> +		if (strncmp(tp->name, name, TRACE_POINT_NAME_SIZE) == 0)
> +			return tp->handle;
> +
> +	return NULL;
> +}
> +
>   int
>   __rte_trace_point_register(rte_trace_t handle, const char *name, uint32_t level,
>   			 void (*fn)(void))
> diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
> index 9aef536a0..9f90a5d17 100644
> --- a/lib/librte_eal/common/eal_trace.h
> +++ b/lib/librte_eal/common/eal_trace.h
> @@ -27,9 +27,20 @@ struct trace_point {
>   
>   struct trace {
>   	int register_errno;
> +	bool global_status;
> +	enum rte_trace_mode_e mode;
> +	uint32_t level;
>   	uint32_t nb_trace_points;
>   };
>   
> +/* Helper functions */
> +static inline uint16_t
> +trace_id_get(rte_trace_t trace)
> +{
> +	return (*trace & __RTE_TRACE_FIELD_ID_MASK) >>
> +		__RTE_TRACE_FIELD_ID_SHIFT;
> +}
> +
>   /* Trace point list functions */
>   STAILQ_HEAD(trace_point_head, trace_point);
>   
> diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
> index d97d14845..841ebc5f9 100644
> --- a/lib/librte_eal/rte_eal_version.map
> +++ b/lib/librte_eal/rte_eal_version.map
> @@ -339,4 +339,22 @@ EXPERIMENTAL {
>   	# added in 20.05
>   	rte_thread_getname;
>   	__rte_trace_point_register;
> +	rte_trace_global_is_enabled;
> +	rte_trace_global_is_disabled;
> +	rte_trace_is_id_invalid;
> +	rte_trace_global_level_set;
> +	rte_trace_global_level_get;
> +	rte_trace_global_mode_set;
> +	rte_trace_global_mode_get;
> +	rte_trace_enable;
> +	rte_trace_disable;
> +	rte_trace_is_enabled;
> +	rte_trace_is_disabled;
> +	rte_trace_level_set;
> +	rte_trace_level_get;
> +	rte_trace_mode_set;
> +	rte_trace_mode_get;
> +	rte_trace_pattern;
> +	rte_trace_regexp;
> +	rte_trace_from_name;
>   };



^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 05/32] eal/trace: add internal trace init and fini interface
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 05/32] eal/trace: add internal trace init and fini interface jerinj
@ 2020-03-19 10:35   ` Mattias Rönnblom
  2020-03-23 12:09     ` Jerin Jacob
  0 siblings, 1 reply; 142+ messages in thread
From: Mattias Rönnblom @ 2020-03-19 10:35 UTC (permalink / raw)
  To: jerinj, Sunil Kumar Kori, Bruce Richardson; +Cc: dev, thomas, david.marchand

On 2020-03-18 20:02, jerinj@marvell.com wrote:
> From: Jerin Jacob <jerinj@marvell.com>
>
> Define eal_trace_init() and eal_trace_fini() EAL interface
> functions that rte_eal_init() and rte_eal_cleanup() function can be
> use to initialize and finalize the trace subsystem.
> eal_trace_init() function will add the following
> functionality if trace is enabled through EAL command line param.
>
> - Test for trace registration failure.
> - Test for duplicate trace name registration
> - Generate UUID ver 4.
> - Create a trace directory
>
> Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> ---
>   lib/librte_eal/common/eal_common_trace.c      |  54 ++++++
>   .../common/eal_common_trace_utils.c           | 173 ++++++++++++++++++
>   lib/librte_eal/common/eal_trace.h             |  21 +++
>   lib/librte_eal/common/meson.build             |   1 +
>   lib/librte_eal/freebsd/eal/Makefile           |   1 +
>   lib/librte_eal/linux/eal/Makefile             |   1 +
>   6 files changed, 251 insertions(+)
>   create mode 100644 lib/librte_eal/common/eal_common_trace_utils.c
>
> diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
> index f8855e09b..abb221cf3 100644
> --- a/lib/librte_eal/common/eal_common_trace.c
> +++ b/lib/librte_eal/common/eal_common_trace.c
> @@ -22,6 +22,60 @@ RTE_DEFINE_PER_LCORE(int, ctf_count);
>   static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
>   static struct trace trace;
>   
> +struct trace*
> +trace_obj_get(void)
> +{
> +	return &trace;
> +}
> +
> +struct trace_point_head *
> +trace_list_head_get(void)
> +{
> +	return &tp_list;
> +}
> +
> +int
> +eal_trace_init(void)
> +{
> +	/* One of the Trace registration failed */
> +	if (trace.register_errno) {
> +		rte_errno = trace.register_errno;
> +		goto fail;
> +	}
> +
> +	if (rte_trace_global_is_disabled())
> +		return 0;
> +
> +	rte_spinlock_init(&trace.lock);
> +
> +	/* Is duplicate trace name registered */
> +	if (trace_has_duplicate_entry())
> +		goto fail;
> +
> +	/* Generate UUID ver 4 with total size of events and number of events */
> +	trace_uuid_generate();
> +
> +	/* Create trace directory */
> +	if (trace_mkdir())
> +		goto fail;
> +
> +
> +	rte_trace_global_mode_set(trace.mode);
> +
> +	return 0;
> +
> +fail:
> +	trace_err("failed to initialize trace [%s]", rte_strerror(rte_errno));
> +	return -rte_errno;
> +}
> +
> +void
> +eal_trace_fini(void)
> +{
> +	if (rte_trace_global_is_disabled())
> +		return;
> +}
> +
>   bool
>   rte_trace_global_is_enabled(void)
>   {
> diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
> new file mode 100644
> index 000000000..f7d59774c
> --- /dev/null
> +++ b/lib/librte_eal/common/eal_common_trace_utils.c
> @@ -0,0 +1,173 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2020 Marvell International Ltd.
> + */
> +
> +#include <fnmatch.h>
> +#include <pwd.h>
> +#include <sys/stat.h>
> +#include <time.h>
> +
> +#include <rte_common.h>
> +#include <rte_errno.h>
> +#include <rte_string_fns.h>
> +
> +#include "eal_filesystem.h"
> +#include "eal_trace.h"
> +
> +static bool
> +trace_entry_compare(const char *name)
> +{
> +	struct trace_point_head *tp_list = trace_list_head_get();
> +	struct trace_point *tp;
> +	int count = 0;
> +
> +	STAILQ_FOREACH(tp, tp_list, next) {
> +		if (strncmp(tp->name, name, TRACE_POINT_NAME_SIZE) == 0)
> +			count++;
> +		if (count > 1) {
> +			trace_err("found duplicate entry %s", name);
> +			rte_errno = EEXIST;
> +			return 1;

Maybe an assertion would be better here, especially since the caller 
doesn't seem to care about the fact the list is inconsistent.

Change 1 -> true.

> +		}
> +	}
> +	return 0;
return false;
> +}
> +
> +bool
> +trace_has_duplicate_entry(void)
> +{
> +	struct trace_point_head *tp_list = trace_list_head_get();
> +	struct trace_point *tp;
> +
> +	/* Is duplicate trace name registered */
> +	STAILQ_FOREACH(tp, tp_list, next)
> +		if (trace_entry_compare(tp->name))
> +			return true;
> +
> +	return false;
> +}
> +
> +void
> +trace_uuid_generate(void)
> +{
> +	struct trace_point_head *tp_list = trace_list_head_get();
> +	struct trace *trace = trace_obj_get();
> +	struct trace_point *tp;
> +	uint64_t sz_total = 0;
> +
> +	/* Go over the registered trace points to get total size of events */
> +	STAILQ_FOREACH(tp, tp_list, next) {
> +		const uint16_t sz = *tp->handle & __RTE_TRACE_FIELD_SIZE_MASK;
> +		sz_total += sz;
> +	}
> +
> +	rte_uuid_t uuid = RTE_UUID_INIT(sz_total, trace->nb_trace_points,
> +		0x4370, 0x8f50, 0x222ddd514176ULL);
> +	rte_uuid_copy(trace->uuid, uuid);
> +}
> +
> +static int
> +trace_session_name_generate(char *trace_dir)
> +{
> +	struct tm *tm_result;
> +	time_t tm;
> +	int rc;
> +
> +	tm = time(NULL);
> +	if ((int)tm == -1)
> +		goto fail;
> +
> +	tm_result = localtime(&tm);
> +	if (tm_result == NULL)
> +		goto fail;
> +
> +	rc = rte_strscpy(trace_dir,
> +			 eal_get_hugefile_prefix(), TRACE_PREFIX_LEN);
> +	if (rc == -E2BIG)
> +		rc = TRACE_PREFIX_LEN;
> +	trace_dir[rc++] = '-';
> +
> +	rc = strftime(trace_dir + rc, TRACE_DIR_STR_LEN - rc,
> +			"%Y-%m-%d-%p-%I-%M-%S", tm_result);
> +	if (rc == 0)
> +		goto fail;
> +
> +	return rc;
> +fail:
> +	rte_errno = errno;
> +	return -rte_errno;
> +}
> +
> +static int
> +trace_dir_default_path_get(char *dir_path)
> +{
> +	struct trace *trace = trace_obj_get();
> +	uint32_t size = sizeof(trace->dir);
> +	struct passwd *pwd;
> +	char *home_dir;
> +
> +	/* First check for shell environment variable */
> +	home_dir = getenv("HOME");
In case of the application being started with 'sudo', $HOME will not be 
"/root", but rather the original user. This sounds like a bug to me.
> +	if (home_dir == NULL) {
> +		/* Fallback to password file entry */
> +		pwd = getpwuid(getuid());
> +		if (pwd == NULL)
> +			return -EINVAL;
> +
> +		home_dir = pwd->pw_dir;
> +	}
> +
> +	/* Append dpdk-traces to directory */
> +	if (snprintf(dir_path, size, "%s/dpdk-traces/", home_dir) < 0)
> +		return -ENAMETOOLONG;
> +
> +	return 0;
> +}
> +
> +int
> +trace_mkdir(void)
> +{
> +	struct trace *trace = trace_obj_get();
> +	char session[TRACE_DIR_STR_LEN];
> +	char *dir_path;
> +	int rc;
> +
> +	if (!trace->dir_offset) {
> +		dir_path = (char *)calloc(1, sizeof(trace->dir));
calloc() returns a void pointer, so no need to cast it.
> +		if (dir_path == NULL) {
> +			trace_err("fail to allocate memory\n");
> +			return -ENOMEM;
> +		}
> +
> +		rc = trace_dir_default_path_get(dir_path);
> +		if (rc < 0) {
> +			trace_err("fail to get default path\n");
> +			free(dir_path);
> +			return rc;
> +		}
> +
> +	}
> +
> +	/* Create the path if it t exist, no "mkdir -p" available here */
> +	rc = mkdir(trace->dir, 0700);
> +	if (rc < 0 && errno != EEXIST) {
> +		trace_err("mkdir %s failed [%s]", trace->dir, strerror(errno));
> +		rte_errno = errno;
> +		return -rte_errno;
> +	}
> +
> +	rc = trace_session_name_generate(session);
> +	if (rc < 0)
> +		return rc;
> +
> +	rc = mkdir(trace->dir, 0700);
> +	if (rc < 0) {
> +		trace_err("mkdir %s failed [%s]", trace->dir, strerror(errno));
> +		rte_errno = errno;
> +		return -rte_errno;
> +	}
> +
> +	RTE_LOG(INFO, EAL, "Trace dir: %s\n", trace->dir);
> +	return 0;

Is dir_path leaked? I can't find a free(), except in one of the error cases.

> +}
> +
> diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
> index 9f90a5d17..10c2f03ac 100644
> --- a/lib/librte_eal/common/eal_trace.h
> +++ b/lib/librte_eal/common/eal_trace.h
> @@ -5,7 +5,9 @@
>   #ifndef __EAL_TRACE_H
>   #define __EAL_TRACE_H
>   
> +#include <rte_spinlock.h>
>   #include <rte_trace.h>
> +#include <rte_uuid.h>
>   
>   #define trace_err(fmt, args...)\
>   	RTE_LOG(ERR, EAL, "%s():%u " fmt "\n",\
> @@ -15,6 +17,8 @@
>   	RTE_LOG(CRIT, EAL, "%s():%u " fmt "\n",\
>   		__func__, __LINE__, ## args)
>   
> +#define TRACE_PREFIX_LEN 12
> +#define TRACE_DIR_STR_LEN (sizeof("YYYY-mm-dd-AM-HH-MM-SS") + TRACE_PREFIX_LEN)
>   #define TRACE_CTF_FIELD_SIZE 384
>   #define TRACE_POINT_NAME_SIZE 64
>   
> @@ -26,11 +30,15 @@ struct trace_point {
>   };
>   
>   struct trace {
> +	char dir[PATH_MAX];
> +	int dir_offset;
>   	int register_errno;
>   	bool global_status;
>   	enum rte_trace_mode_e mode;
> +	rte_uuid_t uuid;
>   	uint32_t level;
>   	uint32_t nb_trace_points;
> +	rte_spinlock_t lock;
>   };
>   
>   /* Helper functions */
> @@ -41,7 +49,20 @@ trace_id_get(rte_trace_t trace)
>   		__RTE_TRACE_FIELD_ID_SHIFT;
>   }
>   
> +/* Trace object functions */
> +struct trace *trace_obj_get(void);
> +
>   /* Trace point list functions */
>   STAILQ_HEAD(trace_point_head, trace_point);
> +struct trace_point_head *trace_list_head_get(void);
> +
> +/* Util functions */
> +bool trace_has_duplicate_entry(void);
> +void trace_uuid_generate(void);
> +int trace_mkdir(void);
> +
> +/* EAL interface */
> +int eal_trace_init(void);
> +void eal_trace_fini(void);
>   
>   #endif /* __EAL_TRACE_H */
> diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
> index 88c14ebe5..716a255d2 100644
> --- a/lib/librte_eal/common/meson.build
> +++ b/lib/librte_eal/common/meson.build
> @@ -29,6 +29,7 @@ common_sources = files(
>   	'eal_common_thread.c',
>   	'eal_common_timer.c',
>   	'eal_common_trace.c',
> +	'eal_common_trace_utils.c',
>   	'eal_common_uuid.c',
>   	'hotplug_mp.c',
>   	'malloc_elem.c',
> diff --git a/lib/librte_eal/freebsd/eal/Makefile b/lib/librte_eal/freebsd/eal/Makefile
> index b2fcc4212..8c444da02 100644
> --- a/lib/librte_eal/freebsd/eal/Makefile
> +++ b/lib/librte_eal/freebsd/eal/Makefile
> @@ -61,6 +61,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_proc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace.c
> +SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_utils.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += malloc_elem.c
> diff --git a/lib/librte_eal/linux/eal/Makefile b/lib/librte_eal/linux/eal/Makefile
> index 95470d3bb..bd9993e58 100644
> --- a/lib/librte_eal/linux/eal/Makefile
> +++ b/lib/librte_eal/linux/eal/Makefile
> @@ -69,6 +69,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_proc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace.c
> +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_utils.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c
>   SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += malloc_elem.c



^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 06/32] eal/trace: get bootup timestamp for trace
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 06/32] eal/trace: get bootup timestamp for trace jerinj
@ 2020-03-19 10:43   ` Mattias Rönnblom
  2020-03-23 11:24     ` Jerin Jacob
  0 siblings, 1 reply; 142+ messages in thread
From: Mattias Rönnblom @ 2020-03-19 10:43 UTC (permalink / raw)
  To: jerinj, Sunil Kumar Kori; +Cc: dev, thomas, bruce.richardson, david.marchand

On 2020-03-18 20:02, jerinj@marvell.com wrote:
> From: Jerin Jacob <jerinj@marvell.com>
>
> Find epoch_sec, epoch_nsec and uptime_ticks time information
> on eal_trace_init()/bootup to derive the time in the trace.
>
> Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> ---
>   lib/librte_eal/common/eal_common_trace.c      |  3 +++
>   .../common/eal_common_trace_utils.c           | 22 +++++++++++++++++++
>   lib/librte_eal/common/eal_trace.h             |  5 +++++
>   3 files changed, 30 insertions(+)
>
> diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
> index abb221cf3..51c4dd550 100644
> --- a/lib/librte_eal/common/eal_common_trace.c
> +++ b/lib/librte_eal/common/eal_common_trace.c
> @@ -59,6 +59,9 @@ eal_trace_init(void)
>   	if (trace_mkdir())
>   		goto fail;
>   
> +	/* Save current epoch timestamp for future use */
> +	if (trace_epoch_time_save())
> +		goto fail;
< 0 looks cleaner.
>   
>   	rte_trace_global_mode_set(trace.mode);
>   
> diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
> index f7d59774c..340ab62e4 100644
> --- a/lib/librte_eal/common/eal_common_trace_utils.c
> +++ b/lib/librte_eal/common/eal_common_trace_utils.c
> @@ -98,6 +98,28 @@ trace_session_name_generate(char *trace_dir)
>   	return -rte_errno;
>   }
>   
> +int
> +trace_epoch_time_save(void)
> +{
> +	struct trace *trace = trace_obj_get();
> +	struct timespec epoch = { 0, 0 };
= {} also works.
> +	uint64_t avg, start, end;
> +
> +	start = rte_get_tsc_cycles();
> +	if (clock_gettime(CLOCK_REALTIME, &epoch) < 0) {
> +		trace_err("failed to get the epoch time");
> +		return -1;
> +	}
> +	end = rte_get_tsc_cycles();
> +	avg = (start + end) >> 1;
> +
> +	trace->epoch_sec = (uint64_t) epoch.tv_sec;
> +	trace->epoch_nsec = (uint64_t) epoch.tv_nsec;
If you would settle with keeping the time offset in microseconds, you 
would only need "epoch_offset_usec".
> +	trace->uptime_ticks = avg;
> +
> +	return 0;
> +}
> +
>   static int
>   trace_dir_default_path_get(char *dir_path)
>   {
> diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
> index 10c2f03ac..9807613d2 100644
> --- a/lib/librte_eal/common/eal_trace.h
> +++ b/lib/librte_eal/common/eal_trace.h
> @@ -5,6 +5,7 @@
>   #ifndef __EAL_TRACE_H
>   #define __EAL_TRACE_H
>   
> +#include <rte_cycles.h>
>   #include <rte_spinlock.h>
>   #include <rte_trace.h>
>   #include <rte_uuid.h>
> @@ -38,6 +39,9 @@ struct trace {
>   	rte_uuid_t uuid;
>   	uint32_t level;
>   	uint32_t nb_trace_points;
> +	uint64_t epoch_sec;
> +	uint64_t epoch_nsec;
> +	uint64_t uptime_ticks;
>   	rte_spinlock_t lock;
>   };
>   
> @@ -60,6 +64,7 @@ struct trace_point_head *trace_list_head_get(void);
>   bool trace_has_duplicate_entry(void);
>   void trace_uuid_generate(void);
>   int trace_mkdir(void);
> +int trace_epoch_time_save(void);
>   
>   /* EAL interface */
>   int eal_trace_init(void);



^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 11/32] eal/trace: implement trace save
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 11/32] eal/trace: implement trace save jerinj
@ 2020-03-19 19:07   ` Mattias Rönnblom
  2020-03-23  9:26     ` Jerin Jacob
  0 siblings, 1 reply; 142+ messages in thread
From: Mattias Rönnblom @ 2020-03-19 19:07 UTC (permalink / raw)
  To: jerinj, Sunil Kumar Kori; +Cc: dev, thomas, bruce.richardson, david.marchand

On 2020-03-18 20:02, jerinj@marvell.com wrote:
> From: Jerin Jacob <jerinj@marvell.com>
>
> Implement rte_trace_save(), which will save the metadata
> file and trace memory snapshot to the trace directory.
>
> Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> ---
>   .../common/eal_common_trace_utils.c           | 75 +++++++++++++++++++
>   lib/librte_eal/rte_eal_version.map            |  1 +
>   2 files changed, 76 insertions(+)
>
> diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
> index dbeb36668..230e4ac95 100644
> --- a/lib/librte_eal/common/eal_common_trace_utils.c
> +++ b/lib/librte_eal/common/eal_common_trace_utils.c
> @@ -213,3 +213,78 @@ trace_mkdir(void)
>   	return 0;
>   }
>   
> +static int
> +trace_meta_save(struct trace *trace)
> +{
> +	char file_name[PATH_MAX];
> +	FILE *f;
> +	int rc;
> +
> +	rc = snprintf(file_name, PATH_MAX, "%s/metadata", trace->dir);
> +	if (rc < 0)
> +		return rc;
> +
> +	f = fopen(file_name, "w");
> +	if (f == NULL)
> +		return -errno;
> +
> +	rc = rte_trace_metadata_dump(f);
> +
> +	fclose(f);
Check fclose() return code.
> +	return rc;
> +}
> +
> +
> +static inline int
> +trace_file_sz(struct __rte_trace_header *hdr)
> +{
> +	return sizeof(struct __rte_trace_stream_header) + hdr->offset;
> +}
> +
> +static int
> +trace_mem_save(struct trace *trace, struct __rte_trace_header *hdr,
> +	       uint32_t cnt)
> +{
> +	char file_name[PATH_MAX];
> +	FILE *f;
> +	int rc;
> +
> +	rc = snprintf(file_name, PATH_MAX, "%s/channel0_%d", trace->dir, cnt);
> +	if (rc < 0)
> +		return rc;
> +
> +	f = fopen(file_name, "w");
> +	if (f == NULL)
> +		return -errno;
> +
> +	rc = fwrite(&hdr->stream_header, trace_file_sz(hdr), 1, f);
> +	fclose(f);
Again, check return code.
> +
> +	return rc == 1 ?  0 : -EACCES;
> +}
> +
> +int
> +rte_trace_save(void)
> +{
> +	struct trace *trace = trace_obj_get();
> +	struct __rte_trace_header *header;
> +	uint32_t count;
> +	int rc = 0;
> +
> +	if (trace->nb_trace_mem_list == 0)
> +		return rc;
> +
> +	rc = trace_meta_save(trace);
> +	if (rc)
> +		return rc;
> +
> +	rte_spinlock_lock(&trace->lock);
> +	for (count = 0; count < trace->nb_trace_mem_list; count++) {
> +		header = trace->lcore_meta[count].mem;
> +		rc =  trace_mem_save(trace, header, count);
> +		if (rc)
> +			break;
> +	}
> +	rte_spinlock_unlock(&trace->lock);
> +	return rc;
> +}
> diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
> index cae358608..f56d1867e 100644
> --- a/lib/librte_eal/rte_eal_version.map
> +++ b/lib/librte_eal/rte_eal_version.map
> @@ -358,6 +358,7 @@ EXPERIMENTAL {
>   	rte_trace_mode_get;
>   	rte_trace_pattern;
>   	rte_trace_regexp;
> +	rte_trace_save;
>   	rte_trace_from_name;
>   	rte_trace_metadata_dump;
>   	rte_trace_dump;



^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 12/32] eal/trace: implement registration payload
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 12/32] eal/trace: implement registration payload jerinj
@ 2020-03-19 19:15   ` Mattias Rönnblom
  2020-03-23  9:24     ` Jerin Jacob
  0 siblings, 1 reply; 142+ messages in thread
From: Mattias Rönnblom @ 2020-03-19 19:15 UTC (permalink / raw)
  To: jerinj, Sunil Kumar Kori; +Cc: dev, thomas, bruce.richardson, david.marchand

On 2020-03-18 20:02, jerinj@marvell.com wrote:
> From: Jerin Jacob <jerinj@marvell.com>
>
> The trace function payloads such as rte_trace_ctf_* have
> dual functions. The first to emit the payload for the registration
> function and the second one to act as trace memory emitters.
>
> When it used as registration payload, it will do the following to
> fulfill the registration job.
> - Find out the size of the event
> - Generate metadata field string using __rte_trace_emit_ctf_field().
>
> Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> ---
>   lib/librte_eal/common/eal_common_trace.c      | 19 +++++++
>   lib/librte_eal/common/include/rte_trace.h     | 20 ++++++++
>   .../common/include/rte_trace_register.h       | 50 +++++++++++++++++++
>   lib/librte_eal/rte_eal_version.map            |  2 +
>   4 files changed, 91 insertions(+)
>
> diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
> index 6cb724080..94d3da0d3 100644
> --- a/lib/librte_eal/common/eal_common_trace.c
> +++ b/lib/librte_eal/common/eal_common_trace.c
> @@ -493,6 +493,25 @@ trace_mem_per_thread_free(void)
>   	rte_spinlock_unlock(&trace->lock);
>   }
>   
> +void
> +__rte_trace_emit_ctf_field(size_t sz, const char *in, const char *datatype)
> +{
> +	char *field = RTE_PER_LCORE(ctf_field);
> +	int count = RTE_PER_LCORE(ctf_count);
> +	int rc;
> +
> +	RTE_PER_LCORE(trace_point_sz) += sz;
> +	rc = snprintf(RTE_PTR_ADD(field, count),
> +		      RTE_MAX(0, TRACE_CTF_FIELD_SIZE - 1 - count),
> +		      "%s %s;", datatype, in);
> +	if (rc <= 0) {
> +		RTE_PER_LCORE(trace_point_sz) = 0;
> +		trace_crit("CTF field is too long");
> +		return;
> +	}
> +	RTE_PER_LCORE(ctf_count) += rc;
> +}
> +
>   int
>   __rte_trace_point_register(rte_trace_t handle, const char *name, uint32_t level,
>   			 void (*fn)(void))
> diff --git a/lib/librte_eal/common/include/rte_trace.h b/lib/librte_eal/common/include/rte_trace.h
> index 358b1b7ca..c24fe8d66 100644
> --- a/lib/librte_eal/common/include/rte_trace.h
> +++ b/lib/librte_eal/common/include/rte_trace.h
> @@ -520,6 +520,8 @@ _tp _args \
>   
>   /** @internal Macro to define maximum emit length of string datatype. */
>   #define __RTE_TRACE_EMIT_STRING_LEN_MAX 32
> +/** @internal Macro to define event header size. */
> +#define __RTE_TRACE_EVENT_HEADER_SZ sizeof(uint64_t)
>   
>   /**
>    * @internal @warning
> @@ -553,6 +555,24 @@ void __rte_trace_mem_per_thread_alloc(void);
>   __rte_experimental
>   int __rte_trace_point_register(rte_trace_t trace, const char *name,
>   			     uint32_t level, void (*fn)(void));
> +/**
> + * @internal @warning
> + * @b EXPERIMENTAL: this API may change without prior notice
> + *
> + * Helper function to emit ctf field.
> + *
> + * @param sz
> + *   The tracepoint size.
> + * @param field
> + *   The name of the trace event.
> + * @param type
> + *   The datatype of the trace event as string.
> + * @return
> + *   - 0: Success.
> + *   - <0: Failure.
> + */
> +__rte_experimental
> +void __rte_trace_emit_ctf_field(size_t sz, const char *field, const char *type);
>   
>   #ifdef RTE_TRACE_POINT_REGISTER_SELECT
>   #include <rte_trace_register.h>
> diff --git a/lib/librte_eal/common/include/rte_trace_register.h b/lib/librte_eal/common/include/rte_trace_register.h
> index e9940b414..93d6396df 100644
> --- a/lib/librte_eal/common/include/rte_trace_register.h
> +++ b/lib/librte_eal/common/include/rte_trace_register.h
> @@ -10,6 +10,7 @@
>   #define _RTE_TRACE_REGISTER_H_
>   
>   #include <rte_per_lcore.h>
> +#include <rte_log.h>
>   
>   RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz);
>   
> @@ -17,4 +18,53 @@ RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz);
>   	__rte_trace_point_register(&__##trace, RTE_STR(name),\
>   			RTE_LOG_ ## level, (void (*)(void)) trace)
>   
> +#define __rte_trace_emit_header_generic(t)\
> +	RTE_PER_LCORE(trace_point_sz) = __RTE_TRACE_EVENT_HEADER_SZ
> +
> +#define __rte_trace_emit_header_dp(t) __rte_trace_emit_header_generic(t)
> +
> +#define rte_trace_ctf_u64(in)\
> +	RTE_BUILD_BUG_ON(sizeof(uint64_t) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(uint64_t), RTE_STR(in), "uint64_t")

Delegate to a generic macro, to which you pass the type and the "in" 
parameter.

> +#define rte_trace_ctf_i64(in)\
> +	RTE_BUILD_BUG_ON(sizeof(int64_t) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(int64_t), RTE_STR(in), "int64_t")
> +#define rte_trace_ctf_u32(in)\
> +	RTE_BUILD_BUG_ON(sizeof(uint32_t) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(uint32_t), RTE_STR(in), "uint32_t")
> +#define rte_trace_ctf_i32(in)\
> +	RTE_BUILD_BUG_ON(sizeof(int32_t) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(int32_t), RTE_STR(in), "int32_t")
> +#define rte_trace_ctf_u16(in)\
> +	RTE_BUILD_BUG_ON(sizeof(uint16_t) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(uint16_t), RTE_STR(in), "uint16_t")
> +#define rte_trace_ctf_i16(in)\
> +	RTE_BUILD_BUG_ON(sizeof(int16_t) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(int16_t), RTE_STR(in), "int16_t")
> +#define rte_trace_ctf_u8(in)\
> +	RTE_BUILD_BUG_ON(sizeof(uint8_t) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(uint8_t), RTE_STR(in), "uint8_t")
> +#define rte_trace_ctf_i8(in)\
> +	RTE_BUILD_BUG_ON(sizeof(int8_t) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(int8_t), RTE_STR(in), "int8_t")
> +#define rte_trace_ctf_int(in)\
> +	RTE_BUILD_BUG_ON(sizeof(int) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(int), RTE_STR(in), "int32_t")
> +#define rte_trace_ctf_long(in)\
> +	RTE_BUILD_BUG_ON(sizeof(long) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(long), RTE_STR(in), "long")
> +#define rte_trace_ctf_float(in)\
> +	RTE_BUILD_BUG_ON(sizeof(float) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(float), RTE_STR(in), "float")
> +#define rte_trace_ctf_double(in)\
> +	RTE_BUILD_BUG_ON(sizeof(double) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(double), RTE_STR(in), "double")
> +#define rte_trace_ctf_ptr(in)\
> +	RTE_BUILD_BUG_ON(sizeof(void *) != sizeof(typeof(in)));\
> +	__rte_trace_emit_ctf_field(sizeof(void *), RTE_STR(in), "uintptr_t")
> +#define rte_trace_ctf_string(in)\
> +	RTE_SET_USED(in);\
> +	__rte_trace_emit_ctf_field(__RTE_TRACE_EMIT_STRING_LEN_MAX,\
> +				   RTE_STR(in)"[32]", "string_bounded_t")
> +
>   #endif /* _RTE_TRACE_REGISTER_H_ */
> diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
> index f56d1867e..0c787302f 100644
> --- a/lib/librte_eal/rte_eal_version.map
> +++ b/lib/librte_eal/rte_eal_version.map
> @@ -339,7 +339,9 @@ EXPERIMENTAL {
>   	# added in 20.05
>   	rte_thread_getname;
>   	__rte_trace_mem_per_thread_alloc;
> +	__rte_trace_emit_ctf_field;
>   	__rte_trace_point_register;
> +	per_lcore_trace_point_sz;
>   	per_lcore_trace_mem;
>   	rte_trace_global_is_enabled;
>   	rte_trace_global_is_disabled;



^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 13/32] eal/trace: implement provider payload
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 13/32] eal/trace: implement provider payload jerinj
@ 2020-03-19 19:27   ` Mattias Rönnblom
  2020-03-23  9:19     ` Jerin Jacob
  0 siblings, 1 reply; 142+ messages in thread
From: Mattias Rönnblom @ 2020-03-19 19:27 UTC (permalink / raw)
  To: jerinj, Sunil Kumar Kori; +Cc: dev, thomas, bruce.richardson, david.marchand

On 2020-03-18 20:02, jerinj@marvell.com wrote:
> From: Jerin Jacob <jerinj@marvell.com>
>
> The trace function payloads such as rte_trace_ctf_* have
> dual functions. The first to emit the payload for the registration
> function and the second one to act as trace mem emitters aka
> provider payload.
>
> When it used as provider payload, those function copy the trace
> field to trace memory based on the tracing mode.
>
> Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> ---
>   .../common/include/rte_trace_provider.h       | 87 +++++++++++++++++++
>   1 file changed, 87 insertions(+)
>
> diff --git a/lib/librte_eal/common/include/rte_trace_provider.h b/lib/librte_eal/common/include/rte_trace_provider.h
> index 2257de85b..66e9d2456 100644
> --- a/lib/librte_eal/common/include/rte_trace_provider.h
> +++ b/lib/librte_eal/common/include/rte_trace_provider.h
> @@ -9,6 +9,9 @@
>   #ifndef _RTE_TRACE_PROVIDER_H_
>   #define _RTE_TRACE_PROVIDER_H_
>   
> +#include <rte_branch_prediction.h>
> +#include <rte_cycles.h>
> +#include <rte_log.h>
>   #include <rte_per_lcore.h>
>   #include <rte_string_fns.h>
>   #include <rte_uuid.h>
> @@ -40,4 +43,88 @@ struct __rte_trace_header {
>   
>   RTE_DECLARE_PER_LCORE(void *, trace_mem);
>   
> +static __rte_always_inline void*
> +__rte_trace_mem_get(uint64_t in)
> +{
> +	struct __rte_trace_header *trace = RTE_PER_LCORE(trace_mem);
> +	const uint16_t sz = in & __RTE_TRACE_FIELD_SIZE_MASK;
> +
> +	/* Trace memory is not initialized for this thread */
> +	if (unlikely(trace == NULL)) {
> +		__rte_trace_mem_per_thread_alloc();
> +		trace = RTE_PER_LCORE(trace_mem);
> +		if (unlikely(trace == NULL))
> +			return NULL;
> +	}
> +	/* Check the wrap around case */
> +	uint32_t offset = trace->offset;
> +	if (unlikely((offset + sz) >= trace->len)) {
> +		/* Disable the trace event if it in DISCARD mode */
> +		if (unlikely(in & __RTE_TRACE_FIELD_ENABLE_DISCARD))
> +			return NULL;
> +
> +		offset = 0;
> +	}
> +	/* Align to event header size */
> +	offset = RTE_ALIGN_CEIL(offset, __RTE_TRACE_EVENT_HEADER_SZ);
> +	void *mem = RTE_PTR_ADD(&trace->mem[0], offset);
> +	offset += sz;
> +	trace->offset = offset;
> +
> +	return mem;
> +}
> +
> +static __rte_always_inline void*
> +__rte_trace_emit_ev_header(void *mem, uint64_t in)
> +{
> +	uint64_t val;
> +
> +	/* Event header [63:0] = id [63:48] | timestamp [47:0] */
> +	val = rte_get_tsc_cycles() &
> +		~(0xffffULL << __RTE_TRACE_EVENT_HEADER_ID_SHIFT);
> +	val |= ((in & __RTE_TRACE_FIELD_ID_MASK) <<
> +	      (__RTE_TRACE_EVENT_HEADER_ID_SHIFT - __RTE_TRACE_FIELD_ID_SHIFT));
> +
> +	*(uint64_t *)mem = val;
> +	return RTE_PTR_ADD(mem, __RTE_TRACE_EVENT_HEADER_SZ);
> +}
> +
> +#define __rte_trace_emit_header_generic(t)\
> +	const uint64_t val = __atomic_load_n(t, __ATOMIC_ACQUIRE);\
> +	if (likely(!(val & __RTE_TRACE_FIELD_ENABLE_MASK)))\
> +		return;\
> +	void *mem = __rte_trace_mem_get(val);\
> +	if (unlikely(mem == NULL)) \
> +		return;\
> +	mem = __rte_trace_emit_ev_header(mem, val)
> +
> +#define __rte_trace_emit_header_dp(t)\
> +	if (!rte_trace_is_dp_enabled())\
> +		return;\
> +	__rte_trace_emit_header_generic(t);
> +
> +#define __rte_trace_emit_datatype(in)\
> +	memcpy(mem, &(in), sizeof(in));\
> +	mem = RTE_PTR_ADD(mem, sizeof(in))
> +
> +#define rte_trace_ctf_u64(in) __rte_trace_emit_datatype(in)

Would it be worth to do a type check here? To avoid having someone do 
something like:

uint32_t v = 42;

rte_trace_ctf_u64(v);

which would spew out a 32-bit number, where there should be 64 bits.

Or maybe better: do an assignment, allowing type conversion (promotion 
at least), and type-checking, of sorts. The macro-generated code could 
look something like:

do {

     uint64_t _in = in;

     __rte_trace_emit_datatype(_in);

} while (0)

If you add a type parameter to __rte_trace_emit_datatype(), it can do 
the job.

> +#define rte_trace_ctf_i64(in) __rte_trace_emit_datatype(in)
> +#define rte_trace_ctf_u32(in) __rte_trace_emit_datatype(in)
> +#define rte_trace_ctf_i32(in) __rte_trace_emit_datatype(in)
> +#define rte_trace_ctf_u16(in) __rte_trace_emit_datatype(in)
> +#define rte_trace_ctf_i16(in) __rte_trace_emit_datatype(in)
> +#define rte_trace_ctf_u8(in) __rte_trace_emit_datatype(in)
> +#define rte_trace_ctf_i8(in) __rte_trace_emit_datatype(in)
> +#define rte_trace_ctf_int(in) __rte_trace_emit_datatype(in)
> +#define rte_trace_ctf_long(in) __rte_trace_emit_datatype(in)
> +#define rte_trace_ctf_float(in) __rte_trace_emit_datatype(in)
> +#define rte_trace_ctf_ptr(in) __rte_trace_emit_datatype(in)
> +#define rte_trace_ctf_double(in) __rte_trace_emit_datatype(in)
> +
> +#define rte_trace_ctf_string(in)\
Add the usual do { /../ } while (0) here?
> +	if (unlikely(in == NULL))\
> +		return;\
> +	rte_strscpy(mem, in, __RTE_TRACE_EMIT_STRING_LEN_MAX);\
> +	mem = RTE_PTR_ADD(mem, __RTE_TRACE_EMIT_STRING_LEN_MAX)
> +
>   #endif /* _RTE_TRACE_PROVIDER_H_ */



^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 13/32] eal/trace: implement provider payload
  2020-03-19 19:27   ` Mattias Rönnblom
@ 2020-03-23  9:19     ` Jerin Jacob
  0 siblings, 0 replies; 142+ messages in thread
From: Jerin Jacob @ 2020-03-23  9:19 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: jerinj, Sunil Kumar Kori, dev, thomas, bruce.richardson, david.marchand

On Fri, Mar 20, 2020 at 12:58 AM Mattias Rönnblom
<mattias.ronnblom@ericsson.com> wrote:

Thanks for the review.

>
> On 2020-03-18 20:02, jerinj@marvell.com wrote:
> > From: Jerin Jacob <jerinj@marvell.com>
> >
> > The trace function payloads such as rte_trace_ctf_* have
> > dual functions. The first to emit the payload for the registration
> > function and the second one to act as trace mem emitters aka
> > provider payload.

> > +
> > +#define rte_trace_ctf_u64(in) __rte_trace_emit_datatype(in)
>
> Would it be worth to do a type check here? To avoid having someone do
> something like:
>
> uint32_t v = 42;
>
> rte_trace_ctf_u64(v);
>
> which would spew out a 32-bit number, where there should be 64 bits.

It is taken care with the register version of this macro by adding
RTE_BUILD_BUG_ON.

http://patches.dpdk.org/patch/66861/

See:
#define rte_trace_ctf_i64(in)\
        RTE_BUILD_BUG_ON(sizeof(int64_t) != sizeof(typeof(in)));\
        __rte_trace_emit_ctf_field(sizeof(int64_t), RTE_STR(in), "int64_t")


>
> Or maybe better: do an assignment, allowing type conversion (promotion
> at least), and type-checking, of sorts. The macro-generated code could
> look something like:
>
> do {
>
>      uint64_t _in = in;
>
>      __rte_trace_emit_datatype(_in);
>
> } while (0)
>
> If you add a type parameter to __rte_trace_emit_datatype(), it can do
> the job.
>

> > +
> > +#define rte_trace_ctf_string(in)\
> Add the usual do { /../ } while (0) here?

Ack. Will add it in  the place where do { /../ } while (0) can be added in v2.

> > +     if (unlikely(in == NULL))\
> > +             return;\
> > +     rte_strscpy(mem, in, __RTE_TRACE_EMIT_STRING_LEN_MAX);\
> > +     mem = RTE_PTR_ADD(mem, __RTE_TRACE_EMIT_STRING_LEN_MAX)
> > +
> >   #endif /* _RTE_TRACE_PROVIDER_H_ */
>
>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 12/32] eal/trace: implement registration payload
  2020-03-19 19:15   ` Mattias Rönnblom
@ 2020-03-23  9:24     ` Jerin Jacob
  2020-03-23 10:18       ` Mattias Rönnblom
  0 siblings, 1 reply; 142+ messages in thread
From: Jerin Jacob @ 2020-03-23  9:24 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: jerinj, Sunil Kumar Kori, dev, thomas, bruce.richardson, david.marchand

On Fri, Mar 20, 2020 at 12:45 AM Mattias Rönnblom
<mattias.ronnblom@ericsson.com> wrote:
>
> On 2020-03-18 20:02, jerinj@marvell.com wrote:
> > From: Jerin Jacob <jerinj@marvell.com>
> >

> > +
> > +#define rte_trace_ctf_u64(in)\
> > +     RTE_BUILD_BUG_ON(sizeof(uint64_t) != sizeof(typeof(in)));\
> > +     __rte_trace_emit_ctf_field(sizeof(uint64_t), RTE_STR(in), "uint64_t")
>
> Delegate to a generic macro, to which you pass the type and the "in"
> parameter.

Not delegated to have a generic patch to catch the following error in
compile time.

uint32_t val = 12;

rte_trace_ctf_u64(val)

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 11/32] eal/trace: implement trace save
  2020-03-19 19:07   ` Mattias Rönnblom
@ 2020-03-23  9:26     ` Jerin Jacob
  0 siblings, 0 replies; 142+ messages in thread
From: Jerin Jacob @ 2020-03-23  9:26 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: jerinj, Sunil Kumar Kori, dev, thomas, bruce.richardson, david.marchand

On Fri, Mar 20, 2020 at 12:37 AM Mattias Rönnblom
<mattias.ronnblom@ericsson.com> wrote:
>
> On 2020-03-18 20:02, jerinj@marvell.com wrote:
> > From: Jerin Jacob <jerinj@marvell.com>

> > +static int
> > +trace_meta_save(struct trace *trace)
> > +{
> > +     char file_name[PATH_MAX];
> > +     FILE *f;
> > +     int rc;
> > +
> > +     rc = snprintf(file_name, PATH_MAX, "%s/metadata", trace->dir);
> > +     if (rc < 0)
> > +             return rc;
> > +
> > +     f = fopen(file_name, "w");
> > +     if (f == NULL)
> > +             return -errno;
> > +
> > +     rc = rte_trace_metadata_dump(f);
> > +
> > +     fclose(f);
> Check fclose() return code.

Ack. Will fix it v2.



> > +     return rc;
> > +}
> > +
> > +
> > +static inline int
> > +trace_file_sz(struct __rte_trace_header *hdr)
> > +{
> > +     return sizeof(struct __rte_trace_stream_header) + hdr->offset;
> > +}
> > +
> > +static int
> > +trace_mem_save(struct trace *trace, struct __rte_trace_header *hdr,
> > +            uint32_t cnt)
> > +{
> > +     char file_name[PATH_MAX];
> > +     FILE *f;
> > +     int rc;
> > +
> > +     rc = snprintf(file_name, PATH_MAX, "%s/channel0_%d", trace->dir, cnt);
> > +     if (rc < 0)
> > +             return rc;
> > +
> > +     f = fopen(file_name, "w");
> > +     if (f == NULL)
> > +             return -errno;
> > +
> > +     rc = fwrite(&hdr->stream_header, trace_file_sz(hdr), 1, f);
> > +     fclose(f);
> Again, check return code.

Ack. Will fix it v2.

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 12/32] eal/trace: implement registration payload
  2020-03-23  9:24     ` Jerin Jacob
@ 2020-03-23 10:18       ` Mattias Rönnblom
  2020-03-23 10:50         ` Jerin Jacob
  0 siblings, 1 reply; 142+ messages in thread
From: Mattias Rönnblom @ 2020-03-23 10:18 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: jerinj, Sunil Kumar Kori, dev, thomas, bruce.richardson, david.marchand

On 2020-03-23 10:24, Jerin Jacob wrote:
> On Fri, Mar 20, 2020 at 12:45 AM Mattias Rönnblom
> <mattias.ronnblom@ericsson.com> wrote:
>> On 2020-03-18 20:02, jerinj@marvell.com wrote:
>>> From: Jerin Jacob <jerinj@marvell.com>
>>>
>>> +
>>> +#define rte_trace_ctf_u64(in)\
>>> +     RTE_BUILD_BUG_ON(sizeof(uint64_t) != sizeof(typeof(in)));\
>>> +     __rte_trace_emit_ctf_field(sizeof(uint64_t), RTE_STR(in), "uint64_t")
>> Delegate to a generic macro, to which you pass the type and the "in"
>> parameter.
> Not delegated to have a generic patch to catch the following error in
> compile time.
>
> uint32_t val = 12;
>
> rte_trace_ctf_u64(val)

If you pass the type as I suggested, is there something preventing 
generating exactly the same code as the non-delegating macros?


#define __rte_trace_cft(in, in_type) \

     RTE_BUILD_BUG_ON(sizeof(in_type), != sizeof(typeof(in)));

     __rte_trace_emit_cft_field(sizeof(in_type), RTE_STR(in), 
RTE_STR(in_type))

#define rte_trace_cft_u64(in) \

     __rte_trace_ctf(in, uint64_t)



^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 12/32] eal/trace: implement registration payload
  2020-03-23 10:18       ` Mattias Rönnblom
@ 2020-03-23 10:50         ` Jerin Jacob
  0 siblings, 0 replies; 142+ messages in thread
From: Jerin Jacob @ 2020-03-23 10:50 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: jerinj, Sunil Kumar Kori, dev, thomas, bruce.richardson, david.marchand

On Mon, Mar 23, 2020 at 3:48 PM Mattias Rönnblom
<mattias.ronnblom@ericsson.com> wrote:
>
> On 2020-03-23 10:24, Jerin Jacob wrote:
> > On Fri, Mar 20, 2020 at 12:45 AM Mattias Rönnblom
> > <mattias.ronnblom@ericsson.com> wrote:
> >> On 2020-03-18 20:02, jerinj@marvell.com wrote:
> >>> From: Jerin Jacob <jerinj@marvell.com>
> >>>
> >>> +
> >>> +#define rte_trace_ctf_u64(in)\
> >>> +     RTE_BUILD_BUG_ON(sizeof(uint64_t) != sizeof(typeof(in)));\
> >>> +     __rte_trace_emit_ctf_field(sizeof(uint64_t), RTE_STR(in), "uint64_t")
> >> Delegate to a generic macro, to which you pass the type and the "in"
> >> parameter.
> > Not delegated to have a generic patch to catch the following error in
> > compile time.
> >
> > uint32_t val = 12;
> >
> > rte_trace_ctf_u64(val)
>
> If you pass the type as I suggested, is there something preventing
> generating exactly the same code as the non-delegating macros?
>
>
> #define __rte_trace_cft(in, in_type) \
>
>      RTE_BUILD_BUG_ON(sizeof(in_type), != sizeof(typeof(in)));
>
>      __rte_trace_emit_cft_field(sizeof(in_type), RTE_STR(in),
> RTE_STR(in_type))
>
> #define rte_trace_cft_u64(in) \
>
>      __rte_trace_ctf(in, uint64_t)

This will work. I will change to this scheme in v2.



>
>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 10/32] eal/trace: implement debug dump function
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 10/32] eal/trace: implement debug dump function jerinj
@ 2020-03-23 10:56   ` Morten Brørup
  2020-03-23 11:08     ` Jerin Jacob
  0 siblings, 1 reply; 142+ messages in thread
From: Morten Brørup @ 2020-03-23 10:56 UTC (permalink / raw)
  To: jerinj, Sunil Kumar Kori
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of jerinj@marvell.com
> Sent: Wednesday, March 18, 2020 8:02 PM
> 
> From: Jerin Jacob <jerinj@marvell.com>
> 
> Implement rte_trace_metadata_dump() and rte_trace_dump()
> functions. Former one used to dump the CTF metadata file and
> the latter one to dump all the registered events and its status.
> 
> Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> ---
>  lib/librte_eal/common/eal_common_log.c       |  9 +--
>  lib/librte_eal/common/eal_common_trace.c     | 63 ++++++++++++++++++
>  lib/librte_eal/common/eal_common_trace_ctf.c | 67 ++++++++++++++++++++
>  lib/librte_eal/common/eal_private.h          |  3 +
>  lib/librte_eal/rte_eal_version.map           |  2 +
>  5 files changed, 140 insertions(+), 4 deletions(-)
> 
> diff --git a/lib/librte_eal/common/eal_common_log.c
> b/lib/librte_eal/common/eal_common_log.c
> index c0efd5214..d8f7feb32 100644
> --- a/lib/librte_eal/common/eal_common_log.c
> +++ b/lib/librte_eal/common/eal_common_log.c
> @@ -372,8 +372,8 @@ RTE_INIT_PRIO(rte_log_init, LOG)
>  	rte_logs.dynamic_types_len = RTE_LOGTYPE_FIRST_EXT_ID;
>  }
> 
> -static const char *
> -loglevel_to_string(uint32_t level)
> +const char *
> +eal_loglevel_to_string(uint32_t level)

Making this function public, rte_ is probably a better prefix than eal_.

There are some functions missing rte_ prefix in eal_private.h, but there's no need to add more.

-Morten

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 10/32] eal/trace: implement debug dump function
  2020-03-23 10:56   ` Morten Brørup
@ 2020-03-23 11:08     ` Jerin Jacob
  0 siblings, 0 replies; 142+ messages in thread
From: Jerin Jacob @ 2020-03-23 11:08 UTC (permalink / raw)
  To: Morten Brørup
  Cc: Jerin Jacob, Sunil Kumar Kori, dpdk-dev, Thomas Monjalon,
	Richardson, Bruce, David Marchand, Mattias Rönnblom

On Mon, Mar 23, 2020 at 4:26 PM Morten Brørup <mb@smartsharesystems.com> wrote:
>
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of jerinj@marvell.com
> > Sent: Wednesday, March 18, 2020 8:02 PM
> >
> > From: Jerin Jacob <jerinj@marvell.com>
> >
> > Implement rte_trace_metadata_dump() and rte_trace_dump()
> > functions. Former one used to dump the CTF metadata file and
> > the latter one to dump all the registered events and its status.
> >
> > Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> > Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> > ---
> >  lib/librte_eal/common/eal_common_log.c       |  9 +--
> >  lib/librte_eal/common/eal_common_trace.c     | 63 ++++++++++++++++++
> >  lib/librte_eal/common/eal_common_trace_ctf.c | 67 ++++++++++++++++++++
> >  lib/librte_eal/common/eal_private.h          |  3 +
> >  lib/librte_eal/rte_eal_version.map           |  2 +
> >  5 files changed, 140 insertions(+), 4 deletions(-)
> >
> > diff --git a/lib/librte_eal/common/eal_common_log.c
> > b/lib/librte_eal/common/eal_common_log.c
> > index c0efd5214..d8f7feb32 100644
> > --- a/lib/librte_eal/common/eal_common_log.c
> > +++ b/lib/librte_eal/common/eal_common_log.c
> > @@ -372,8 +372,8 @@ RTE_INIT_PRIO(rte_log_init, LOG)
> >       rte_logs.dynamic_types_len = RTE_LOGTYPE_FIRST_EXT_ID;
> >  }
> >
> > -static const char *
> > -loglevel_to_string(uint32_t level)
> > +const char *
> > +eal_loglevel_to_string(uint32_t level)
>
> Making this function public, rte_ is probably a better prefix than eal_.

Not making it as public function(i.e not updated in .map file). It is
an EAL private function, whose scope is limited only to the EAL
library.

>
> There are some functions missing rte_ prefix in eal_private.h, but there's no need to add more.
>
> -Morten

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 06/32] eal/trace: get bootup timestamp for trace
  2020-03-19 10:43   ` Mattias Rönnblom
@ 2020-03-23 11:24     ` Jerin Jacob
  0 siblings, 0 replies; 142+ messages in thread
From: Jerin Jacob @ 2020-03-23 11:24 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: jerinj, Sunil Kumar Kori, dev, thomas, bruce.richardson, david.marchand

On Thu, Mar 19, 2020 at 4:13 PM Mattias Rönnblom
<mattias.ronnblom@ericsson.com> wrote:
>
> On 2020-03-18 20:02, jerinj@marvell.com wrote:
> > From: Jerin Jacob <jerinj@marvell.com>
> >
> > Find epoch_sec, epoch_nsec and uptime_ticks time information
> > on eal_trace_init()/bootup to derive the time in the trace.
> >
> > Signed-off-by: Jerin Jacob <jerinj@marvell.com>
> > ---
> >   lib/librte_eal/common/eal_common_trace.c      |  3 +++
> >   .../common/eal_common_trace_utils.c           | 22 +++++++++++++++++++
> >   lib/librte_eal/common/eal_trace.h             |  5 +++++
> >   3 files changed, 30 insertions(+)
> >
> > diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
> > index abb221cf3..51c4dd550 100644
> > --- a/lib/librte_eal/common/eal_common_trace.c
> > +++ b/lib/librte_eal/common/eal_common_trace.c
> > @@ -59,6 +59,9 @@ eal_trace_init(void)
> >       if (trace_mkdir())
> >               goto fail;
> >
> > +     /* Save current epoch timestamp for future use */
> > +     if (trace_epoch_time_save())
> > +             goto fail;
> < 0 looks cleaner.

OK. I will change it in v2.

> >
> >       rte_trace_global_mode_set(trace.mode);
> >
> > diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
> > index f7d59774c..340ab62e4 100644
> > --- a/lib/librte_eal/common/eal_common_trace_utils.c
> > +++ b/lib/librte_eal/common/eal_common_trace_utils.c
> > @@ -98,6 +98,28 @@ trace_session_name_generate(char *trace_dir)
> >       return -rte_errno;
> >   }
> >
> > +int
> > +trace_epoch_time_save(void)
> > +{
> > +     struct trace *trace = trace_obj_get();
> > +     struct timespec epoch = { 0, 0 };
> = {} also works.
> > +     uint64_t avg, start, end;
> > +
> > +     start = rte_get_tsc_cycles();
> > +     if (clock_gettime(CLOCK_REALTIME, &epoch) < 0) {
> > +             trace_err("failed to get the epoch time");
> > +             return -1;
> > +     }
> > +     end = rte_get_tsc_cycles();
> > +     avg = (start + end) >> 1;
> > +
> > +     trace->epoch_sec = (uint64_t) epoch.tv_sec;
> > +     trace->epoch_nsec = (uint64_t) epoch.tv_nsec;
> If you would settle with keeping the time offset in microseconds, you
> would only need "epoch_offset_usec".

ctf spec[1] uses offset_s and offset in clock definition. Storing both
to avoid conversion in the future.

[1]
https://diamon.org/ctf/#spec8

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 05/32] eal/trace: add internal trace init and fini interface
  2020-03-19 10:35   ` Mattias Rönnblom
@ 2020-03-23 12:09     ` Jerin Jacob
  0 siblings, 0 replies; 142+ messages in thread
From: Jerin Jacob @ 2020-03-23 12:09 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: jerinj, Sunil Kumar Kori, Bruce Richardson, dev, thomas, david.marchand

On Thu, Mar 19, 2020 at 4:05 PM Mattias Rönnblom
<mattias.ronnblom@ericsson.com> wrote:
>
> On 2020-03-18 20:02, jerinj@marvell.com wrote:
> > From: Jerin Jacob <jerinj@marvell.com>

> > +static bool
> > +trace_entry_compare(const char *name)
> > +{
> > +     struct trace_point_head *tp_list = trace_list_head_get();
> > +     struct trace_point *tp;
> > +     int count = 0;
> > +
> > +     STAILQ_FOREACH(tp, tp_list, next) {
> > +             if (strncmp(tp->name, name, TRACE_POINT_NAME_SIZE) == 0)
> > +                     count++;
> > +             if (count > 1) {
> > +                     trace_err("found duplicate entry %s", name);
> > +                     rte_errno = EEXIST;
> > +                     return 1;
>
> Maybe an assertion would be better here, especially since the caller
> doesn't seem to care about the fact the list is inconsistent.

assertion/panic are getting removed from the libraries.
This error propagates up to rte_eal_init() failure. So, the current
scheme is OK.

>
> Change 1 -> true.

Will fix it in v2.

>
> > +             }
> > +     }
> > +     return 0;
> return false;


Will fix it in v2.

> > +}
> > +

> > +static int
> > +trace_dir_default_path_get(char *dir_path)
> > +{
> > +     struct trace *trace = trace_obj_get();
> > +     uint32_t size = sizeof(trace->dir);
> > +     struct passwd *pwd;
> > +     char *home_dir;
> > +
> > +     /* First check for shell environment variable */
> > +     home_dir = getenv("HOME");
> In case of the application being started with 'sudo', $HOME will not be
> "/root", but rather the original user. This sounds like a bug to me.

When the application started with sudo, the trace will be written
by the "root" user. Probably it is not good to have some file whose
ownership as root in /home/user/dpdk-trace/ where the user can
not delete it.

A similar scheme followed in LTTng for trace directory.
I am open to a better scheme if any.


> > +     if (home_dir == NULL) {
> > +             /* Fallback to password file entry */
> > +             pwd = getpwuid(getuid());
> > +             if (pwd == NULL)
> > +                     return -EINVAL;
> > +
> > +             home_dir = pwd->pw_dir;
> > +     }
> > +
> > +     /* Append dpdk-traces to directory */
> > +     if (snprintf(dir_path, size, "%s/dpdk-traces/", home_dir) < 0)
> > +             return -ENAMETOOLONG;
> > +
> > +     return 0;
> > +}
> > +
> > +int
> > +trace_mkdir(void)
> > +{
> > +     struct trace *trace = trace_obj_get();
> > +     char session[TRACE_DIR_STR_LEN];
> > +     char *dir_path;
> > +     int rc;
> > +
> > +     if (!trace->dir_offset) {
> > +             dir_path = (char *)calloc(1, sizeof(trace->dir));
> calloc() returns a void pointer, so no need to cast it.

Will fix it in v2.

> > +             if (dir_path == NULL) {
> > +                     trace_err("fail to allocate memory\n");
> > +                     return -ENOMEM;
> > +             }
> > +
> > +             rc = trace_dir_default_path_get(dir_path);
> > +             if (rc < 0) {
> > +                     trace_err("fail to get default path\n");
> > +                     free(dir_path);
> > +                     return rc;
> > +             }
> > +
> > +     }
> > +
> > +     /* Create the path if it t exist, no "mkdir -p" available here */
> > +     rc = mkdir(trace->dir, 0700);
> > +     if (rc < 0 && errno != EEXIST) {
> > +             trace_err("mkdir %s failed [%s]", trace->dir, strerror(errno));
> > +             rte_errno = errno;
> > +             return -rte_errno;
> > +     }
> > +
> > +     rc = trace_session_name_generate(session);
> > +     if (rc < 0)
> > +             return rc;
> > +
> > +     rc = mkdir(trace->dir, 0700);
> > +     if (rc < 0) {
> > +             trace_err("mkdir %s failed [%s]", trace->dir, strerror(errno));
> > +             rte_errno = errno;
> > +             return -rte_errno;
> > +     }
> > +
> > +     RTE_LOG(INFO, EAL, "Trace dir: %s\n", trace->dir);
> > +     return 0;
>
> Is dir_path leaked? I can't find a free(), except in one of the error cases.

Not is in "struct trace" as memory.

struct trace {
        char dir[PATH_MAX];
..
}

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 04/32] eal/trace: implement trace operation APIs
  2020-03-19 10:16   ` Mattias Rönnblom
@ 2020-03-23 12:23     ` Jerin Jacob
  0 siblings, 0 replies; 142+ messages in thread
From: Jerin Jacob @ 2020-03-23 12:23 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: jerinj, Sunil Kumar Kori, dev, thomas, bruce.richardson, david.marchand

On Thu, Mar 19, 2020 at 3:46 PM Mattias Rönnblom
<mattias.ronnblom@ericsson.com> wrote:
>
> On 2020-03-18 20:02, jerinj@marvell.com wrote:
> > From: Jerin Jacob <jerinj@marvell.com>
> >
> > This patch implements the following public trace APIs.

All the comments in this patch will be fixed in v2.

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 03/32] eal/trace: implement trace register API
  2020-03-19 10:02   ` Mattias Rönnblom
@ 2020-03-23 13:37     ` Jerin Jacob
  2020-03-23 14:43       ` Mattias Rönnblom
  0 siblings, 1 reply; 142+ messages in thread
From: Jerin Jacob @ 2020-03-23 13:37 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: jerinj, Thomas Monjalon, Sunil Kumar Kori, dev, bruce.richardson,
	david.marchand

On Thu, Mar 19, 2020 at 3:33 PM Mattias Rönnblom
<mattias.ronnblom@ericsson.com> wrote:
>
> On 2020-03-18 20:02, jerinj@marvell.com wrote:
> > From: Jerin Jacob <jerinj@marvell.com>
> >

> > +int
> > +__rte_trace_point_register(rte_trace_t handle, const char *name, uint32_t level,
> > +                      void (*fn)(void))
> Maybe a more descriptive name than 'fn' would be in order.

OK. I will change to "register_fn" in v2.


> > +{
> > +     char *field = RTE_PER_LCORE(ctf_field);
> > +     struct trace_point *tp;
> > +     uint16_t sz;
> > +
> > +     /* Sanity checks of arguments */
> > +     if (name == NULL || fn == NULL || handle == NULL) {
> > +             trace_err("invalid arguments");
> > +             rte_errno = EINVAL; goto fail;
> > +     }
> > +
> > +     /* Sanity check of level */
> > +     if (level > RTE_LOG_DEBUG || level > UINT8_MAX) {
>
> Consider a #define for the max level. If the type was uint8_t, you
> wouldn't need to check max at all.

The reason for keeping level as uint32_t to keep compatibility
with rte_log level datatype. For some reason, rte_log defined level
as uint32_t, So I thought of sticking to that so that we can migrate the
rte_log to rte_trace in future if needed and also making semantics
similar to rte_log.

>
> > +             trace_err("invalid log level=%d", level);
> > +             rte_errno = EINVAL; goto fail;
> > +
> > +     }
> > +
> > +     /* Check the size of the trace point object */
> > +     RTE_PER_LCORE(trace_point_sz) = 0;
> > +     RTE_PER_LCORE(ctf_count) = 0;
> > +     fn();
> > +     if (RTE_PER_LCORE(trace_point_sz) == 0) {
> > +             trace_err("missing rte_trace_emit_header() in register fn");
> > +             rte_errno = EBADF; goto fail;
> > +     }
> > +
> > +     /* Is size overflowed */
> > +     if (RTE_PER_LCORE(trace_point_sz) > UINT16_MAX) {
> > +             trace_err("trace point size overflowed");
> > +             rte_errno = ENOSPC; goto fail;
> > +     }
> > +
> > +     /* Are we running out of space to store trace points? */
> > +     if (trace.nb_trace_points > UINT16_MAX) {
> > +             trace_err("trace point exceeds the max count");
> > +             rte_errno = ENOSPC; goto fail;
> > +     }
> > +
> > +     /* Get the size of the trace point */
> > +     sz = RTE_PER_LCORE(trace_point_sz);
> > +     tp = calloc(1, sizeof(struct trace_point));
> Not rte_zmalloc()? Are secondary processes accessing this memory?

This been called by the constructor at that time memory
services are not enabled and it is for the per-process like rte_log
scheme.


> > +     if (tp == NULL) {
> > +             trace_err("fail to allocate trace point memory");
> > +             rte_errno = ENOMEM; goto fail;
> Missing newline.

I will fix it in v2.

> > +     }
> > +
> > +     /* Initialize the trace point */
> > +     if (rte_strscpy(tp->name, name, TRACE_POINT_NAME_SIZE) < 0) {
> > +             trace_err("name is too long");
> > +             rte_errno = E2BIG;
> > +             goto free;
> > +     }
> > +
> > +     /* Copy the field data for future use */
> > +     if (rte_strscpy(tp->ctf_field, field, TRACE_CTF_FIELD_SIZE) < 0) {
> > +             trace_err("CTF field size is too long");
> > +             rte_errno = E2BIG;
> > +             goto free;
> > +     }
> > +
> > +     /* Clear field memory for the next event */
> > +     memset(field, 0, TRACE_CTF_FIELD_SIZE);
> > +
> > +     /* Form the trace handle */
> > +     *handle = sz;
> > +     *handle |= trace.nb_trace_points << __RTE_TRACE_FIELD_ID_SHIFT;
> > +     *handle |= (uint64_t)level << __RTE_TRACE_FIELD_LEVEL_SHIFT;
> If *handle would be a struct, you could use a bitfield instead, and much
> simplify this code.

I thought that initially, Two reasons why I did not do that
1) The flags have been used in fastpath, I prefer to work with flags
in fastpath so that
there is no performance impact using bitfields from the compiler _if any_.
2) In some of the places, I can simply operate on APIs like
__atomic_and_fetch() with flags.

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 02/32] eal: define the public API for trace support
  2020-03-18 20:58   ` Mattias Rönnblom
@ 2020-03-23 14:29     ` Jerin Jacob
  2020-03-23 14:46       ` Mattias Rönnblom
  0 siblings, 1 reply; 142+ messages in thread
From: Jerin Jacob @ 2020-03-23 14:29 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: jerinj, Thomas Monjalon, Bruce Richardson, John McNamara,
	Marko Kovacevic, Sunil Kumar Kori, dev, david.marchand

On Thu, Mar 19, 2020 at 2:28 AM Mattias Rönnblom
<mattias.ronnblom@ericsson.com> wrote:
>
> On 2020-03-18 20:02, jerinj@marvell.com wrote:
> > From: Jerin Jacob <jerinj@marvell.com>

> > +
> > +#include <rte_common.h>
> > +#include <rte_compat.h>
> > +
> > +/** The trace object. The trace APIs are based on this opaque object. */
> > +typedef uint64_t *rte_trace_t;
>
> Wouldn't a forward-declared struct, with the definition hidden from the
> user, be more appropriate? As a bonus, you'll get some type checking.
>
> "struct rte_trace;" here and "struct rte_trace*" in all the APIs.
> "struct rte_trace { uint64_t val; }; in the implementation. Or just cast
> it to a uint64_t *.

OK. I will remove the typedef then.

>
> typdef:ing pointers is generally considered a no-no, at least if you
> follow the Linux kernel coding conventions.
>
> > +
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + *
> > + * Enumerate trace mode operation.
> > + */
> > +enum rte_trace_mode_e {
> > +     /**
> > +      * In this mode, When no space left in trace buffer, the subsequent
> > +      * events overwrite the old events in the trace buffer.
> > +      */
> > +     RTE_TRACE_MODE_OVERWRITE,
> > +     /**
> > +      * In this mode, When no space left on trace buffer, the subsequent
> > +      * events shall not be recorded in the trace buffer.
> > +      */
> > +     RTE_TRACE_MODE_DISCARD,
> > +};
>
> Have you considered having a blocking mode as well, where the thread
> will just wait for space to be freed?

The trace buffer is per thread. So there is no waiting.

The new features can be added later as needed by extending the mode.

>
> Remove the "_e" from the name. "enum" already tells us it's an enumeration.

OK. I will remove it in v2.

>
> > +
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + *
> > + * Test if global trace is enabled.
> > + *
> > + * @return
> > + *    true if global trace is enabled, false otherwise.
> > + */
> > +__rte_experimental
> > +bool rte_trace_global_is_enabled(void);
>
> My impression is that DPDK does:
>
>
> __rte_experimental bool
>
> rte_trace_global_is_enabled(void);
>
>
> Now when I check the coding conventions, that's only for function
> definition. Why declaration and definition should be different, I don't
> know.

I see two patterns.(Both cases __rte_experimental in a new line)

__rte_experimental
bool
rte_trace_global_is_enabled(void);

or

__rte_experimental
bool rte_trace_global_is_enabled(void);

For the prototype case, I prefer a later option and for definition
case the first option.
If there are no specific opinions, I would like to stick to this model



> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + *
> > + * Set the global trace level.
> > + *
> > + * After this call, trace with a level lower or equal than the level
> > + * passed as argument will be captured in the trace buffer.
> > + *
> > + * @param level
> > + *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
> > + */
> > +__rte_experimental
> > +void rte_trace_global_level_set(uint32_t level);
>
> uint32_t means a lot of levels.

Yes. I did this to make compatibly with rte_log level datatype.


> > + *
> > + * @param trace
> > + *    The trace object.
> > + * @return
> > + *   - Zero or positive: Mode encoded as enum rte_trace_mode_e.
> > + *   - (-EINVAL): Trace object is not registered.
> > + */
> > +__rte_experimental
> > +int rte_trace_mode_get(rte_trace_t trace);
> > +
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + *
> > + * Enable/Disable a set of tracepoints based on shell pattern.
> Shell pattern means what I think is usually referred to as a glob?

According, "man 3 fnmatch", it can be both.
No preference here, The rte_log is using shell pattern as the comment
so I thought of
using the same.

Thoughts?


> > + *
> > + * @param pattern
> > + *   The match pattern identifying the tracepoint.
> > + * @param enable
> > + *    true to enable tracepoint, false to disable the tracepoint, upon match.
> > + * @param[out] found
> > + *    NULL value allowed, if not NULL, true if match found, false otherwise.
> > + * @return
> > + *   - 0: Success.
> > + *   - (-ERANGE): Trace object is not registered.
> > + */
> > +__rte_experimental
> > +int rte_trace_pattern(const char *pattern, bool enable, bool *found);
> > +
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + *
> > + * Enable/Disable a set of tracepoints based on regular expression.
> > + *
> > + * @param regex
> > + *   A regular expression identifying the tracepoint.
> > + * @param enable
> > + *    true to enable tracepoint, false to disable the tracepoint, upon match.
> > + * @param[out] found
> > + *    NULL value allowed, if not NULL, true if match found, false otherwise.
> What's the reason of having this output parameter, as opposed to coding
> the information into the return code?

I thought making explicit is good . No strong opinion here.
How about?

0: Success but no pattern found
>0: Sucess and pattern found
<0: error



> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + *
> > + * Search a trace object from its name.
> > + *
> > + * @param name
> > + *   The name of the tracepoint.
> > + * @return
> > + *   The tracepoint object or NULL if not found.
> > + */
> > +__rte_experimental
> > +rte_trace_t rte_trace_from_name(const char *name);
>
> Would "rte_trace_by_name" be a better name?

No strong preference. I will change to rte_trace_by_name().

>
> > +
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + *
> > + * Dump the trace metadata to a file.
> > + *
> > + * @param f
> > + *   A pointer to a file for output
> > + * @return
> > + *   - 0: Success.
> > + *   - <0 : Failure.
> > + */
> > +__rte_experimental
> > +int rte_trace_metadata_dump(FILE *f);
> > +
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + * Dump the trace subsystem status to a file.
> > + *
> > + * @param f
> > + *   A pointer to a file for output
> > + */
> > +__rte_experimental
> > +void rte_trace_dump(FILE *f);
> > +
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this API may change without prior notice
> > + *
> > + * Test if the trace datapath compile-time option is enabled.
> > + *
> > + * @return
> > + *   A positive value if trace datapath enabled, value zero otherwise.
> Switch to a bool return type.

I thought of avoiding "bool" in fastpath, I will change to bool if
there is no performance
impact.


> > + */
> > +static __rte_always_inline int
> > +rte_trace_is_dp_enabled(void)
> > +{
> > +#ifdef RTE_ENABLE_TRACE_DP
> > +     return RTE_ENABLE_TRACE_DP;
> > +#else
> > +     return 0;
> > +#endif
> > +}
> > +

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 03/32] eal/trace: implement trace register API
  2020-03-23 13:37     ` Jerin Jacob
@ 2020-03-23 14:43       ` Mattias Rönnblom
  2020-03-23 15:08         ` Jerin Jacob
  0 siblings, 1 reply; 142+ messages in thread
From: Mattias Rönnblom @ 2020-03-23 14:43 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: jerinj, Thomas Monjalon, Sunil Kumar Kori, dev, bruce.richardson,
	david.marchand

On 2020-03-23 14:37, Jerin Jacob wrote:
>>> +     }
>>> +
>>> +     /* Initialize the trace point */
>>> +     if (rte_strscpy(tp->name, name, TRACE_POINT_NAME_SIZE) < 0) {
>>> +             trace_err("name is too long");
>>> +             rte_errno = E2BIG;
>>> +             goto free;
>>> +     }
>>> +
>>> +     /* Copy the field data for future use */
>>> +     if (rte_strscpy(tp->ctf_field, field, TRACE_CTF_FIELD_SIZE) < 0) {
>>> +             trace_err("CTF field size is too long");
>>> +             rte_errno = E2BIG;
>>> +             goto free;
>>> +     }
>>> +
>>> +     /* Clear field memory for the next event */
>>> +     memset(field, 0, TRACE_CTF_FIELD_SIZE);
>>> +
>>> +     /* Form the trace handle */
>>> +     *handle = sz;
>>> +     *handle |= trace.nb_trace_points << __RTE_TRACE_FIELD_ID_SHIFT;
>>> +     *handle |= (uint64_t)level << __RTE_TRACE_FIELD_LEVEL_SHIFT;
>> If *handle would be a struct, you could use a bitfield instead, and much
>> simplify this code.
> I thought that initially, Two reasons why I did not do that
> 1) The flags have been used in fastpath, I prefer to work with flags
> in fastpath so that
Is it really that obvious that flags are faster than bitfield 
operations? I think most modern architectures have machine instructions 
for bitfield manipulation.
> there is no performance impact using bitfields from the compiler _if any_.
> 2) In some of the places, I can simply operate on APIs like
> __atomic_and_fetch() with flags.

I think you may still use such atomic operations. Just convert the 
struct to a uint64_t, which will essentially be a no-operation, and fire 
away.


static uint64_t

__rte_trace_raw(struct trace *t)

{

     uint64_t raw;

     memcpy(&raw, t, sizeof(struct trace));

     return raw;

}



^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 02/32] eal: define the public API for trace support
  2020-03-23 14:29     ` Jerin Jacob
@ 2020-03-23 14:46       ` Mattias Rönnblom
  0 siblings, 0 replies; 142+ messages in thread
From: Mattias Rönnblom @ 2020-03-23 14:46 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: jerinj, Thomas Monjalon, Bruce Richardson, John McNamara,
	Marko Kovacevic, Sunil Kumar Kori, dev, david.marchand

On 2020-03-23 15:29, Jerin Jacob wrote:
> On Thu, Mar 19, 2020 at 2:28 AM Mattias Rönnblom
> <mattias.ronnblom@ericsson.com> wrote:
>> On 2020-03-18 20:02, jerinj@marvell.com wrote:
>>> From: Jerin Jacob <jerinj@marvell.com>
>>> +
>>> +#include <rte_common.h>
>>> +#include <rte_compat.h>
>>> +
>>> +/** The trace object. The trace APIs are based on this opaque object. */
>>> +typedef uint64_t *rte_trace_t;
>> Wouldn't a forward-declared struct, with the definition hidden from the
>> user, be more appropriate? As a bonus, you'll get some type checking.
>>
>> "struct rte_trace;" here and "struct rte_trace*" in all the APIs.
>> "struct rte_trace { uint64_t val; }; in the implementation. Or just cast
>> it to a uint64_t *.
> OK. I will remove the typedef then.
>
>> typdef:ing pointers is generally considered a no-no, at least if you
>> follow the Linux kernel coding conventions.
>>
>>> +
>>> +/**
>>> + * @warning
>>> + * @b EXPERIMENTAL: this API may change without prior notice
>>> + *
>>> + * Enumerate trace mode operation.
>>> + */
>>> +enum rte_trace_mode_e {
>>> +     /**
>>> +      * In this mode, When no space left in trace buffer, the subsequent
>>> +      * events overwrite the old events in the trace buffer.
>>> +      */
>>> +     RTE_TRACE_MODE_OVERWRITE,
>>> +     /**
>>> +      * In this mode, When no space left on trace buffer, the subsequent
>>> +      * events shall not be recorded in the trace buffer.
>>> +      */
>>> +     RTE_TRACE_MODE_DISCARD,
>>> +};
>> Have you considered having a blocking mode as well, where the thread
>> will just wait for space to be freed?
> The trace buffer is per thread. So there is no waiting.
>
> The new features can be added later as needed by extending the mode.
>
>> Remove the "_e" from the name. "enum" already tells us it's an enumeration.
> OK. I will remove it in v2.
>
>>> +
>>> +/**
>>> + * @warning
>>> + * @b EXPERIMENTAL: this API may change without prior notice
>>> + *
>>> + * Test if global trace is enabled.
>>> + *
>>> + * @return
>>> + *    true if global trace is enabled, false otherwise.
>>> + */
>>> +__rte_experimental
>>> +bool rte_trace_global_is_enabled(void);
>> My impression is that DPDK does:
>>
>>
>> __rte_experimental bool
>>
>> rte_trace_global_is_enabled(void);
>>
>>
>> Now when I check the coding conventions, that's only for function
>> definition. Why declaration and definition should be different, I don't
>> know.
> I see two patterns.(Both cases __rte_experimental in a new line)
>
> __rte_experimental
> bool
> rte_trace_global_is_enabled(void);
>
> or
>
> __rte_experimental
> bool rte_trace_global_is_enabled(void);
>
> For the prototype case, I prefer a later option and for definition
> case the first option.
> If there are no specific opinions, I would like to stick to this model
>
>
>
>>> + * @warning
>>> + * @b EXPERIMENTAL: this API may change without prior notice
>>> + *
>>> + * Set the global trace level.
>>> + *
>>> + * After this call, trace with a level lower or equal than the level
>>> + * passed as argument will be captured in the trace buffer.
>>> + *
>>> + * @param level
>>> + *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
>>> + */
>>> +__rte_experimental
>>> +void rte_trace_global_level_set(uint32_t level);
>> uint32_t means a lot of levels.
> Yes. I did this to make compatibly with rte_log level datatype.
>
>
>>> + *
>>> + * @param trace
>>> + *    The trace object.
>>> + * @return
>>> + *   - Zero or positive: Mode encoded as enum rte_trace_mode_e.
>>> + *   - (-EINVAL): Trace object is not registered.
>>> + */
>>> +__rte_experimental
>>> +int rte_trace_mode_get(rte_trace_t trace);
>>> +
>>> +/**
>>> + * @warning
>>> + * @b EXPERIMENTAL: this API may change without prior notice
>>> + *
>>> + * Enable/Disable a set of tracepoints based on shell pattern.
>> Shell pattern means what I think is usually referred to as a glob?
> According, "man 3 fnmatch", it can be both.
> No preference here, The rte_log is using shell pattern as the comment
> so I thought of
> using the same.
>
> Thoughts?
>
If we're using "shell pattern" already, it would make sense to stick 
with this.
>>> + *
>>> + * @param pattern
>>> + *   The match pattern identifying the tracepoint.
>>> + * @param enable
>>> + *    true to enable tracepoint, false to disable the tracepoint, upon match.
>>> + * @param[out] found
>>> + *    NULL value allowed, if not NULL, true if match found, false otherwise.
>>> + * @return
>>> + *   - 0: Success.
>>> + *   - (-ERANGE): Trace object is not registered.
>>> + */
>>> +__rte_experimental
>>> +int rte_trace_pattern(const char *pattern, bool enable, bool *found);
>>> +
>>> +/**
>>> + * @warning
>>> + * @b EXPERIMENTAL: this API may change without prior notice
>>> + *
>>> + * Enable/Disable a set of tracepoints based on regular expression.
>>> + *
>>> + * @param regex
>>> + *   A regular expression identifying the tracepoint.
>>> + * @param enable
>>> + *    true to enable tracepoint, false to disable the tracepoint, upon match.
>>> + * @param[out] found
>>> + *    NULL value allowed, if not NULL, true if match found, false otherwise.
>> What's the reason of having this output parameter, as opposed to coding
>> the information into the return code?
> I thought making explicit is good . No strong opinion here.
> How about?
>
> 0: Success but no pattern found
>> 0: Sucess and pattern found
> <0: error
>
Sounds like an improvement to me.

>
>>> +/**
>>> + * @warning
>>> + * @b EXPERIMENTAL: this API may change without prior notice
>>> + *
>>> + * Search a trace object from its name.
>>> + *
>>> + * @param name
>>> + *   The name of the tracepoint.
>>> + * @return
>>> + *   The tracepoint object or NULL if not found.
>>> + */
>>> +__rte_experimental
>>> +rte_trace_t rte_trace_from_name(const char *name);
>> Would "rte_trace_by_name" be a better name?
> No strong preference. I will change to rte_trace_by_name().
>
>>> +
>>> +/**
>>> + * @warning
>>> + * @b EXPERIMENTAL: this API may change without prior notice
>>> + *
>>> + * Dump the trace metadata to a file.
>>> + *
>>> + * @param f
>>> + *   A pointer to a file for output
>>> + * @return
>>> + *   - 0: Success.
>>> + *   - <0 : Failure.
>>> + */
>>> +__rte_experimental
>>> +int rte_trace_metadata_dump(FILE *f);
>>> +
>>> +/**
>>> + * @warning
>>> + * @b EXPERIMENTAL: this API may change without prior notice
>>> + * Dump the trace subsystem status to a file.
>>> + *
>>> + * @param f
>>> + *   A pointer to a file for output
>>> + */
>>> +__rte_experimental
>>> +void rte_trace_dump(FILE *f);
>>> +
>>> +/**
>>> + * @warning
>>> + * @b EXPERIMENTAL: this API may change without prior notice
>>> + *
>>> + * Test if the trace datapath compile-time option is enabled.
>>> + *
>>> + * @return
>>> + *   A positive value if trace datapath enabled, value zero otherwise.
>> Switch to a bool return type.
> I thought of avoiding "bool" in fastpath, I will change to bool if
> there is no performance
> impact.
>
>
>>> + */
>>> +static __rte_always_inline int
>>> +rte_trace_is_dp_enabled(void)
>>> +{
>>> +#ifdef RTE_ENABLE_TRACE_DP
>>> +     return RTE_ENABLE_TRACE_DP;
>>> +#else
>>> +     return 0;
>>> +#endif
>>> +}
>>> +



^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 03/32] eal/trace: implement trace register API
  2020-03-23 14:43       ` Mattias Rönnblom
@ 2020-03-23 15:08         ` Jerin Jacob
  2020-03-23 16:44           ` Mattias Rönnblom
  0 siblings, 1 reply; 142+ messages in thread
From: Jerin Jacob @ 2020-03-23 15:08 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: jerinj, Thomas Monjalon, Sunil Kumar Kori, dev, bruce.richardson,
	david.marchand, Ananyev, Konstantin

On Mon, Mar 23, 2020 at 8:13 PM Mattias Rönnblom
<mattias.ronnblom@ericsson.com> wrote:
>
> On 2020-03-23 14:37, Jerin Jacob wrote:
> >>> +     }
> >>> +
> >>> +     /* Initialize the trace point */
> >>> +     if (rte_strscpy(tp->name, name, TRACE_POINT_NAME_SIZE) < 0) {
> >>> +             trace_err("name is too long");
> >>> +             rte_errno = E2BIG;
> >>> +             goto free;
> >>> +     }
> >>> +
> >>> +     /* Copy the field data for future use */
> >>> +     if (rte_strscpy(tp->ctf_field, field, TRACE_CTF_FIELD_SIZE) < 0) {
> >>> +             trace_err("CTF field size is too long");
> >>> +             rte_errno = E2BIG;
> >>> +             goto free;
> >>> +     }
> >>> +
> >>> +     /* Clear field memory for the next event */
> >>> +     memset(field, 0, TRACE_CTF_FIELD_SIZE);
> >>> +
> >>> +     /* Form the trace handle */
> >>> +     *handle = sz;
> >>> +     *handle |= trace.nb_trace_points << __RTE_TRACE_FIELD_ID_SHIFT;
> >>> +     *handle |= (uint64_t)level << __RTE_TRACE_FIELD_LEVEL_SHIFT;
> >> If *handle would be a struct, you could use a bitfield instead, and much
> >> simplify this code.
> > I thought that initially, Two reasons why I did not do that
> > 1) The flags have been used in fastpath, I prefer to work with flags
> > in fastpath so that
> Is it really that obvious that flags are faster than bitfield
> operations? I think most modern architectures have machine instructions
> for bitfield manipulation.

Add x86 maintainers.

There were comments in ml about bitfield inefficiency usage with x86.

http://patches.dpdk.org/patch/16482/

Search for: Bitfileds are efficient on Octeon. What's about other CPUs
you have in
mind? x86 is not as efficient.

Thoughts from x86 folks.

> > there is no performance impact using bitfields from the compiler _if any_.
> > 2) In some of the places, I can simply operate on APIs like
> > __atomic_and_fetch() with flags.
>
> I think you may still use such atomic operations. Just convert the
> struct to a uint64_t, which will essentially be a no-operation, and fire
> away.

Not sure, We think about the atomic "and" and fetch here.
That memcpy may translate additional load/store based on the compiler
optimization level.(say compiled with -O0)

>
>
> static uint64_t
>
> __rte_trace_raw(struct trace *t)
>
> {
>
>      uint64_t raw;
>
>      memcpy(&raw, t, sizeof(struct trace));
>
>      return raw;
>
> }
>
>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 03/32] eal/trace: implement trace register API
  2020-03-23 15:08         ` Jerin Jacob
@ 2020-03-23 16:44           ` Mattias Rönnblom
  2020-03-23 18:40             ` Jerin Jacob
  0 siblings, 1 reply; 142+ messages in thread
From: Mattias Rönnblom @ 2020-03-23 16:44 UTC (permalink / raw)
  To: Jerin Jacob
  Cc: jerinj, Thomas Monjalon, Sunil Kumar Kori, dev, bruce.richardson,
	david.marchand, Ananyev, Konstantin

On 2020-03-23 16:08, Jerin Jacob wrote:
> On Mon, Mar 23, 2020 at 8:13 PM Mattias Rönnblom
> <mattias.ronnblom@ericsson.com> wrote:
>> On 2020-03-23 14:37, Jerin Jacob wrote:
>>>>> +     }
>>>>> +
>>>>> +     /* Initialize the trace point */
>>>>> +     if (rte_strscpy(tp->name, name, TRACE_POINT_NAME_SIZE) < 0) {
>>>>> +             trace_err("name is too long");
>>>>> +             rte_errno = E2BIG;
>>>>> +             goto free;
>>>>> +     }
>>>>> +
>>>>> +     /* Copy the field data for future use */
>>>>> +     if (rte_strscpy(tp->ctf_field, field, TRACE_CTF_FIELD_SIZE) < 0) {
>>>>> +             trace_err("CTF field size is too long");
>>>>> +             rte_errno = E2BIG;
>>>>> +             goto free;
>>>>> +     }
>>>>> +
>>>>> +     /* Clear field memory for the next event */
>>>>> +     memset(field, 0, TRACE_CTF_FIELD_SIZE);
>>>>> +
>>>>> +     /* Form the trace handle */
>>>>> +     *handle = sz;
>>>>> +     *handle |= trace.nb_trace_points << __RTE_TRACE_FIELD_ID_SHIFT;
>>>>> +     *handle |= (uint64_t)level << __RTE_TRACE_FIELD_LEVEL_SHIFT;
>>>> If *handle would be a struct, you could use a bitfield instead, and much
>>>> simplify this code.
>>> I thought that initially, Two reasons why I did not do that
>>> 1) The flags have been used in fastpath, I prefer to work with flags
>>> in fastpath so that
>> Is it really that obvious that flags are faster than bitfield
>> operations? I think most modern architectures have machine instructions
>> for bitfield manipulation.
> Add x86 maintainers.
>
> There were comments in ml about bitfield inefficiency usage with x86.
>
> https://protect2.fireeye.com/v1/url?k=2bd2d3ad-7706d931-2bd29336-8631fc8bdea5-8a1bf17ed26f6ce6&q=1&e=0c620ac5-c028-44d9-a4e8-e04057940075&u=http%3A%2F%2Fpatches.dpdk.org%2Fpatch%2F16482%2F
>
> Search for: Bitfileds are efficient on Octeon. What's about other CPUs
> you have in
> mind? x86 is not as efficient.


I thought both ARM and x86 had bitfield access instructions, but it 
looks like I was wrong about x86. x86_64 GCC seems to convert bitfield 
read to 'shr' and 'and', just like an open-coded bitfield. Bitfield 
write requires more instructions.


> Thoughts from x86 folks.
>
>>> there is no performance impact using bitfields from the compiler _if any_.
>>> 2) In some of the places, I can simply operate on APIs like
>>> __atomic_and_fetch() with flags.
>> I think you may still use such atomic operations. Just convert the
>> struct to a uint64_t, which will essentially be a no-operation, and fire
>> away.
> Not sure, We think about the atomic "and" and fetch here.
> That memcpy may translate additional load/store based on the compiler
> optimization level.(say compiled with -O0)


I would be surprised if that happened on anything but -O0. At least 
modern GCC on ARM and x86_64 don't seem to add any loads or stores.


I assume you are not suggesting we should optimize for -O0.


>>
>> static uint64_t
>>
>> __rte_trace_raw(struct trace *t)
>>
>> {
>>
>>       uint64_t raw;
>>
>>       memcpy(&raw, t, sizeof(struct trace));
>>
>>       return raw;
>>
>> }
>>
>>


^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [dpdk-dev] [PATCH v1 03/32] eal/trace: implement trace register API
  2020-03-23 16:44           ` Mattias Rönnblom
@ 2020-03-23 18:40             ` Jerin Jacob
  0 siblings, 0 replies; 142+ messages in thread
From: Jerin Jacob @ 2020-03-23 18:40 UTC (permalink / raw)
  To: Mattias Rönnblom
  Cc: jerinj, Thomas Monjalon, Sunil Kumar Kori, dev, bruce.richardson,
	david.marchand, Ananyev, Konstantin

On Mon, Mar 23, 2020 at 10:14 PM Mattias Rönnblom
<mattias.ronnblom@ericsson.com> wrote:
>
> On 2020-03-23 16:08, Jerin Jacob wrote:
> > On Mon, Mar 23, 2020 at 8:13 PM Mattias Rönnblom
> > <mattias.ronnblom@ericsson.com> wrote:
> >> On 2020-03-23 14:37, Jerin Jacob wrote:
> >>>>> +     }
> >>>>> +
> >>>>> +     /* Initialize the trace point */
> >>>>> +     if (rte_strscpy(tp->name, name, TRACE_POINT_NAME_SIZE) < 0) {
> >>>>> +             trace_err("name is too long");
> >>>>> +             rte_errno = E2BIG;
> >>>>> +             goto free;
> >>>>> +     }
> >>>>> +
> >>>>> +     /* Copy the field data for future use */
> >>>>> +     if (rte_strscpy(tp->ctf_field, field, TRACE_CTF_FIELD_SIZE) < 0) {
> >>>>> +             trace_err("CTF field size is too long");
> >>>>> +             rte_errno = E2BIG;
> >>>>> +             goto free;
> >>>>> +     }
> >>>>> +
> >>>>> +     /* Clear field memory for the next event */
> >>>>> +     memset(field, 0, TRACE_CTF_FIELD_SIZE);
> >>>>> +
> >>>>> +     /* Form the trace handle */
> >>>>> +     *handle = sz;
> >>>>> +     *handle |= trace.nb_trace_points << __RTE_TRACE_FIELD_ID_SHIFT;
> >>>>> +     *handle |= (uint64_t)level << __RTE_TRACE_FIELD_LEVEL_SHIFT;
> >>>> If *handle would be a struct, you could use a bitfield instead, and much
> >>>> simplify this code.
> >>> I thought that initially, Two reasons why I did not do that
> >>> 1) The flags have been used in fastpath, I prefer to work with flags
> >>> in fastpath so that
> >> Is it really that obvious that flags are faster than bitfield
> >> operations? I think most modern architectures have machine instructions
> >> for bitfield manipulation.
> > Add x86 maintainers.
> >
> > There were comments in ml about bitfield inefficiency usage with x86.
> >
> > https://protect2.fireeye.com/v1/url?k=2bd2d3ad-7706d931-2bd29336-8631fc8bdea5-8a1bf17ed26f6ce6&q=1&e=0c620ac5-c028-44d9-a4e8-e04057940075&u=http%3A%2F%2Fpatches.dpdk.org%2Fpatch%2F16482%2F
> >
> > Search for: Bitfileds are efficient on Octeon. What's about other CPUs
> > you have in
> > mind? x86 is not as efficient.
>
>
> I thought both ARM and x86 had bitfield access instructions, but it
> looks like I was wrong about x86. x86_64 GCC seems to convert bitfield
> read to 'shr' and 'and', just like an open-coded bitfield. Bitfield
> write requires more instructions.

Yes. ARM64 has bitfield access instructions. considering x86,
it is better to avoid bitfields.

See below,

>
>
> > Thoughts from x86 folks.
> >
> >>> there is no performance impact using bitfields from the compiler _if any_.
> >>> 2) In some of the places, I can simply operate on APIs like
> >>> __atomic_and_fetch() with flags.
> >> I think you may still use such atomic operations. Just convert the
> >> struct to a uint64_t, which will essentially be a no-operation, and fire
> >> away.
> > Not sure, We think about the atomic "and" and fetch here.
> > That memcpy may translate additional load/store based on the compiler
> > optimization level.(say compiled with -O0)
>
>
> I would be surprised if that happened on anything but -O0. At least
> modern GCC on ARM and x86_64 don't seem to add any loads or stores.
>
>
> I assume you are not suggesting we should optimize for -O0.

No. I was just mentining that, we can not assume  the code generation
with -O0. Anyway considering the above point, lets use flags.

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v2 00/32] DPDK Trace support
  2020-03-18 19:02 [dpdk-dev] [PATCH v1 00/32] DPDK Trace support jerinj
                   ` (31 preceding siblings ...)
  2020-03-18 19:02 ` [dpdk-dev] [PATCH v1 32/32] doc: add trace library guide jerinj
@ 2020-03-25 21:15 ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 01/32] eal: introduce API for getting thread name jerinj
                     ` (32 more replies)
  32 siblings, 33 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

v2:

Addressed the following review comments from Mattias Rönnblom:

1) Changed 

from:
typedef uint64_t* rte_trace_t;
to
typedef uint64_t rte_trace_t;

Initially thought to make the handle as
struct rte_trace {
    uint64_t val;
}

but changed to uint64_t for the following reasons
a) It is opaque to the application and it will fix the compile-time type
check as well.
b) The handle has an index that will point to an internal slow-path
structure so no ABI change required in the future.
c) RTE_TRACE_POINT_DEFINE need to expose trace object. So it is better
to keep as uint64_t and avoid one more indirection for no use.

2)
Changed:
from:
enum rte_trace_mode_e {
to:
enum rte_trace_mode {


3) removed [out] "found" param from rte_trace_pattern() and
rte_trace_regexp()


4) Changed rte_trace_from_name to rte_trace_by_name

5) rte_trace_is_dp_enabled() return bool now


6) in __rte_trace_point_register() the argument fn change to register_fn

7) removed !! from rte_trace_is_enabled()

8) Remove uninitialized "rc warning" from rte_trace_pattern() and
rte_trace_regexp()

9) fixup bool return type for trace_entry_compare()

10) fixup calloc casting in trace_mkdir()

11) check fclose() return in trace_meta_save() and trace_mem_save()

12) rte_trace_ctf_* macro cleanup

13) added release notes

14) fix build issues reported by CI
http://mails.dpdk.org/archives/test-report/2020-March/121235.html


This patch set contains 
~~~~~~~~~~~~~~~~~~~~~~~~

# The native implementation of common trace format(CTF)[1] based tracer
# Public API to create the trace points.
# Add tracepoints to eal, ethdev, mempool, eventdev and cryptodev 
library for tracing support
# A unit test case
# Performance test case to measure the trace overhead. (See eal/trace:
# add trace performance test cases, patch)
# Programmers guide for Trace support(See doc: add trace library guide,
# patch)

# Tested OS:
~~~~~~~~~~~
- Linux
- FreeBSD

# Tested open source CTF trace viewers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Babeltrace
- Tracecompass

# Trace overhead comparison with LTTng
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

trace overhead data on x86:[2]
# 236 cycles with LTTng(>100ns)
# 18 cycles(7ns) with Native DPDK CTF emitter.(See eal/trace: add trace
# performance test cases patch)

trace overhead data on arm64:
#  312  cycles to  1100 cycles with LTTng based on the class of arm64
#  CPU.
#  11 cycles to 13 cycles with Native DPDK CTF emitter based on the
class of arm64 CPU.

18 cycles(on x86) vs 11 cycles(on arm64) is due to rdtsc() overhead in
x86. It seems  rdtsc takes around 15cycles in x86.


Items that needs to be sort it out 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Makefile and meson.build are updated to allow experimental APIs.

As multiple EXPERIMENTAL symbols, exported by trace library, are
used in various drivers, lib, app and examples. So to fix compilation
warning/error, Makefile and meson.build are updated for all required
components to support EXPERIMENTAL APIs.
It results same code changes at multiple components as well as
increases source code line changes in patchset too.
Suggestions are welcome to resolve this issue with lesser code changes.
	
More details:
~~~~~~~~~~~~~

# The Native DPDK CTF trace support does not have any dependency on
third-party library.
The generated output file is compatible with LTTng as both are using
CTF trace format.

The performance gain comes from:
1) exploit dpdk worker thread usage model to avoid atomics and use per
core variables
2) use hugepage,
3) avoid a lot function pointers in fast-path etc
4) avoid unaligned store for arm64 etc

Features:
~~~~~~~~~
- APIs and Features are similar to rte_log dynamic framework
API(expect log prints on stdout vs it dumps on trace file)
- No specific limit on the events. A string-based event like rte_log
for pattern matching
- Dynamic enable/disable support.
- Instructmention overhead is ~1 cycle. i.e cost of adding the code
wth out using trace feature.
- Timestamp support for all the events using DPDK rte_rtdsc
- No dependency on another library. Clean room native implementation of
  CTF.

Functional test case:
a) echo "trace_autotest" | sudo ./build/app/test/dpdk-test  -c 0x3
--trace-level=8

The above command emits the following trace events
<code>
        uint8_t i;

        rte_trace_lib_eal_generic_void();
        rte_trace_lib_eal_generic_u64(0x10000000000000);
        rte_trace_lib_eal_generic_u32(0x10000000);
        rte_trace_lib_eal_generic_u16(0xffee);
        rte_trace_lib_eal_generic_u8(0xc);
        rte_trace_lib_eal_generic_i64(-1234);
        rte_trace_lib_eal_generic_i32(-1234567);
        rte_trace_lib_eal_generic_i16(12);
        rte_trace_lib_eal_generic_i8(-3);
        rte_trace_lib_eal_generic_string("my string");
        rte_trace_lib_eal_generic_function(__func__);

        for (i = 0; i < 128; i++)
                rte_trace_lib_eal_generic_u8(i);
</code>

Install babeltrace package in Linux and point the generated trace file
to babel trace. By default trace file created under
<user>/dpdk-traces/time_stamp/

example:
# babeltrace /root/dpdk-traces/rte-2020-02-15-PM-02-56-51 | more

[13:27:36.138468807] (+?.?????????) lib.eal.generic.void: { cpu_id =
0, name = "dpdk-test" }, { }
[13:27:36.138468851] (+0.000000044) lib.eal.generic.u64: { cpu_id = 0,
name = "dpdk-test" }, { in = 4503599627370496 }
[13:27:36.138468860] (+0.000000009) lib.eal.generic.u32: { cpu_id = 0,
name = "dpdk-test" }, { in = 268435456 }
[13:27:36.138468934] (+0.000000074) lib.eal.generic.u16: { cpu_id = 0,
name = "dpdk-test" }, { in = 65518 }
[13:27:36.138468949] (+0.000000015) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 12 }
[13:27:36.138468956] (+0.000000007) lib.eal.generic.i64: { cpu_id = 0,
name = "dpdk-test" }, { in = -1234 }
[13:27:36.138468963] (+0.000000007) lib.eal.generic.i32: { cpu_id = 0,
name = "dpdk-test" }, { in = -1234567 }
[13:27:36.138469024] (+0.000000061) lib.eal.generic.i16: { cpu_id = 0,
name = "dpdk-test" }, { in = 12 }
[13:27:36.138469044] (+0.000000020) lib.eal.generic.i8: { cpu_id = 0,
name = "dpdk-test" }, { in = -3 }
[13:27:36.138469051] (+0.000000007) lib.eal.generic.string: { cpu_id =
0, name = "dpdk-test" }, { str = "my string" }
[13:27:36.138469203] (+0.000000152) lib.eal.generic.func: { cpu_id =
0, name = "dpdk-test" }, { func = "test_trace_points" }
[13:27:36.138469239] (+0.000000036) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 0 }
[13:27:36.138469246] (+0.000000007) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 1 }
[13:27:36.138469252] (+0.000000006) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 2 }
[13:27:36.138469262] (+0.000000010) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 3 }
[13:27:36.138469269] (+0.000000007) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 4 }
[13:27:36.138469276] (+0.000000007) lib.eal.generic.u8: { cpu_id = 0,
name = "dpdk-test" }, { in = 5 }

# There is a  GUI based trace viewer available in Windows, Linux and
# Mac.
It is called as tracecompass.(https://www.eclipse.org/tracecompass/)

The example screenshot and Histogram of above DPDK trace using
Tracecompass.

https://github.com/jerinjacobk/share/blob/master/dpdk_trace.JPG



File walk through:
~~~~~~~~~~~~~~~~~~

lib/librte_eal/common/include/rte_trace.h - Public API for Trace
provider and Trace control
lib/librte_eal/common/eal_common_trace.c - main trace implementation
lib/librte_eal/common/eal_common_trace_ctf.c - CTF metadata spec
implementation
lib/librte_eal/common/eal_common_trace_utils.c - command line utils
and filesystem operations.
lib/librte_eal/common/eal_common_trace_points.c -  trace points for EAL
library
lib/librte_eal/common/include/rte_trace_eal.h - EAL tracepoint public
API.
lib/librte_eal/common/eal_trace.h - Private trace header file.


[1] https://diamon.org/ctf/

[2] The above test is ported to LTTng for finding the LTTng trace
overhead. It available at
https://github.com/jerinjacobk/lttng-overhead
https://github.com/jerinjacobk/lttng-overhead/blob/master/README

Jerin Jacob (21):
  eal: introduce API for getting thread name
  eal: define the public API for trace support
  eal/trace: implement trace register API
  eal/trace: implement trace operation APIs
  eal/trace: add internal trace init and fini interface
  eal/trace: get bootup timestamp for trace
  eal/trace: create CTF TDSL metadata in memory
  eal/trace: implement trace memory allocation
  eal/trace: implement debug dump function
  eal/trace: implement trace save
  eal/trace: implement registration payload
  eal/trace: implement provider payload
  eal/trace: hook internal trace APIs to Linux
  eal/trace: hook internal trace APIs to FreeBSD
  eal/trace: add generic tracepoints
  eal/trace: add alarm tracepoints
  eal/trace: add memory tracepoints
  eal/trace: add memzone tracepoints
  eal/trace: add thread tracepoints
  eal/trace: add interrupt tracepoints
  eal/trace: add trace performance test cases

Sunil Kumar Kori (11):
  eal/trace: handle CTF keyword collision
  eal/trace: add trace level configuration parameter
  eal/trace: add trace dir configuration parameter
  eal/trace: add trace bufsize configuration parameter
  eal/trace: add trace mode configuration parameter
  eal/trace: add unit test cases
  ethdev: add tracepoints
  eventdev: add tracepoints
  cryptodev: add tracepoints
  mempool: add tracepoints
  doc: add trace library guide

 MAINTAINERS                                   |  15 +
 app/pdump/Makefile                            |   1 +
 app/pdump/meson.build                         |   1 +
 app/proc-info/Makefile                        |   1 +
 app/proc-info/meson.build                     |   1 +
 app/test-acl/Makefile                         |   1 +
 app/test-acl/meson.build                      |   1 +
 app/test-cmdline/Makefile                     |   1 +
 app/test-cmdline/meson.build                  |   1 +
 app/test-eventdev/Makefile                    |   1 +
 app/test-eventdev/meson.build                 |   1 +
 app/test-pipeline/Makefile                    |   1 +
 app/test-pipeline/meson.build                 |   1 +
 app/test/Makefile                             |   4 +-
 app/test/meson.build                          |   3 +
 app/test/test_trace.c                         | 618 ++++++++++++++++++
 app/test/test_trace.h                         |  52 ++
 app/test/test_trace_perf.c                    | 179 +++++
 app/test/test_trace_register.c                |  46 ++
 config/common_base                            |   1 +
 config/rte_config.h                           |   1 +
 doc/api/doxy-api-index.md                     |   3 +-
 doc/guides/linux_gsg/eal_args.include.rst     |  55 ++
 doc/guides/prog_guide/index.rst               |   1 +
 doc/guides/prog_guide/trace_lib.rst           | 265 ++++++++
 doc/guides/rel_notes/release_20_05.rst        |   9 +
 drivers/common/cpt/Makefile                   |   1 +
 drivers/crypto/ccp/Makefile                   |   1 +
 drivers/crypto/ccp/meson.build                |   2 +
 drivers/crypto/mvsam/Makefile                 |   1 +
 drivers/crypto/mvsam/meson.build              |   1 +
 drivers/crypto/null/Makefile                  |   1 +
 drivers/crypto/null/meson.build               |   1 +
 drivers/crypto/scheduler/Makefile             |   1 +
 drivers/crypto/scheduler/meson.build          |   1 +
 drivers/crypto/virtio/Makefile                |   1 +
 drivers/crypto/virtio/meson.build             |   1 +
 drivers/event/octeontx/Makefile               |   1 +
 drivers/event/octeontx/meson.build            |   1 +
 drivers/event/skeleton/Makefile               |   1 +
 drivers/event/skeleton/meson.build            |   1 +
 drivers/event/sw/Makefile                     |   1 +
 drivers/event/sw/meson.build                  |   1 +
 drivers/mempool/ring/Makefile                 |   1 +
 drivers/mempool/ring/meson.build              |   1 +
 drivers/net/af_packet/Makefile                |   1 +
 drivers/net/af_packet/meson.build             |   1 +
 drivers/net/af_xdp/Makefile                   |   1 +
 drivers/net/af_xdp/meson.build                |   1 +
 drivers/net/ark/Makefile                      |   1 +
 drivers/net/ark/meson.build                   |   1 +
 drivers/net/bnxt/Makefile                     |   1 +
 drivers/net/bnxt/meson.build                  |   1 +
 drivers/net/cxgbe/Makefile                    |   1 +
 drivers/net/cxgbe/meson.build                 |   1 +
 drivers/net/enetc/Makefile                    |   1 +
 drivers/net/enetc/meson.build                 |   1 +
 drivers/net/hinic/Makefile                    |   1 +
 drivers/net/hinic/base/meson.build            |   3 +-
 drivers/net/hinic/meson.build                 |   1 +
 drivers/net/ionic/ionic_dev.c                 |   1 +
 drivers/net/ionic/ionic_mac_api.c             |   1 +
 drivers/net/ionic/ionic_main.c                |   1 +
 drivers/net/kni/Makefile                      |   1 +
 drivers/net/kni/meson.build                   |   1 +
 drivers/net/liquidio/Makefile                 |   1 +
 drivers/net/liquidio/meson.build              |   1 +
 drivers/net/mvneta/Makefile                   |   1 +
 drivers/net/mvneta/meson.build                |   1 +
 drivers/net/mvpp2/Makefile                    |   1 +
 drivers/net/mvpp2/meson.build                 |   1 +
 drivers/net/nfb/Makefile                      |   1 +
 drivers/net/nfb/meson.build                   |   1 +
 drivers/net/null/Makefile                     |   1 +
 drivers/net/null/meson.build                  |   1 +
 drivers/net/octeontx/Makefile                 |   1 +
 drivers/net/octeontx2/Makefile                |   1 +
 drivers/net/octeontx2/meson.build             |   1 +
 drivers/net/pcap/Makefile                     |   1 +
 drivers/net/pcap/meson.build                  |   1 +
 drivers/net/ring/Makefile                     |   1 +
 drivers/net/ring/meson.build                  |   1 +
 drivers/net/szedata2/Makefile                 |   1 +
 drivers/net/szedata2/meson.build              |   1 +
 drivers/net/thunderx/base/meson.build         |   1 +
 drivers/net/vhost/Makefile                    |   1 +
 drivers/net/vhost/meson.build                 |   1 +
 drivers/raw/ioat/Makefile                     |   1 +
 drivers/raw/ioat/meson.build                  |   1 +
 drivers/raw/octeontx2_dma/Makefile            |   1 +
 drivers/raw/octeontx2_dma/meson.build         |   1 +
 drivers/raw/octeontx2_ep/Makefile             |   1 +
 drivers/raw/octeontx2_ep/meson.build          |   1 +
 drivers/raw/skeleton/Makefile                 |   1 +
 drivers/raw/skeleton/meson.build              |   1 +
 examples/cmdline/Makefile                     |   1 +
 examples/cmdline/meson.build                  |   1 +
 examples/distributor/Makefile                 |   1 +
 examples/distributor/meson.build              |   1 +
 examples/ethtool/ethtool-app/Makefile         |   1 +
 examples/eventdev_pipeline/meson.build        |   1 +
 examples/flow_filtering/Makefile              |   1 +
 examples/flow_filtering/meson.build           |   1 +
 examples/helloworld/Makefile                  |   1 +
 examples/helloworld/meson.build               |   1 +
 examples/ioat/Makefile                        |   1 +
 examples/ioat/meson.build                     |   1 +
 examples/ip_fragmentation/Makefile            |   2 +
 examples/ip_fragmentation/meson.build         |   1 +
 examples/ip_reassembly/Makefile               |   1 +
 examples/ip_reassembly/meson.build            |   1 +
 examples/ipv4_multicast/Makefile              |   1 +
 examples/ipv4_multicast/meson.build           |   1 +
 examples/l2fwd-cat/Makefile                   |   1 +
 examples/l2fwd-cat/meson.build                |   1 +
 examples/l2fwd-event/Makefile                 |   1 +
 examples/l2fwd-event/meson.build              |   1 +
 examples/l2fwd-jobstats/Makefile              |   1 +
 examples/l2fwd-jobstats/meson.build           |   1 +
 examples/l2fwd-keepalive/Makefile             |   1 +
 examples/l2fwd-keepalive/ka-agent/Makefile    |   1 +
 examples/l2fwd-keepalive/meson.build          |   1 +
 examples/l3fwd-acl/Makefile                   |   1 +
 examples/l3fwd-acl/meson.build                |   1 +
 examples/l3fwd/Makefile                       |   1 +
 examples/l3fwd/meson.build                    |   1 +
 examples/link_status_interrupt/Makefile       |   1 +
 examples/link_status_interrupt/meson.build    |   1 +
 .../client_server_mp/mp_client/Makefile       |   1 +
 .../client_server_mp/mp_client/meson.build    |   1 +
 .../client_server_mp/mp_server/meson.build    |   1 +
 examples/multi_process/hotplug_mp/Makefile    |   1 +
 examples/multi_process/hotplug_mp/meson.build |   1 +
 examples/multi_process/simple_mp/Makefile     |   1 +
 examples/multi_process/simple_mp/meson.build  |   1 +
 examples/multi_process/symmetric_mp/Makefile  |   1 +
 .../multi_process/symmetric_mp/meson.build    |   1 +
 examples/ntb/Makefile                         |   1 +
 examples/ntb/meson.build                      |   1 +
 examples/packet_ordering/Makefile             |   1 +
 examples/packet_ordering/meson.build          |   1 +
 .../performance-thread/l3fwd-thread/Makefile  |   1 +
 .../l3fwd-thread/meson.build                  |   1 +
 .../performance-thread/pthread_shim/Makefile  |   1 +
 .../pthread_shim/meson.build                  |   1 +
 examples/ptpclient/Makefile                   |   1 +
 examples/ptpclient/meson.build                |   1 +
 examples/qos_meter/Makefile                   |   1 +
 examples/qos_meter/meson.build                |   1 +
 examples/qos_sched/Makefile                   |   1 +
 examples/qos_sched/meson.build                |   1 +
 examples/server_node_efd/node/Makefile        |   1 +
 examples/server_node_efd/node/meson.build     |   1 +
 examples/server_node_efd/server/Makefile      |   1 +
 examples/server_node_efd/server/meson.build   |   1 +
 examples/service_cores/Makefile               |   1 +
 examples/service_cores/meson.build            |   1 +
 examples/skeleton/Makefile                    |   1 +
 examples/skeleton/meson.build                 |   1 +
 examples/timer/Makefile                       |   1 +
 examples/timer/meson.build                    |   1 +
 examples/vm_power_manager/Makefile            |   1 +
 examples/vm_power_manager/meson.build         |   1 +
 examples/vmdq/Makefile                        |   1 +
 examples/vmdq/meson.build                     |   1 +
 examples/vmdq_dcb/Makefile                    |   1 +
 examples/vmdq_dcb/meson.build                 |   1 +
 lib/librte_bitratestats/Makefile              |   1 +
 lib/librte_bitratestats/meson.build           |   1 +
 lib/librte_cryptodev/Makefile                 |   4 +-
 lib/librte_cryptodev/cryptodev_trace_points.c |  70 ++
 lib/librte_cryptodev/meson.build              |   7 +-
 lib/librte_cryptodev/rte_cryptodev.c          |  18 +
 lib/librte_cryptodev/rte_cryptodev.h          |   6 +
 .../rte_cryptodev_version.map                 |  18 +
 lib/librte_cryptodev/rte_trace_cryptodev.h    | 133 ++++
 lib/librte_cryptodev/rte_trace_cryptodev_fp.h |  34 +
 lib/librte_distributor/Makefile               |   1 +
 lib/librte_distributor/meson.build            |   1 +
 lib/librte_eal/common/Makefile                |   1 +
 lib/librte_eal/common/eal_common_log.c        |   9 +-
 lib/librte_eal/common/eal_common_memzone.c    |   9 +
 lib/librte_eal/common/eal_common_options.c    |  68 +-
 lib/librte_eal/common/eal_common_thread.c     |   3 +-
 lib/librte_eal/common/eal_common_trace.c      | 610 +++++++++++++++++
 lib/librte_eal/common/eal_common_trace_ctf.c  | 488 ++++++++++++++
 .../common/eal_common_trace_points.c          | 115 ++++
 .../common/eal_common_trace_utils.c           | 523 +++++++++++++++
 lib/librte_eal/common/eal_options.h           |   8 +
 lib/librte_eal/common/eal_private.h           |  11 +
 lib/librte_eal/common/eal_trace.h             | 122 ++++
 lib/librte_eal/common/include/rte_lcore.h     |  17 +
 lib/librte_eal/common/include/rte_trace.h     | 584 +++++++++++++++++
 lib/librte_eal/common/include/rte_trace_eal.h | 247 +++++++
 .../common/include/rte_trace_provider.h       | 137 ++++
 .../common/include/rte_trace_register.h       |  53 ++
 lib/librte_eal/common/meson.build             |   8 +
 lib/librte_eal/common/rte_malloc.c            |  60 +-
 lib/librte_eal/freebsd/eal/Makefile           |   4 +
 lib/librte_eal/freebsd/eal/eal.c              |  10 +
 lib/librte_eal/freebsd/eal/eal_alarm.c        |   3 +
 lib/librte_eal/freebsd/eal/eal_interrupts.c   |  52 +-
 lib/librte_eal/freebsd/eal/eal_thread.c       |  21 +-
 lib/librte_eal/linux/eal/Makefile             |   4 +
 lib/librte_eal/linux/eal/eal.c                |   9 +
 lib/librte_eal/linux/eal/eal_alarm.c          |   4 +
 lib/librte_eal/linux/eal/eal_interrupts.c     |  84 ++-
 lib/librte_eal/linux/eal/eal_thread.c         |  27 +-
 lib/librte_eal/rte_eal_version.map            |  61 ++
 lib/librte_ethdev/Makefile                    |   3 +
 lib/librte_ethdev/ethdev_trace_points.c       |  43 ++
 lib/librte_ethdev/meson.build                 |   5 +-
 lib/librte_ethdev/rte_ethdev.c                |  12 +
 lib/librte_ethdev/rte_ethdev.h                |   5 +
 lib/librte_ethdev/rte_ethdev_version.map      |  10 +
 lib/librte_ethdev/rte_trace_ethdev.h          |  90 +++
 lib/librte_ethdev/rte_trace_ethdev_fp.h       |  40 ++
 lib/librte_eventdev/Makefile                  |   3 +
 lib/librte_eventdev/eventdev_trace_points.c   | 173 +++++
 lib/librte_eventdev/meson.build               |   3 +
 .../rte_event_crypto_adapter.c                |  10 +
 .../rte_event_eth_rx_adapter.c                |  11 +
 .../rte_event_eth_tx_adapter.c                |  13 +-
 .../rte_event_eth_tx_adapter.h                |   2 +
 lib/librte_eventdev/rte_event_timer_adapter.c |   8 +-
 lib/librte_eventdev/rte_event_timer_adapter.h |   8 +
 lib/librte_eventdev/rte_eventdev.c            |   9 +
 lib/librte_eventdev/rte_eventdev.h            |   5 +-
 lib/librte_eventdev/rte_eventdev_version.map  |  42 ++
 lib/librte_eventdev/rte_trace_eventdev.h      | 278 ++++++++
 lib/librte_eventdev/rte_trace_eventdev_fp.h   |  75 +++
 lib/librte_gro/Makefile                       |   1 +
 lib/librte_gro/meson.build                    |   1 +
 lib/librte_gso/Makefile                       |   1 +
 lib/librte_gso/meson.build                    |   1 +
 lib/librte_ip_frag/Makefile                   |   1 +
 lib/librte_ip_frag/meson.build                |   1 +
 lib/librte_kni/Makefile                       |   1 +
 lib/librte_kni/meson.build                    |   1 +
 lib/librte_latencystats/Makefile              |   1 +
 lib/librte_latencystats/meson.build           |   1 +
 lib/librte_mempool/Makefile                   |   3 +
 lib/librte_mempool/mempool_trace_points.c     | 108 +++
 lib/librte_mempool/meson.build                |   7 +-
 lib/librte_mempool/rte_mempool.c              |  16 +
 lib/librte_mempool/rte_mempool.h              |  13 +
 lib/librte_mempool/rte_mempool_ops.c          |   7 +
 lib/librte_mempool/rte_mempool_version.map    |  26 +
 lib/librte_mempool/rte_trace_mempool.h        | 148 +++++
 lib/librte_mempool/rte_trace_mempool_fp.h     | 102 +++
 lib/librte_port/Makefile                      |   1 +
 lib/librte_port/meson.build                   |   1 +
 lib/librte_reorder/Makefile                   |   1 +
 lib/librte_reorder/meson.build                |   1 +
 lib/librte_sched/Makefile                     |   1 +
 lib/librte_sched/meson.build                  |   1 +
 lib/librte_security/Makefile                  |   1 +
 lib/librte_security/meson.build               |   1 +
 lib/librte_table/Makefile                     |   1 +
 lib/librte_table/meson.build                  |   1 +
 260 files changed, 6271 insertions(+), 82 deletions(-)
 create mode 100644 app/test/test_trace.c
 create mode 100644 app/test/test_trace.h
 create mode 100644 app/test/test_trace_perf.c
 create mode 100644 app/test/test_trace_register.c
 create mode 100644 doc/guides/prog_guide/trace_lib.rst
 create mode 100644 lib/librte_cryptodev/cryptodev_trace_points.c
 create mode 100644 lib/librte_cryptodev/rte_trace_cryptodev.h
 create mode 100644 lib/librte_cryptodev/rte_trace_cryptodev_fp.h
 create mode 100644 lib/librte_eal/common/eal_common_trace.c
 create mode 100644 lib/librte_eal/common/eal_common_trace_ctf.c
 create mode 100644 lib/librte_eal/common/eal_common_trace_points.c
 create mode 100644 lib/librte_eal/common/eal_common_trace_utils.c
 create mode 100644 lib/librte_eal/common/eal_trace.h
 create mode 100644 lib/librte_eal/common/include/rte_trace.h
 create mode 100644 lib/librte_eal/common/include/rte_trace_eal.h
 create mode 100644 lib/librte_eal/common/include/rte_trace_provider.h
 create mode 100644 lib/librte_eal/common/include/rte_trace_register.h
 create mode 100644 lib/librte_ethdev/ethdev_trace_points.c
 create mode 100644 lib/librte_ethdev/rte_trace_ethdev.h
 create mode 100644 lib/librte_ethdev/rte_trace_ethdev_fp.h
 create mode 100644 lib/librte_eventdev/eventdev_trace_points.c
 create mode 100644 lib/librte_eventdev/rte_trace_eventdev.h
 create mode 100644 lib/librte_eventdev/rte_trace_eventdev_fp.h
 create mode 100644 lib/librte_mempool/mempool_trace_points.c
 create mode 100644 lib/librte_mempool/rte_trace_mempool.h
 create mode 100644 lib/librte_mempool/rte_trace_mempool_fp.h

-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 01/32] eal: introduce API for getting thread name
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 02/32] eal: define the public API for trace support jerinj
                     ` (31 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom, skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Introduce rte_thread_getname() API to get the thread name
and implement it for Linux and FreeBSD.

FreeBSD does not support getting the thread name.

One of the consumers of this API will be the trace subsystem where
it used as an informative purpose.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/include/rte_lcore.h | 17 +++++++++++++++++
 lib/librte_eal/freebsd/eal/eal_thread.c   |  9 +++++++++
 lib/librte_eal/linux/eal/eal_thread.c     | 15 +++++++++++++++
 lib/librte_eal/rte_eal_version.map        |  3 +++
 4 files changed, 44 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_lcore.h b/lib/librte_eal/common/include/rte_lcore.h
index 476b8ef3a..339046bc8 100644
--- a/lib/librte_eal/common/include/rte_lcore.h
+++ b/lib/librte_eal/common/include/rte_lcore.h
@@ -240,6 +240,23 @@ void rte_thread_get_affinity(rte_cpuset_t *cpusetp);
  */
 int rte_thread_setname(pthread_t id, const char *name);
 
+/**
+ * Get thread name.
+ *
+ * @note It fails with glibc < 2.12.
+ *
+ * @param id
+ *   Thread id.
+ * @param name
+ *   Thread name to set.
+ * @param len
+ *   Thread name buffer length.
+ * @return
+ *   On success, return 0; otherwise return a negative value.
+ */
+__rte_experimental
+int rte_thread_getname(pthread_t id, char *name, size_t len);
+
 /**
  * Create a control thread.
  *
diff --git a/lib/librte_eal/freebsd/eal/eal_thread.c b/lib/librte_eal/freebsd/eal/eal_thread.c
index 309b58726..ae7b57672 100644
--- a/lib/librte_eal/freebsd/eal/eal_thread.c
+++ b/lib/librte_eal/freebsd/eal/eal_thread.c
@@ -175,3 +175,12 @@ int rte_thread_setname(pthread_t id, const char *name)
 	pthread_set_name_np(id, name);
 	return 0;
 }
+
+int rte_thread_getname(pthread_t id, char *name, size_t len)
+{
+	RTE_SET_USED(id);
+	RTE_SET_USED(name);
+	RTE_SET_USED(len);
+
+	return -ENOTSUP;
+}
diff --git a/lib/librte_eal/linux/eal/eal_thread.c b/lib/librte_eal/linux/eal/eal_thread.c
index 379773b68..3f82b286c 100644
--- a/lib/librte_eal/linux/eal/eal_thread.c
+++ b/lib/librte_eal/linux/eal/eal_thread.c
@@ -186,3 +186,18 @@ int rte_thread_setname(pthread_t id, const char *name)
 	RTE_SET_USED(name);
 	return -ret;
 }
+
+int rte_thread_getname(pthread_t id, char *name, size_t len)
+{
+	int ret = ENOSYS;
+#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
+#if __GLIBC_PREREQ(2, 12)
+	ret = pthread_getname_np(id, name, len);
+#endif
+#endif
+	RTE_SET_USED(id);
+	RTE_SET_USED(name);
+	RTE_SET_USED(len);
+	return -ret;
+
+}
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 6cf507068..cadfa6465 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -335,4 +335,7 @@ EXPERIMENTAL {
 
 	# added in 20.02
 	rte_thread_is_intr;
+
+	# added in 20.05
+	rte_thread_getname;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 02/32] eal: define the public API for trace support
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 01/32] eal: introduce API for getting thread name jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 03/32] eal/trace: implement trace register API jerinj
                     ` (30 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  To: Thomas Monjalon, Bruce Richardson, John McNamara, Marko Kovacevic
  Cc: dev, david.marchand, mattias.ronnblom, skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Define the public API for trace support.
This patch also adds support for the build infrastructure and
update the MAINTAINERS file for the trace subsystem.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 MAINTAINERS                               |   6 +
 config/common_base                        |   1 +
 config/rte_config.h                       |   1 +
 doc/api/doxy-api-index.md                 |   3 +-
 lib/librte_eal/common/Makefile            |   1 +
 lib/librte_eal/common/eal_common_trace.c  |   6 +
 lib/librte_eal/common/include/rte_trace.h | 522 ++++++++++++++++++++++
 lib/librte_eal/common/meson.build         |   2 +
 lib/librte_eal/freebsd/eal/Makefile       |   1 +
 lib/librte_eal/linux/eal/Makefile         |   1 +
 10 files changed, 543 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/common/eal_common_trace.c
 create mode 100644 lib/librte_eal/common/include/rte_trace.h

diff --git a/MAINTAINERS b/MAINTAINERS
index db235c2cc..7ce224330 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -196,6 +196,12 @@ F: app/test/test_string_fns.c
 F: app/test/test_tailq.c
 F: app/test/test_version.c
 
+Trace
+M: Jerin Jacob <jerinj@marvell.com>
+M: Sunil Kumar Kori <skori@marvell.com>
+F: lib/librte_eal/common/include/rte_trace*.h
+F: lib/librte_eal/common/eal_common_trace*.c
+
 Memory Allocation
 M: Anatoly Burakov <anatoly.burakov@intel.com>
 F: lib/librte_eal/common/include/rte_fbarray.h
diff --git a/config/common_base b/config/common_base
index c31175f9d..a3508d1f2 100644
--- a/config/common_base
+++ b/config/common_base
@@ -99,6 +99,7 @@ CONFIG_RTE_MAX_MEMZONE=2560
 CONFIG_RTE_MAX_TAILQ=32
 CONFIG_RTE_ENABLE_ASSERT=n
 CONFIG_RTE_LOG_DP_LEVEL=RTE_LOG_INFO
+CONFIG_RTE_ENABLE_TRACE_DP=n
 CONFIG_RTE_LOG_HISTORY=256
 CONFIG_RTE_BACKTRACE=y
 CONFIG_RTE_LIBEAL_USE_HPET=n
diff --git a/config/rte_config.h b/config/rte_config.h
index d30786bc0..6b250288c 100644
--- a/config/rte_config.h
+++ b/config/rte_config.h
@@ -42,6 +42,7 @@
 #define RTE_MAX_MEMZONE 2560
 #define RTE_MAX_TAILQ 32
 #define RTE_LOG_DP_LEVEL RTE_LOG_INFO
+#define RTE_ENABLE_TRACE_DP 0
 #define RTE_BACKTRACE 1
 #define RTE_MAX_VFIO_CONTAINERS 64
 
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index dff496be0..190f0ccc2 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -174,7 +174,8 @@ The public API headers are grouped by topics:
   [hexdump]            (@ref rte_hexdump.h),
   [debug]              (@ref rte_debug.h),
   [log]                (@ref rte_log.h),
-  [errno]              (@ref rte_errno.h)
+  [errno]              (@ref rte_errno.h),
+  [trace]              (@ref rte_trace.h)
 
 - **misc**:
   [EAL config]         (@ref rte_eal.h),
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index c2c6d92cd..9384d6f6e 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -9,6 +9,7 @@ INC += rte_debug.h rte_eal.h rte_eal_interrupts.h
 INC += rte_errno.h rte_launch.h rte_lcore.h
 INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
+INC += rte_trace.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h
diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
new file mode 100644
index 000000000..e18ba1c95
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#include <rte_trace.h>
+
diff --git a/lib/librte_eal/common/include/rte_trace.h b/lib/librte_eal/common/include/rte_trace.h
new file mode 100644
index 000000000..459374d86
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_trace.h
@@ -0,0 +1,522 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_H_
+#define _RTE_TRACE_H_
+
+/**
+ * @file
+ *
+ * RTE Trace API
+ *
+ * This file provides the trace API to RTE applications.
+ *
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <rte_common.h>
+#include <rte_compat.h>
+
+/** The trace object. The trace APIs are based on this opaque object. */
+typedef uint64_t rte_trace_t;
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Enumerate trace mode operation.
+ */
+enum rte_trace_mode {
+	/**
+	 * In this mode, When no space left in trace buffer, the subsequent
+	 * events overwrite the old events in the trace buffer.
+	 */
+	RTE_TRACE_MODE_OVERWRITE,
+	/**
+	 * In this mode, When no space left on trace buffer, the subsequent
+	 * events shall not be recorded in the trace buffer.
+	 */
+	RTE_TRACE_MODE_DISCARD,
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Test if global trace is enabled.
+ *
+ * @return
+ *    true if global trace is enabled, false otherwise.
+ */
+__rte_experimental
+bool rte_trace_global_is_enabled(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Test if global trace is disabled.
+ *
+ * @return
+ *    true if global trace is disabled, false otherwise.
+ */
+__rte_experimental
+bool rte_trace_global_is_disabled(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Test if a given trace is invalid.
+ * @param trace
+ *    The trace object.
+ * @return
+ *    true if global trace is invalid, false otherwise.
+ */
+__rte_experimental
+bool rte_trace_is_id_invalid(rte_trace_t *trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Set the global trace level.
+ *
+ * After this call, trace with a level lower or equal than the level
+ * passed as argument will be captured in the trace buffer.
+ *
+ * @param level
+ *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ */
+__rte_experimental
+void rte_trace_global_level_set(uint32_t level);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Get the global trace level.
+ *
+ * @return
+ *   The current global trace level.
+ */
+__rte_experimental
+uint32_t rte_trace_global_level_get(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Set the global trace mode.
+ *
+ * After this call, All tracepoints will be switched to new mode.
+ *
+ * @param mode
+ *   Trace mode.
+ */
+__rte_experimental
+void rte_trace_global_mode_set(enum rte_trace_mode mode);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Get the global trace mode.
+ *
+ * @return
+ *   The current global trace mode.
+ */
+__rte_experimental
+enum rte_trace_mode rte_trace_global_mode_get(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Enable recording of the given tracepoint in the trace buffer.
+ *
+ * @param trace
+ *   The tracepoint object to enable.
+ * @return
+ *   - 0: Success.
+ *   - (-ERANGE): Trace object is not registered.
+ *   - (-EACCES): Trace object level is less than the global trace level.
+ */
+__rte_experimental
+int rte_trace_enable(rte_trace_t *trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Disable recording of the given tracepoint in the trace buffer.
+ *
+ * @param trace
+ *   The tracepoint object to disable.
+ * @return
+ *   - 0: Success.
+ *   - (-ERANGE): Trace object is not registered.
+ */
+__rte_experimental
+int rte_trace_disable(rte_trace_t *trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Test if given trace is enabled.
+ *
+ * @param trace
+ *    The trace object.
+ * @return
+ *    true if trace is enabled, false otherwise.
+ */
+__rte_experimental
+bool rte_trace_is_enabled(rte_trace_t *trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Test if given trace is disabled.
+ *
+ * @param trace
+ *    The trace object.
+ * @return
+ *    true if trace is disabled, false otherwise.
+ */
+__rte_experimental
+bool rte_trace_is_disabled(rte_trace_t *trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Set the trace level for the given tracepoint.
+ *
+ * After this call, if passed trace level lower or equal than the global trace
+ * level and this trace is enabled then trace will be captured in the
+ * trace buffer.
+ *
+ * @param trace
+ *    The trace object.
+ * @param level
+ *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ * @return
+ *   - 0: Success.
+ *   - (-EINVAL): Trace object is not registered or invalid trace level.
+ */
+__rte_experimental
+int rte_trace_level_set(rte_trace_t *trace, uint32_t level);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Get the trace level for the given tracepoint.
+ *
+ * @param trace
+ *    The trace object.
+ * @return
+ *   - A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ *   - 0: Trace object is not registered.
+ */
+__rte_experimental
+uint32_t rte_trace_level_get(rte_trace_t *trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Set the trace mode for the given tracepoint.
+ *
+ * @param trace
+ *    The trace object.
+ * @param mode
+ *   Trace mode.
+ * @return
+ *   - 0: Success.
+ *   - (-EINVAL): Trace object is not registered or invalid trace level.
+ */
+__rte_experimental
+int rte_trace_mode_set(rte_trace_t *trace, enum rte_trace_mode mode);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Get the trace mode for the given tracepoint.
+ *
+ * @param trace
+ *    The trace object.
+ * @return
+ *   - Zero or positive: Mode encoded as enum rte_trace_mode.
+ *   - (-EINVAL): Trace object is not registered.
+ */
+__rte_experimental
+int rte_trace_mode_get(rte_trace_t *trace);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Enable/Disable a set of tracepoints based on shell pattern.
+ *
+ * @param pattern
+ *   The match pattern identifying the tracepoint.
+ * @param enable
+ *    true to enable tracepoint, false to disable the tracepoint, upon match.
+ * @return
+ *   - 0: Success and no pattern match.
+ *   - 1: Success and found pattern match.
+ *   - (-ERANGE): Trace object is not registered.
+ */
+__rte_experimental
+int rte_trace_pattern(const char *pattern, bool enable);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Enable/Disable a set of tracepoints based on regular expression.
+ *
+ * @param regex
+ *   A regular expression identifying the tracepoint.
+ * @param enable
+ *    true to enable tracepoint, false to disable the tracepoint, upon match.
+ * @return
+ *   - 0: Success.
+ *   - (-ERANGE): Trace object is not registered.
+ *   - (-EINVAL): Invalid regular expression rule.
+ */
+__rte_experimental
+int rte_trace_regexp(const char *regex, bool enable);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Save the trace buffer to the trace directory.
+ *
+ * By default, trace directory will be created at HOME directory and this can be
+ * overridden by --trace-dir EAL parameter.
+ *
+ * @return
+ *   - 0: Success.
+ *   - <0 : Failure.
+ */
+__rte_experimental
+int rte_trace_save(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Search a trace object from its name.
+ *
+ * @param name
+ *   The name of the tracepoint.
+ * @return
+ *   The tracepoint object or NULL if not found.
+ */
+__rte_experimental
+rte_trace_t *rte_trace_by_name(const char *name);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Dump the trace metadata to a file.
+ *
+ * @param f
+ *   A pointer to a file for output
+ * @return
+ *   - 0: Success.
+ *   - <0 : Failure.
+ */
+__rte_experimental
+int rte_trace_metadata_dump(FILE *f);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ * Dump the trace subsystem status to a file.
+ *
+ * @param f
+ *   A pointer to a file for output
+ */
+__rte_experimental
+void rte_trace_dump(FILE *f);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Test if the trace datapath compile-time option is enabled.
+ *
+ * @return
+ *   true if trace datapath enabled, false otherwise.
+ */
+static __rte_always_inline bool
+rte_trace_is_dp_enabled(void)
+{
+#ifdef RTE_ENABLE_TRACE_DP
+	return RTE_ENABLE_TRACE_DP;
+#else
+	return false;
+#endif
+}
+
+/** Macro to define the tracepoint. */
+#define RTE_TRACE_POINT_DEFINE(tp)\
+rte_trace_t __attribute__((section("__rte_trace_point"))) __##tp
+
+/**
+ * Macro to define the tracepoint arguments in RTE_TRACE_POINT macro.
+
+ * @see RTE_TRACE_POINT RTE_TRACE_POINT_DP
+ */
+#define RTE_TRACE_POINT_ARGS
+
+/** @internal Helper Macro to support RTE_TRACE_POINT and RTE_TRACE_POINT_DP */
+#define __RTE_TRACE_POINT(_mode, _tp, _args, ...)\
+extern rte_trace_t __##_tp;\
+static __rte_always_inline void \
+_tp _args \
+{\
+	__rte_trace_emit_header_##_mode(&__##_tp);\
+	__VA_ARGS__\
+}
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Create a tracepoint definition.
+ *
+ * A tracepoint definition defines, for a given tracepoint:
+ * - Its input arguments. They are the C function style parameters to define
+ * the arguments of tracepoint function. These input arguments embedded using
+ * RTE_TRACE_POINT_ARGS macro.
+ * - Its output event fields. They are the sources of event fields that form
+ * the payload of any event that the execution of the tracepoint macro emits
+ * for this particular tracepoint. The application uses rte_trace_ctf_* macros
+ * to emit the output event fields.
+ *
+ * @param tp
+ *   Tracepoint object. Before using the tracepoint, an application needs to
+ * define the tracepoint using RTE_TRACE_POINT_DEFINE() macro.
+ * @param args
+ *   C function style input arguments to define the arguments to tracepoint
+ * function.
+ * @param ...
+ *   Define the payload of trace function. The payload will be formed using
+ * rte_trace_ctf_* macros, Use ";" delimiter between two payloads.
+ *
+ * @see RTE_TRACE_POINT_ARGS, RTE_TRACE_POINT_DEFINE, rte_trace_ctf_*
+ */
+#define RTE_TRACE_POINT(tp, args, ...)\
+	__RTE_TRACE_POINT(generic, tp, args, __VA_ARGS__)
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Create a tracepoint definition for the data path.
+ *
+ * Similar to RTE_TRACE_POINT(), except that it is removed at compilation time
+ * using RTE_ENABLE_TRACE_DP configuration parameter.
+ *
+ * @param tp
+ *   Tracepoint object. Before using the tracepoint, an application needs to
+ * define the tracepoint using RTE_TRACE_POINT_DEFINE() macro.
+ * @param args
+ *   C function style input arguments to define the arguments to tracepoint
+ * function.
+ * @param ...
+ *   Define the payload of trace function. The payload will be formed using
+ * rte_trace_ctf_* macros, Use ";" delimiter between two payloads.
+ *
+ * @see rte_trace_is_dp_enabled, RTE_TRACE_POINT()
+ */
+#define RTE_TRACE_POINT_DP(tp, args, ...)\
+	__RTE_TRACE_POINT(dp, tp, args, __VA_ARGS__)
+
+#ifdef __DOXYGEN__
+
+/**
+ * Macro to select rte_trace_ctf_* definition for trace register function.
+ *
+ * rte_trace_ctf_* emits different definitions for trace function.
+ * Application must define RTE_TRACE_POINT_REGISTER_SELECT before including
+ * rte_trace.h in the C file where RTE_TRACE_POINT_REGISTER() used.
+ *
+ * @see RTE_TRACE_POINT_REGISTER()
+ */
+#define RTE_TRACE_POINT_REGISTER_SELECT
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Register a dynamic tracepoint.
+ *
+ * @param trace
+ *   The tracepoint object created using RTE_TRACE_POINT_DEFINE().
+ * @param name
+ *   The name of the tracepoint object.
+ * @param level
+ *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ * @return
+ *   - 0: Successfully registered the tracepoint.
+ *   - <0: Failure to register the tracepoint.
+ *
+ * @see RTE_TRACE_POINT_REGISTER_SELECT
+ */
+#define RTE_TRACE_POINT_REGISTER(trace, name, level)
+
+/** Tracepoint function payload for uint64_t datatype */
+#define rte_trace_ctf_u64(val)
+/** Tracepoint function payload for int64_t datatype */
+#define rte_trace_ctf_i64(val)
+/** Tracepoint function payload for uint32_t datatype */
+#define rte_trace_ctf_u32(val)
+/** Tracepoint function payload for int32_t datatype */
+#define rte_trace_ctf_i32(val)
+/** Tracepoint function payload for uint16_t datatype */
+#define rte_trace_ctf_u16(val)
+/** Tracepoint function payload for int16_t datatype */
+#define rte_trace_ctf_i16(val)
+/** Tracepoint function payload for uint8_t datatype */
+#define rte_trace_ctf_u8(val)
+/** Tracepoint function payload for int8_t datatype */
+#define rte_trace_ctf_i8(val)
+/** Tracepoint function payload for int datatype */
+#define rte_trace_ctf_int(val)
+/** Tracepoint function payload for long datatype */
+#define rte_trace_ctf_long(val)
+/** Tracepoint function payload for float datatype */
+#define rte_trace_ctf_float(val)
+/** Tracepoint function payload for double datatype */
+#define rte_trace_ctf_double(val)
+/** Tracepoint function payload for pointer datatype */
+#define rte_trace_ctf_ptr(val)
+/** Tracepoint function payload for string datatype */
+#define rte_trace_ctf_string(val)
+
+#endif /* __DOXYGEN__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TRACE_H_ */
diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
index 2b97715a2..30fb9b85f 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -28,6 +28,7 @@ common_sources = files(
 	'eal_common_tailqs.c',
 	'eal_common_thread.c',
 	'eal_common_timer.c',
+	'eal_common_trace.c',
 	'eal_common_uuid.c',
 	'hotplug_mp.c',
 	'malloc_elem.c',
@@ -84,6 +85,7 @@ common_headers = files(
 	'include/rte_service_component.h',
 	'include/rte_string_fns.h',
 	'include/rte_tailq.h',
+	'include/rte_trace.h',
 	'include/rte_time.h',
 	'include/rte_uuid.h',
 	'include/rte_version.h',
diff --git a/lib/librte_eal/freebsd/eal/Makefile b/lib/librte_eal/freebsd/eal/Makefile
index b160b5790..b2fcc4212 100644
--- a/lib/librte_eal/freebsd/eal/Makefile
+++ b/lib/librte_eal/freebsd/eal/Makefile
@@ -60,6 +60,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += malloc_elem.c
diff --git a/lib/librte_eal/linux/eal/Makefile b/lib/librte_eal/linux/eal/Makefile
index e70cf104a..95470d3bb 100644
--- a/lib/librte_eal/linux/eal/Makefile
+++ b/lib/librte_eal/linux/eal/Makefile
@@ -68,6 +68,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += malloc_elem.c
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 03/32] eal/trace: implement trace register API
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 01/32] eal: introduce API for getting thread name jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 02/32] eal: define the public API for trace support jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 04/32] eal/trace: implement trace operation APIs jerinj
                     ` (29 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, bruce.richardson, david.marchand, mattias.ronnblom, skori,
	Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

The consumers of trace API defines the tracepoint and registers
to eal. Internally these tracepoints will be stored in STAILQ
for future use. This patch implements the tracepoint
registration function.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 MAINTAINERS                                   |   1 +
 lib/librte_eal/common/Makefile                |   2 +-
 lib/librte_eal/common/eal_common_trace.c      | 107 +++++++++++++++++-
 lib/librte_eal/common/eal_trace.h             |  36 ++++++
 lib/librte_eal/common/include/rte_trace.h     |  29 +++++
 .../common/include/rte_trace_provider.h       |  24 ++++
 .../common/include/rte_trace_register.h       |  20 ++++
 lib/librte_eal/common/meson.build             |   2 +
 lib/librte_eal/rte_eal_version.map            |   1 +
 9 files changed, 220 insertions(+), 2 deletions(-)
 create mode 100644 lib/librte_eal/common/eal_trace.h
 create mode 100644 lib/librte_eal/common/include/rte_trace_provider.h
 create mode 100644 lib/librte_eal/common/include/rte_trace_register.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 7ce224330..cdaed3f5a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -201,6 +201,7 @@ M: Jerin Jacob <jerinj@marvell.com>
 M: Sunil Kumar Kori <skori@marvell.com>
 F: lib/librte_eal/common/include/rte_trace*.h
 F: lib/librte_eal/common/eal_common_trace*.c
+F: lib/librte_eal/common/eal_trace.h
 
 Memory Allocation
 M: Anatoly Burakov <anatoly.burakov@intel.com>
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 9384d6f6e..8f2f25c1d 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -9,7 +9,7 @@ INC += rte_debug.h rte_eal.h rte_eal_interrupts.h
 INC += rte_errno.h rte_launch.h rte_lcore.h
 INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
-INC += rte_trace.h
+INC += rte_trace.h rte_trace_provider.h rte_trace_register.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h
diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index e18ba1c95..a8890345b 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -2,5 +2,110 @@
  * Copyright(C) 2020 Marvell International Ltd.
  */
 
-#include <rte_trace.h>
+#include <inttypes.h>
+#include <sys/queue.h>
 
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_lcore.h>
+#include <rte_per_lcore.h>
+#include <rte_string_fns.h>
+
+#include "eal_trace.h"
+
+RTE_DEFINE_PER_LCORE(volatile int, trace_point_sz);
+RTE_DEFINE_PER_LCORE(char, ctf_field[TRACE_CTF_FIELD_SIZE]);
+RTE_DEFINE_PER_LCORE(int, ctf_count);
+
+static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
+static struct trace trace;
+
+int
+__rte_trace_point_register(rte_trace_t *handle, const char *name,
+			   uint32_t level, void (*register_fn)(void))
+{
+	char *field = RTE_PER_LCORE(ctf_field);
+	struct trace_point *tp;
+	uint16_t sz;
+
+	/* Sanity checks of arguments */
+	if (name == NULL || register_fn == NULL || handle == NULL) {
+		trace_err("invalid arguments");
+		rte_errno = EINVAL; goto fail;
+	}
+
+	/* Sanity check of level */
+	if (level > RTE_LOG_DEBUG || level > UINT8_MAX) {
+		trace_err("invalid log level=%d", level);
+		rte_errno = EINVAL; goto fail;
+
+	}
+
+	/* Check the size of the trace point object */
+	RTE_PER_LCORE(trace_point_sz) = 0;
+	RTE_PER_LCORE(ctf_count) = 0;
+	register_fn();
+	if (RTE_PER_LCORE(trace_point_sz) == 0) {
+		trace_err("missing rte_trace_emit_header() in register fn");
+		rte_errno = EBADF; goto fail;
+	}
+
+	/* Is size overflowed */
+	if (RTE_PER_LCORE(trace_point_sz) > UINT16_MAX) {
+		trace_err("trace point size overflowed");
+		rte_errno = ENOSPC; goto fail;
+	}
+
+	/* Are we running out of space to store trace points? */
+	if (trace.nb_trace_points > UINT16_MAX) {
+		trace_err("trace point exceeds the max count");
+		rte_errno = ENOSPC; goto fail;
+	}
+
+	/* Get the size of the trace point */
+	sz = RTE_PER_LCORE(trace_point_sz);
+	tp = calloc(1, sizeof(struct trace_point));
+	if (tp == NULL) {
+		trace_err("fail to allocate trace point memory");
+		rte_errno = ENOMEM; goto fail;
+	}
+
+	/* Initialize the trace point */
+	if (rte_strscpy(tp->name, name, TRACE_POINT_NAME_SIZE) < 0) {
+		trace_err("name is too long");
+		rte_errno = E2BIG;
+		goto free;
+	}
+
+	/* Copy the field data for future use */
+	if (rte_strscpy(tp->ctf_field, field, TRACE_CTF_FIELD_SIZE) < 0) {
+		trace_err("CTF field size is too long");
+		rte_errno = E2BIG;
+		goto free;
+	}
+
+	/* Clear field memory for the next event */
+	memset(field, 0, TRACE_CTF_FIELD_SIZE);
+
+	/* Form the trace handle */
+	*handle = sz;
+	*handle |= trace.nb_trace_points << __RTE_TRACE_FIELD_ID_SHIFT;
+	*handle |= (uint64_t)level << __RTE_TRACE_FIELD_LEVEL_SHIFT;
+
+	trace.nb_trace_points++;
+	tp->handle = handle;
+
+	/* Add the trace point at tail */
+	STAILQ_INSERT_TAIL(&tp_list, tp, next);
+	__atomic_thread_fence(__ATOMIC_RELEASE);
+
+	/* All Good !!! */
+	return 0;
+free:
+	free(tp);
+fail:
+	if (trace.register_errno == 0)
+		trace.register_errno = rte_errno;
+
+	return -rte_errno;
+}
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
new file mode 100644
index 000000000..7665bd6be
--- /dev/null
+++ b/lib/librte_eal/common/eal_trace.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef __EAL_TRACE_H
+#define __EAL_TRACE_H
+
+#include <rte_trace.h>
+
+#define trace_err(fmt, args...)\
+	RTE_LOG(ERR, EAL, "%s():%u " fmt "\n",\
+		__func__, __LINE__, ## args)
+
+#define trace_crit(fmt, args...)\
+	RTE_LOG(CRIT, EAL, "%s():%u " fmt "\n",\
+		__func__, __LINE__, ## args)
+
+#define TRACE_CTF_FIELD_SIZE 384
+#define TRACE_POINT_NAME_SIZE 64
+
+struct trace_point {
+	STAILQ_ENTRY(trace_point) next;
+	rte_trace_t *handle;
+	char name[TRACE_POINT_NAME_SIZE];
+	char ctf_field[TRACE_CTF_FIELD_SIZE];
+};
+
+struct trace {
+	int register_errno;
+	uint32_t nb_trace_points;
+};
+
+/* Trace point list functions */
+STAILQ_HEAD(trace_point_head, trace_point);
+
+#endif /* __EAL_TRACE_H */
diff --git a/lib/librte_eal/common/include/rte_trace.h b/lib/librte_eal/common/include/rte_trace.h
index 459374d86..90b9d5894 100644
--- a/lib/librte_eal/common/include/rte_trace.h
+++ b/lib/librte_eal/common/include/rte_trace.h
@@ -515,6 +515,35 @@ _tp _args \
 
 #endif /* __DOXYGEN__ */
 
+/**
+ * @internal @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Helper function to register a dynamic tracepoint.
+ * Use RTE_TRACE_POINT_REGISTER() macro for tracepoint registration.
+ *
+ * @param trace
+ *   The tracepoint object created using RTE_TRACE_POINT_DEFINE().
+ * @param name
+ *   The name of the tracepoint object.
+ * @param level
+ *   Trace level. A value between RTE_LOG_EMERG (1) and RTE_LOG_DEBUG (8).
+ * @param register_fn
+ *   Trace registration function.
+ * @return
+ *   - 0: Successfully registered the tracepoint.
+ *   - <0: Failure to register the tracepoint.
+ */
+__rte_experimental
+int __rte_trace_point_register(rte_trace_t *trace, const char *name,
+			     uint32_t level, void (*register_fn)(void));
+
+#ifdef RTE_TRACE_POINT_REGISTER_SELECT
+#include <rte_trace_register.h>
+#else
+#include <rte_trace_provider.h>
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/common/include/rte_trace_provider.h b/lib/librte_eal/common/include/rte_trace_provider.h
new file mode 100644
index 000000000..b4da87ba1
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_trace_provider.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_H_
+#error do not include this file directly, use <rte_trace.h> instead
+#endif
+
+#ifndef _RTE_TRACE_PROVIDER_H_
+#define _RTE_TRACE_PROVIDER_H_
+
+#define __RTE_TRACE_EVENT_HEADER_ID_SHIFT (48)
+
+#define __RTE_TRACE_FIELD_ENABLE_MASK (1ULL << 63)
+#define __RTE_TRACE_FIELD_ENABLE_DISCARD (1ULL << 62)
+#define __RTE_TRACE_FIELD_SIZE_SHIFT 0
+#define __RTE_TRACE_FIELD_SIZE_MASK (0xffffULL << __RTE_TRACE_FIELD_SIZE_SHIFT)
+#define __RTE_TRACE_FIELD_ID_SHIFT (16)
+#define __RTE_TRACE_FIELD_ID_MASK (0xffffULL << __RTE_TRACE_FIELD_ID_SHIFT)
+#define __RTE_TRACE_FIELD_LEVEL_SHIFT (32)
+#define __RTE_TRACE_FIELD_LEVEL_MASK (0xffULL << __RTE_TRACE_FIELD_LEVEL_SHIFT)
+
+
+#endif /* _RTE_TRACE_PROVIDER_H_ */
diff --git a/lib/librte_eal/common/include/rte_trace_register.h b/lib/librte_eal/common/include/rte_trace_register.h
new file mode 100644
index 000000000..e9940b414
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_trace_register.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_H_
+#error do not include this file directly, use <rte_trace.h> instead
+#endif
+
+#ifndef _RTE_TRACE_REGISTER_H_
+#define _RTE_TRACE_REGISTER_H_
+
+#include <rte_per_lcore.h>
+
+RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz);
+
+#define RTE_TRACE_POINT_REGISTER(trace, name, level)\
+	__rte_trace_point_register(&__##trace, RTE_STR(name),\
+			RTE_LOG_ ## level, (void (*)(void)) trace)
+
+#endif /* _RTE_TRACE_REGISTER_H_ */
diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
index 30fb9b85f..88c14ebe5 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -86,6 +86,8 @@ common_headers = files(
 	'include/rte_string_fns.h',
 	'include/rte_tailq.h',
 	'include/rte_trace.h',
+	'include/rte_trace_provider.h',
+	'include/rte_trace_register.h',
 	'include/rte_time.h',
 	'include/rte_uuid.h',
 	'include/rte_version.h',
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index cadfa6465..d97d14845 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -338,4 +338,5 @@ EXPERIMENTAL {
 
 	# added in 20.05
 	rte_thread_getname;
+	__rte_trace_point_register;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 04/32] eal/trace: implement trace operation APIs
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (2 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 03/32] eal/trace: implement trace register API jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 05/32] eal/trace: add internal trace init and fini interface jerinj
                     ` (28 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

This patch implements the following public trace APIs.

- rte_trace_global_is_enabled()
- rte_trace_global_is_disabled()
- rte_trace_is_id_invalid()
- rte_trace_global_level_set()
- rte_trace_global_level_get()
- rte_trace_global_mode_set()
- rte_trace_global_mode_get()
- rte_trace_enable()
- rte_trace_disable()
- rte_trace_is_enabled()
- rte_trace_is_disabled()
- rte_trace_level_set()
- rte_trace_level_get()
- rte_trace_mode_set()
- rte_trace_mode_get()
- rte_trace_pattern()
- rte_trace_regexp()
- rte_trace_by_name()

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c | 243 +++++++++++++++++++++++
 lib/librte_eal/common/eal_trace.h        |  11 +
 lib/librte_eal/rte_eal_version.map       |  18 ++
 3 files changed, 272 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index a8890345b..b5d6c842f 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -3,7 +3,9 @@
  */
 
 #include <inttypes.h>
+#include <fnmatch.h>
 #include <sys/queue.h>
+#include <regex.h>
 
 #include <rte_common.h>
 #include <rte_errno.h>
@@ -20,6 +22,247 @@ RTE_DEFINE_PER_LCORE(int, ctf_count);
 static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
 static struct trace trace;
 
+bool
+rte_trace_global_is_enabled(void)
+{
+	return trace.global_status;
+}
+
+bool
+rte_trace_global_is_disabled(void)
+{
+	return !trace.global_status;
+}
+
+void
+rte_trace_global_level_set(uint32_t level)
+{
+	struct trace_point *tp;
+
+	trace.level = level;
+
+	if (rte_trace_global_is_disabled())
+		return;
+
+	STAILQ_FOREACH(tp, &tp_list, next) {
+		if (level >= rte_trace_level_get(tp->handle))
+			rte_trace_enable(tp->handle);
+		else
+			rte_trace_disable(tp->handle);
+	}
+}
+
+uint32_t
+rte_trace_global_level_get(void)
+{
+	return trace.level;
+}
+
+void
+rte_trace_global_mode_set(enum rte_trace_mode mode)
+{
+	struct trace_point *tp;
+
+	if (rte_trace_global_is_disabled())
+		return;
+
+	STAILQ_FOREACH(tp, &tp_list, next)
+		rte_trace_mode_set(tp->handle, mode);
+
+	trace.mode = mode;
+}
+
+enum
+rte_trace_mode rte_trace_global_mode_get(void)
+{
+	return trace.mode;
+}
+
+bool
+rte_trace_is_id_invalid(rte_trace_t *t)
+{
+	if (trace_id_get(t) >= trace.nb_trace_points)
+		return true;
+
+	return false;
+}
+
+bool
+rte_trace_is_enabled(rte_trace_t *trace)
+{
+	uint64_t val;
+
+	if (rte_trace_is_id_invalid(trace))
+		return false;
+
+	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
+	return val & __RTE_TRACE_FIELD_ENABLE_MASK;
+}
+
+bool
+rte_trace_is_disabled(rte_trace_t *trace)
+{
+	uint64_t val;
+
+	if (rte_trace_is_id_invalid(trace))
+		return true;
+
+	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
+	return !(val & __RTE_TRACE_FIELD_ENABLE_MASK);
+}
+
+int
+rte_trace_enable(rte_trace_t *trace)
+{
+	if (rte_trace_is_id_invalid(trace))
+		return -ERANGE;
+
+	if (rte_trace_level_get(trace) > rte_trace_global_level_get())
+		return -EACCES;
+
+	__atomic_or_fetch(trace, __RTE_TRACE_FIELD_ENABLE_MASK,
+			  __ATOMIC_RELEASE);
+	return 0;
+}
+
+int
+rte_trace_disable(rte_trace_t *trace)
+{
+	if (rte_trace_is_id_invalid(trace))
+		return -ERANGE;
+
+	__atomic_and_fetch(trace, ~__RTE_TRACE_FIELD_ENABLE_MASK,
+			   __ATOMIC_RELEASE);
+	return 0;
+}
+
+uint32_t
+rte_trace_level_get(rte_trace_t *trace)
+{
+	uint64_t val;
+
+	if (rte_trace_is_id_invalid(trace))
+		return 0;
+
+	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
+	val &= __RTE_TRACE_FIELD_LEVEL_MASK;
+	val = val >> __RTE_TRACE_FIELD_LEVEL_SHIFT;
+
+	return val;
+}
+
+int
+rte_trace_level_set(rte_trace_t *trace, uint32_t level)
+{
+	uint64_t val;
+
+	if (rte_trace_is_id_invalid(trace) || level > RTE_LOG_DEBUG)
+		return -EINVAL;
+
+	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
+	val &= ~__RTE_TRACE_FIELD_LEVEL_MASK;
+	val |= (uint64_t)level << __RTE_TRACE_FIELD_LEVEL_SHIFT;
+	__atomic_store_n(trace, val, __ATOMIC_RELEASE);
+
+	if (level <= rte_trace_global_level_get())
+		rte_trace_enable(trace);
+	else
+		rte_trace_disable(trace);
+
+	return 0;
+}
+
+int
+rte_trace_mode_get(rte_trace_t *trace)
+{
+	uint64_t val;
+
+	if (rte_trace_is_id_invalid(trace))
+		return -EINVAL;
+
+	val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
+
+	return !!(val & __RTE_TRACE_FIELD_ENABLE_DISCARD);
+}
+
+int
+rte_trace_mode_set(rte_trace_t *trace, enum rte_trace_mode mode)
+{
+	if (rte_trace_is_id_invalid(trace) || mode >  RTE_TRACE_MODE_DISCARD)
+		return -EINVAL;
+
+	if (mode == RTE_TRACE_MODE_OVERWRITE)
+		__atomic_and_fetch(trace, ~__RTE_TRACE_FIELD_ENABLE_DISCARD,
+				   __ATOMIC_RELEASE);
+	else
+		__atomic_or_fetch(trace, __RTE_TRACE_FIELD_ENABLE_DISCARD,
+				   __ATOMIC_RELEASE);
+
+	return 0;
+}
+
+int
+rte_trace_pattern(const char *pattern, bool enable)
+{
+	struct trace_point *tp;
+	int rc = 0, found = 0;
+
+	STAILQ_FOREACH(tp, &tp_list, next) {
+		if (fnmatch(pattern, tp->name, 0) == 0) {
+			if (enable)
+				rc = rte_trace_enable(tp->handle);
+			else
+				rc = rte_trace_disable(tp->handle);
+			found = 1;
+		}
+		if (rc < 0)
+			return rc;
+	}
+
+	return rc | found;
+}
+
+int
+rte_trace_regexp(const char *regex, bool enable)
+{
+	struct trace_point *tp;
+	int rc = 0, found = 0;
+	regex_t r;
+
+	if (regcomp(&r, regex, 0) != 0)
+		return -EINVAL;
+
+	STAILQ_FOREACH(tp, &tp_list, next) {
+		if (regexec(&r, tp->name, 0, NULL, 0) == 0) {
+			if (enable)
+				rc = rte_trace_enable(tp->handle);
+			else
+				rc = rte_trace_disable(tp->handle);
+			found = 1;
+		}
+		if (rc < 0)
+			return rc;
+	}
+	regfree(&r);
+
+	return rc | found;
+}
+
+rte_trace_t *
+rte_trace_by_name(const char *name)
+{
+	struct trace_point *tp;
+
+	if (name == NULL)
+		return NULL;
+
+	STAILQ_FOREACH(tp, &tp_list, next)
+		if (strncmp(tp->name, name, TRACE_POINT_NAME_SIZE) == 0)
+			return tp->handle;
+
+	return NULL;
+}
+
 int
 __rte_trace_point_register(rte_trace_t *handle, const char *name,
 			   uint32_t level, void (*register_fn)(void))
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index 7665bd6be..e32e0821f 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -27,9 +27,20 @@ struct trace_point {
 
 struct trace {
 	int register_errno;
+	bool global_status;
+	enum rte_trace_mode mode;
+	uint32_t level;
 	uint32_t nb_trace_points;
 };
 
+/* Helper functions */
+static inline uint16_t
+trace_id_get(rte_trace_t *trace)
+{
+	return (*trace & __RTE_TRACE_FIELD_ID_MASK) >>
+		__RTE_TRACE_FIELD_ID_SHIFT;
+}
+
 /* Trace point list functions */
 STAILQ_HEAD(trace_point_head, trace_point);
 
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index d97d14845..ca1f2cc86 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -339,4 +339,22 @@ EXPERIMENTAL {
 	# added in 20.05
 	rte_thread_getname;
 	__rte_trace_point_register;
+	rte_trace_global_is_enabled;
+	rte_trace_global_is_disabled;
+	rte_trace_is_id_invalid;
+	rte_trace_global_level_set;
+	rte_trace_global_level_get;
+	rte_trace_global_mode_set;
+	rte_trace_global_mode_get;
+	rte_trace_enable;
+	rte_trace_disable;
+	rte_trace_is_enabled;
+	rte_trace_is_disabled;
+	rte_trace_level_set;
+	rte_trace_level_get;
+	rte_trace_mode_set;
+	rte_trace_mode_get;
+	rte_trace_pattern;
+	rte_trace_regexp;
+	rte_trace_by_name;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 05/32] eal/trace: add internal trace init and fini interface
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (3 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 04/32] eal/trace: implement trace operation APIs jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 06/32] eal/trace: get bootup timestamp for trace jerinj
                     ` (27 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom, skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Define eal_trace_init() and eal_trace_fini() EAL interface
functions that rte_eal_init() and rte_eal_cleanup() function can be
use to initialize and finalize the trace subsystem.
eal_trace_init() function will add the following
functionality if trace is enabled through EAL command line param.

- Test for trace registration failure.
- Test for duplicate trace name registration
- Generate UUID ver 4.
- Create a trace directory

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c      |  54 ++++++
 .../common/eal_common_trace_utils.c           | 173 ++++++++++++++++++
 lib/librte_eal/common/eal_trace.h             |  21 +++
 lib/librte_eal/common/meson.build             |   1 +
 lib/librte_eal/freebsd/eal/Makefile           |   1 +
 lib/librte_eal/linux/eal/Makefile             |   1 +
 6 files changed, 251 insertions(+)
 create mode 100644 lib/librte_eal/common/eal_common_trace_utils.c

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index b5d6c842f..50890fb5b 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -22,6 +22,60 @@ RTE_DEFINE_PER_LCORE(int, ctf_count);
 static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
 static struct trace trace;
 
+struct trace*
+trace_obj_get(void)
+{
+	return &trace;
+}
+
+struct trace_point_head *
+trace_list_head_get(void)
+{
+	return &tp_list;
+}
+
+int
+eal_trace_init(void)
+{
+	/* One of the Trace registration failed */
+	if (trace.register_errno) {
+		rte_errno = trace.register_errno;
+		goto fail;
+	}
+
+	if (rte_trace_global_is_disabled())
+		return 0;
+
+	rte_spinlock_init(&trace.lock);
+
+	/* Is duplicate trace name registered */
+	if (trace_has_duplicate_entry())
+		goto fail;
+
+	/* Generate UUID ver 4 with total size of events and number of events */
+	trace_uuid_generate();
+
+	/* Create trace directory */
+	if (trace_mkdir())
+		goto fail;
+
+
+	rte_trace_global_mode_set(trace.mode);
+
+	return 0;
+
+fail:
+	trace_err("failed to initialize trace [%s]", rte_strerror(rte_errno));
+	return -rte_errno;
+}
+
+void
+eal_trace_fini(void)
+{
+	if (rte_trace_global_is_disabled())
+		return;
+}
+
 bool
 rte_trace_global_is_enabled(void)
 {
diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
new file mode 100644
index 000000000..8df7b5c33
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -0,0 +1,173 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#include <fnmatch.h>
+#include <pwd.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_string_fns.h>
+
+#include "eal_filesystem.h"
+#include "eal_trace.h"
+
+static bool
+trace_entry_compare(const char *name)
+{
+	struct trace_point_head *tp_list = trace_list_head_get();
+	struct trace_point *tp;
+	int count = 0;
+
+	STAILQ_FOREACH(tp, tp_list, next) {
+		if (strncmp(tp->name, name, TRACE_POINT_NAME_SIZE) == 0)
+			count++;
+		if (count > 1) {
+			trace_err("found duplicate entry %s", name);
+			rte_errno = EEXIST;
+			return true;
+		}
+	}
+	return false;
+}
+
+bool
+trace_has_duplicate_entry(void)
+{
+	struct trace_point_head *tp_list = trace_list_head_get();
+	struct trace_point *tp;
+
+	/* Is duplicate trace name registered */
+	STAILQ_FOREACH(tp, tp_list, next)
+		if (trace_entry_compare(tp->name))
+			return true;
+
+	return false;
+}
+
+void
+trace_uuid_generate(void)
+{
+	struct trace_point_head *tp_list = trace_list_head_get();
+	struct trace *trace = trace_obj_get();
+	struct trace_point *tp;
+	uint64_t sz_total = 0;
+
+	/* Go over the registered trace points to get total size of events */
+	STAILQ_FOREACH(tp, tp_list, next) {
+		const uint16_t sz = *tp->handle & __RTE_TRACE_FIELD_SIZE_MASK;
+		sz_total += sz;
+	}
+
+	rte_uuid_t uuid = RTE_UUID_INIT(sz_total, trace->nb_trace_points,
+		0x4370, 0x8f50, 0x222ddd514176ULL);
+	rte_uuid_copy(trace->uuid, uuid);
+}
+
+static int
+trace_session_name_generate(char *trace_dir)
+{
+	struct tm *tm_result;
+	time_t tm;
+	int rc;
+
+	tm = time(NULL);
+	if ((int)tm == -1)
+		goto fail;
+
+	tm_result = localtime(&tm);
+	if (tm_result == NULL)
+		goto fail;
+
+	rc = rte_strscpy(trace_dir,
+			 eal_get_hugefile_prefix(), TRACE_PREFIX_LEN);
+	if (rc == -E2BIG)
+		rc = TRACE_PREFIX_LEN;
+	trace_dir[rc++] = '-';
+
+	rc = strftime(trace_dir + rc, TRACE_DIR_STR_LEN - rc,
+			"%Y-%m-%d-%p-%I-%M-%S", tm_result);
+	if (rc == 0)
+		goto fail;
+
+	return rc;
+fail:
+	rte_errno = errno;
+	return -rte_errno;
+}
+
+static int
+trace_dir_default_path_get(char *dir_path)
+{
+	struct trace *trace = trace_obj_get();
+	uint32_t size = sizeof(trace->dir);
+	struct passwd *pwd;
+	char *home_dir;
+
+	/* First check for shell environment variable */
+	home_dir = getenv("HOME");
+	if (home_dir == NULL) {
+		/* Fallback to password file entry */
+		pwd = getpwuid(getuid());
+		if (pwd == NULL)
+			return -EINVAL;
+
+		home_dir = pwd->pw_dir;
+	}
+
+	/* Append dpdk-traces to directory */
+	if (snprintf(dir_path, size, "%s/dpdk-traces/", home_dir) < 0)
+		return -ENAMETOOLONG;
+
+	return 0;
+}
+
+int
+trace_mkdir(void)
+{
+	struct trace *trace = trace_obj_get();
+	char session[TRACE_DIR_STR_LEN];
+	char *dir_path;
+	int rc;
+
+	if (!trace->dir_offset) {
+		dir_path = calloc(1, sizeof(trace->dir));
+		if (dir_path == NULL) {
+			trace_err("fail to allocate memory\n");
+			return -ENOMEM;
+		}
+
+		rc = trace_dir_default_path_get(dir_path);
+		if (rc < 0) {
+			trace_err("fail to get default path\n");
+			free(dir_path);
+			return rc;
+		}
+
+	}
+
+	/* Create the path if it t exist, no "mkdir -p" available here */
+	rc = mkdir(trace->dir, 0700);
+	if (rc < 0 && errno != EEXIST) {
+		trace_err("mkdir %s failed [%s]", trace->dir, strerror(errno));
+		rte_errno = errno;
+		return -rte_errno;
+	}
+
+	rc = trace_session_name_generate(session);
+	if (rc < 0)
+		return rc;
+
+	rc = mkdir(trace->dir, 0700);
+	if (rc < 0) {
+		trace_err("mkdir %s failed [%s]", trace->dir, strerror(errno));
+		rte_errno = errno;
+		return -rte_errno;
+	}
+
+	RTE_LOG(INFO, EAL, "Trace dir: %s\n", trace->dir);
+	return 0;
+}
+
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index e32e0821f..9354f2456 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -5,7 +5,9 @@
 #ifndef __EAL_TRACE_H
 #define __EAL_TRACE_H
 
+#include <rte_spinlock.h>
 #include <rte_trace.h>
+#include <rte_uuid.h>
 
 #define trace_err(fmt, args...)\
 	RTE_LOG(ERR, EAL, "%s():%u " fmt "\n",\
@@ -15,6 +17,8 @@
 	RTE_LOG(CRIT, EAL, "%s():%u " fmt "\n",\
 		__func__, __LINE__, ## args)
 
+#define TRACE_PREFIX_LEN 12
+#define TRACE_DIR_STR_LEN (sizeof("YYYY-mm-dd-AM-HH-MM-SS") + TRACE_PREFIX_LEN)
 #define TRACE_CTF_FIELD_SIZE 384
 #define TRACE_POINT_NAME_SIZE 64
 
@@ -26,11 +30,15 @@ struct trace_point {
 };
 
 struct trace {
+	char dir[PATH_MAX];
+	int dir_offset;
 	int register_errno;
 	bool global_status;
 	enum rte_trace_mode mode;
+	rte_uuid_t uuid;
 	uint32_t level;
 	uint32_t nb_trace_points;
+	rte_spinlock_t lock;
 };
 
 /* Helper functions */
@@ -41,7 +49,20 @@ trace_id_get(rte_trace_t *trace)
 		__RTE_TRACE_FIELD_ID_SHIFT;
 }
 
+/* Trace object functions */
+struct trace *trace_obj_get(void);
+
 /* Trace point list functions */
 STAILQ_HEAD(trace_point_head, trace_point);
+struct trace_point_head *trace_list_head_get(void);
+
+/* Util functions */
+bool trace_has_duplicate_entry(void);
+void trace_uuid_generate(void);
+int trace_mkdir(void);
+
+/* EAL interface */
+int eal_trace_init(void);
+void eal_trace_fini(void);
 
 #endif /* __EAL_TRACE_H */
diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
index 88c14ebe5..716a255d2 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -29,6 +29,7 @@ common_sources = files(
 	'eal_common_thread.c',
 	'eal_common_timer.c',
 	'eal_common_trace.c',
+	'eal_common_trace_utils.c',
 	'eal_common_uuid.c',
 	'hotplug_mp.c',
 	'malloc_elem.c',
diff --git a/lib/librte_eal/freebsd/eal/Makefile b/lib/librte_eal/freebsd/eal/Makefile
index b2fcc4212..8c444da02 100644
--- a/lib/librte_eal/freebsd/eal/Makefile
+++ b/lib/librte_eal/freebsd/eal/Makefile
@@ -61,6 +61,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_utils.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += malloc_elem.c
diff --git a/lib/librte_eal/linux/eal/Makefile b/lib/librte_eal/linux/eal/Makefile
index 95470d3bb..bd9993e58 100644
--- a/lib/librte_eal/linux/eal/Makefile
+++ b/lib/librte_eal/linux/eal/Makefile
@@ -69,6 +69,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_utils.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += malloc_elem.c
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 06/32] eal/trace: get bootup timestamp for trace
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (4 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 05/32] eal/trace: add internal trace init and fini interface jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 07/32] eal/trace: create CTF TDSL metadata in memory jerinj
                     ` (26 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Find epoch_sec, epoch_nsec and uptime_ticks time information
on eal_trace_init()/bootup to derive the time in the trace.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c      |  3 +++
 .../common/eal_common_trace_utils.c           | 22 +++++++++++++++++++
 lib/librte_eal/common/eal_trace.h             |  5 +++++
 3 files changed, 30 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index 50890fb5b..42829ed6f 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -59,6 +59,9 @@ eal_trace_init(void)
 	if (trace_mkdir())
 		goto fail;
 
+	/* Save current epoch timestamp for future use */
+	if (trace_epoch_time_save() < 0)
+		goto fail;
 
 	rte_trace_global_mode_set(trace.mode);
 
diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
index 8df7b5c33..f65672119 100644
--- a/lib/librte_eal/common/eal_common_trace_utils.c
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -98,6 +98,28 @@ trace_session_name_generate(char *trace_dir)
 	return -rte_errno;
 }
 
+int
+trace_epoch_time_save(void)
+{
+	struct trace *trace = trace_obj_get();
+	struct timespec epoch = { 0, 0 };
+	uint64_t avg, start, end;
+
+	start = rte_get_tsc_cycles();
+	if (clock_gettime(CLOCK_REALTIME, &epoch) < 0) {
+		trace_err("failed to get the epoch time");
+		return -1;
+	}
+	end = rte_get_tsc_cycles();
+	avg = (start + end) >> 1;
+
+	trace->epoch_sec = (uint64_t) epoch.tv_sec;
+	trace->epoch_nsec = (uint64_t) epoch.tv_nsec;
+	trace->uptime_ticks = avg;
+
+	return 0;
+}
+
 static int
 trace_dir_default_path_get(char *dir_path)
 {
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index 9354f2456..10139c06c 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -5,6 +5,7 @@
 #ifndef __EAL_TRACE_H
 #define __EAL_TRACE_H
 
+#include <rte_cycles.h>
 #include <rte_spinlock.h>
 #include <rte_trace.h>
 #include <rte_uuid.h>
@@ -38,6 +39,9 @@ struct trace {
 	rte_uuid_t uuid;
 	uint32_t level;
 	uint32_t nb_trace_points;
+	uint64_t epoch_sec;
+	uint64_t epoch_nsec;
+	uint64_t uptime_ticks;
 	rte_spinlock_t lock;
 };
 
@@ -60,6 +64,7 @@ struct trace_point_head *trace_list_head_get(void);
 bool trace_has_duplicate_entry(void);
 void trace_uuid_generate(void);
 int trace_mkdir(void);
+int trace_epoch_time_save(void);
 
 /* EAL interface */
 int eal_trace_init(void);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 07/32] eal/trace: create CTF TDSL metadata in memory
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (5 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 06/32] eal/trace: get bootup timestamp for trace jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 08/32] eal/trace: handle CTF keyword collision jerinj
                     ` (25 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom, skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Common trace format(CTF) defines the metadata[1][2] for trace events,
This patch creates the metadata for the DPDK events in memory and
latter this will be saved to trace directory on rte_trace_save()
invocation.

[1] https://diamon.org/ctf/#specification
[2] https://diamon.org/ctf/#examples

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c     |   9 +-
 lib/librte_eal/common/eal_common_trace_ctf.c | 302 +++++++++++++++++++
 lib/librte_eal/common/eal_trace.h            |   7 +
 lib/librte_eal/common/meson.build            |   1 +
 lib/librte_eal/freebsd/eal/Makefile          |   1 +
 lib/librte_eal/linux/eal/Makefile            |   1 +
 6 files changed, 320 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/common/eal_common_trace_ctf.c

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index 42829ed6f..e889c6f0e 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -55,9 +55,13 @@ eal_trace_init(void)
 	/* Generate UUID ver 4 with total size of events and number of events */
 	trace_uuid_generate();
 
+	/* Generate CTF TDSL metadata */
+	if (trace_metadata_create() < 0)
+		goto fail;
+
 	/* Create trace directory */
 	if (trace_mkdir())
-		goto fail;
+		goto free_meta;
 
 	/* Save current epoch timestamp for future use */
 	if (trace_epoch_time_save() < 0)
@@ -67,6 +71,8 @@ eal_trace_init(void)
 
 	return 0;
 
+free_meta:
+	trace_metadata_destroy();
 fail:
 	trace_err("failed to initialize trace [%s]", rte_strerror(rte_errno));
 	return -rte_errno;
@@ -77,6 +83,7 @@ eal_trace_fini(void)
 {
 	if (rte_trace_global_is_disabled())
 		return;
+	trace_metadata_destroy();
 }
 
 bool
diff --git a/lib/librte_eal/common/eal_common_trace_ctf.c b/lib/librte_eal/common/eal_common_trace_ctf.c
new file mode 100644
index 000000000..5ad44cc8d
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_trace_ctf.c
@@ -0,0 +1,302 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#include <inttypes.h>
+#include <time.h>
+
+#include <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_time.h>
+#include <rte_trace.h>
+#include <rte_version.h>
+
+#include "eal_trace.h"
+
+__rte_format_printf(2, 0)
+static int
+metadata_printf(char **str, const char *fmt, ...)
+{
+	va_list ap;
+	int rc;
+
+	*str = NULL;
+	va_start(ap, fmt);
+	rc = vasprintf(str, fmt, ap);
+	va_end(ap);
+
+	return rc;
+}
+
+static int
+meta_copy(char **meta, int *offset, char *str, int rc)
+{
+	int count = *offset;
+	char *ptr = *meta;
+
+	if (rc < 0)
+		return rc;
+
+	ptr = realloc(ptr, count + rc);
+	if (ptr == NULL)
+		goto free_str;
+
+	memcpy(RTE_PTR_ADD(ptr, count), str, rc);
+	count += rc;
+	free(str);
+
+	*meta = ptr;
+	*offset = count;
+
+	return rc;
+
+free_str:
+	if (str)
+		free(str);
+	return -ENOMEM;
+}
+
+static int
+meta_data_type_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"/* CTF 1.8 */\n"
+		"typealias integer {size = 8; base = x;}:= uint8_t;\n"
+		"typealias integer {size = 16; base = x;} := uint16_t;\n"
+		"typealias integer {size = 32; base = x;} := uint32_t;\n"
+		"typealias integer {size = 64; base = x;} := uint64_t;\n"
+		"typealias integer {size = 8; signed = true;}  := int8_t;\n"
+		"typealias integer {size = 16; signed = true;} := int16_t;\n"
+		"typealias integer {size = 32; signed = true;} := int32_t;\n"
+		"typealias integer {size = 64; signed = true;} := int64_t;\n"
+#ifdef RTE_ARCH_64
+		"typealias integer {size = 64; base = x;} := uintptr_t;\n"
+#else
+		"typealias integer {size = 32; base = x;} := uintptr_t;\n"
+#endif
+#ifdef RTE_ARCH_64
+		"typealias integer {size = 64; base = x;} := long;\n"
+#else
+		"typealias integer {size = 32; base = x;} := long;\n"
+#endif
+		"typealias integer {size = 8; signed = false; encoding = ASCII; } := string_bounded_t;\n\n"
+		"typealias floating_point {\n"
+		"    exp_dig = 8;\n"
+		"    mant_dig = 24;\n"
+		"} := float;\n\n"
+		"typealias floating_point {\n"
+		"    exp_dig = 11;\n"
+		"    mant_dig = 53;\n"
+		"} := double;\n\n");
+
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+is_be(void)
+{
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+	return 1;
+#else
+	return 0;
+#endif
+}
+
+static int
+meta_header_emit(char **meta, int *offset)
+{
+	struct trace *trace = trace_obj_get();
+	char uustr[RTE_UUID_STRLEN];
+	char *str = NULL;
+	int rc;
+
+	rte_uuid_unparse(trace->uuid, uustr, RTE_UUID_STRLEN);
+	rc = metadata_printf(&str,
+		"trace {\n"
+		"    major = 1;\n"
+		"    minor = 8;\n"
+		"    uuid = \"%s\";\n"
+		"    byte_order = %s;\n"
+		"    packet.header := struct {\n"
+		"	    uint32_t magic;\n"
+		"	    uint8_t  uuid[16];\n"
+		"    };\n"
+		"};\n\n", uustr, is_be() ? "be" : "le");
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_env_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"env {\n"
+		"    dpdk_version = \"%s\";\n"
+		"    tracer_name = \"dpdk\";\n"
+		"};\n\n", rte_version());
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_clock_pass1_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"clock {\n"
+		"    name = \"dpdk\";\n"
+		"    freq = ");
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_clock_pass2_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"%20"PRIu64";\n"
+		"    offset_s =", 0);
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_clock_pass3_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"%20"PRIu64";\n"
+		"    offset =", 0);
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_clock_pass4_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"%20"PRIu64";\n};\n\n"
+		"typealias integer {\n"
+		"    size = 48; align = 1; signed = false;\n"
+		"    map = clock.dpdk.value;\n"
+		"} := uint48_clock_dpdk_t;\n\n", 0);
+
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_stream_emit(char **meta, int *offset)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"stream {\n"
+		"    packet.context := struct {\n"
+		"         uint32_t cpu_id;\n"
+		"         string_bounded_t name[32];\n"
+		"    };\n"
+		"    event.header := struct {\n"
+		"          uint48_clock_dpdk_t timestamp;\n"
+		"          uint16_t id;\n"
+		"    } align(64);\n"
+		"};\n\n");
+	return meta_copy(meta, offset, str, rc);
+}
+
+static int
+meta_event_emit(char **meta, int *offset, struct trace_point *tp)
+{
+	char *str = NULL;
+	int rc;
+
+	rc = metadata_printf(&str,
+		"event {\n"
+		"    id = %d;\n"
+		"    name = \"%s\";\n"
+		"    fields := struct {\n"
+		"        %s\n"
+		"    };\n"
+		"};\n\n", trace_id_get(tp->handle), tp->name, tp->ctf_field);
+	return meta_copy(meta, offset, str, rc);
+}
+
+int
+trace_metadata_create(void)
+{
+	struct trace_point_head *tp_list = trace_list_head_get();
+	struct trace *trace = trace_obj_get();
+	struct trace_point *tp;
+	int rc, offset = 0;
+	char *meta = NULL;
+
+	rc = meta_data_type_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+
+	rc = meta_header_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+
+	rc = meta_env_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+
+	rc = meta_clock_pass1_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+	trace->ctf_meta_offset_freq = offset;
+
+	rc = meta_clock_pass2_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+	trace->ctf_meta_offset_freq_off_s = offset;
+
+	rc = meta_clock_pass3_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+	trace->ctf_meta_offset_freq_off = offset;
+
+	rc = meta_clock_pass4_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+
+	rc = meta_stream_emit(&meta, &offset);
+	if (rc < 0)
+		goto fail;
+
+	STAILQ_FOREACH(tp, tp_list, next)
+		if (meta_event_emit(&meta, &offset, tp) < 0)
+			goto fail;
+
+	trace->ctf_meta = meta;
+	return 0;
+
+fail:
+	if (meta)
+		free(meta);
+	return -EBADF;
+}
+
+void
+trace_metadata_destroy(void)
+{
+	struct trace *trace = trace_obj_get();
+
+	if (trace->ctf_meta) {
+		free(trace->ctf_meta);
+		trace->ctf_meta = NULL;
+	}
+}
+
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index 10139c06c..4c77796ce 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -42,6 +42,11 @@ struct trace {
 	uint64_t epoch_sec;
 	uint64_t epoch_nsec;
 	uint64_t uptime_ticks;
+	char *ctf_meta;
+	uint32_t ctf_meta_offset_freq;
+	uint32_t ctf_meta_offset_freq_off_s;
+	uint32_t ctf_meta_offset_freq_off;
+	uint16_t ctf_fixup_done;
 	rte_spinlock_t lock;
 };
 
@@ -63,6 +68,8 @@ struct trace_point_head *trace_list_head_get(void);
 /* Util functions */
 bool trace_has_duplicate_entry(void);
 void trace_uuid_generate(void);
+int trace_metadata_create(void);
+void trace_metadata_destroy(void);
 int trace_mkdir(void);
 int trace_epoch_time_save(void);
 
diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
index 716a255d2..4ccdf1eee 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -29,6 +29,7 @@ common_sources = files(
 	'eal_common_thread.c',
 	'eal_common_timer.c',
 	'eal_common_trace.c',
+	'eal_common_trace_ctf.c',
 	'eal_common_trace_utils.c',
 	'eal_common_uuid.c',
 	'hotplug_mp.c',
diff --git a/lib/librte_eal/freebsd/eal/Makefile b/lib/librte_eal/freebsd/eal/Makefile
index 8c444da02..546d79514 100644
--- a/lib/librte_eal/freebsd/eal/Makefile
+++ b/lib/librte_eal/freebsd/eal/Makefile
@@ -61,6 +61,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_ctf.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_utils.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c
diff --git a/lib/librte_eal/linux/eal/Makefile b/lib/librte_eal/linux/eal/Makefile
index bd9993e58..1980e9fc5 100644
--- a/lib/librte_eal/linux/eal/Makefile
+++ b/lib/librte_eal/linux/eal/Makefile
@@ -69,6 +69,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_ctf.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_utils.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 08/32] eal/trace: handle CTF keyword collision
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (6 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 07/32] eal/trace: create CTF TDSL metadata in memory jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 09/32] eal/trace: implement trace memory allocation jerinj
                     ` (24 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom, skori

From: Sunil Kumar Kori <skori@marvell.com>

Some of the keyword like align, event, "." and "->" etc will be
used in CTF metadata syntax. This patch support for handling
those keywords with DPDK events name.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 lib/librte_eal/common/eal_common_trace_ctf.c | 119 +++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace_ctf.c b/lib/librte_eal/common/eal_common_trace_ctf.c
index 5ad44cc8d..c4f00bf22 100644
--- a/lib/librte_eal/common/eal_common_trace_ctf.c
+++ b/lib/librte_eal/common/eal_common_trace_ctf.c
@@ -215,12 +215,131 @@ meta_stream_emit(char **meta, int *offset)
 	return meta_copy(meta, offset, str, rc);
 }
 
+static void
+string_fixed_replace(char *input, const char *search, const char *replace)
+{
+	char *found;
+	size_t len;
+
+	found = strstr(input, search);
+	if (found == NULL)
+		return;
+
+	if (strlen(found) != strlen(search))
+		return;
+
+	len = strlen(replace);
+	memcpy(found, replace, len);
+	found[len] = '\0';
+}
+
+static void
+ctf_fixup_align(char *str)
+{
+	string_fixed_replace(str, "align", "_align");
+}
+
+static void
+ctf_fixup_arrow_deref(char *str)
+{
+	const char *replace = "_";
+	const char *search = "->";
+	char *found;
+	size_t len;
+
+	found = strstr(str, search);
+	if (found == NULL)
+		return;
+
+	do {
+		memcpy(found, replace, strlen(replace));
+		len = strlen(found + 2);
+		memcpy(found + 1, found + 2, len);
+		found[len + 1] = '\0';
+		found = strstr(str, search);
+	} while (found != NULL);
+}
+
+static void
+ctf_fixup_dot_deref(char *str)
+{
+	const char *replace = "_";
+	const char *search = ".";
+	char *found;
+	size_t len;
+
+	found = strstr(str, search);
+	if (found == NULL)
+		return;
+
+	len = strlen(replace);
+	do {
+		memcpy(found, replace, len);
+		found = strstr(str, search);
+	} while (found != NULL);
+}
+
+static void
+ctf_fixup_event(char *str)
+{
+	string_fixed_replace(str, "event", "_event");
+}
+
+static int
+ctf_fixup_keyword(char *str)
+{
+	char dup_str[TRACE_CTF_FIELD_SIZE];
+	char input[TRACE_CTF_FIELD_SIZE];
+	const char *delim = ";";
+	char *from;
+	int len;
+
+	if (str == NULL)
+		return 0;
+
+	len = strlen(str);
+	if (len >= TRACE_CTF_FIELD_SIZE) {
+		trace_err("ctf_field reached its maximum limit");
+		return -EMSGSIZE;
+	}
+
+	/* Create duplicate string */
+	strcpy(dup_str, str);
+
+	len = 0;
+	from = strtok(dup_str, delim);
+	while (from != NULL) {
+		strcpy(input, from);
+		ctf_fixup_align(input);
+		ctf_fixup_dot_deref(input);
+		ctf_fixup_arrow_deref(input);
+		ctf_fixup_event(input);
+
+		strcpy(&input[strlen(input)], delim);
+		if ((len + strlen(input)) >= TRACE_CTF_FIELD_SIZE) {
+			trace_err("ctf_field reached its maximum limit");
+			return -EMSGSIZE;
+		}
+
+		strcpy(str + len, input);
+		len += strlen(input);
+		from = strtok(NULL, delim);
+	}
+
+	return 0;
+}
+
 static int
 meta_event_emit(char **meta, int *offset, struct trace_point *tp)
 {
 	char *str = NULL;
 	int rc;
 
+	/* Fixup ctf field string in case it using reserved ctf keywords */
+	rc = ctf_fixup_keyword(tp->ctf_field);
+	if (rc)
+		return rc;
+
 	rc = metadata_printf(&str,
 		"event {\n"
 		"    id = %d;\n"
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 09/32] eal/trace: implement trace memory allocation
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (7 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 08/32] eal/trace: handle CTF keyword collision jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 10/32] eal/trace: implement debug dump function jerinj
                     ` (23 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Trace memory will be allocated per thread to enable lockless trace
events updates to the memory. The allocator will first attempt to
allocate from hugepage, if not available from hugepage then
fallback to malloc memory.

Later in the patches series, This API will be hooked to DPDK fastpath
and control plane thread creation API. It is possible for non
DPDK thread to use trace events, in that case, trace memory
will be allocated on the first event emission.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c      | 97 +++++++++++++++++++
 .../common/eal_common_trace_utils.c           | 20 ++++
 lib/librte_eal/common/eal_trace.h             | 29 ++++++
 lib/librte_eal/common/include/rte_trace.h     | 13 +++
 .../common/include/rte_trace_provider.h       | 19 ++++
 lib/librte_eal/rte_eal_version.map            |  2 +
 6 files changed, 180 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index e889c6f0e..4f032273c 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -16,6 +16,7 @@
 #include "eal_trace.h"
 
 RTE_DEFINE_PER_LCORE(volatile int, trace_point_sz);
+RTE_DEFINE_PER_LCORE(void *, trace_mem);
 RTE_DEFINE_PER_LCORE(char, ctf_field[TRACE_CTF_FIELD_SIZE]);
 RTE_DEFINE_PER_LCORE(int, ctf_count);
 
@@ -37,6 +38,9 @@ trace_list_head_get(void)
 int
 eal_trace_init(void)
 {
+	/* Trace memory should start with 8B aligned for natural alignment */
+	RTE_BUILD_BUG_ON((offsetof(struct __rte_trace_header, mem) % 8) != 0);
+
 	/* One of the Trace registration failed */
 	if (trace.register_errno) {
 		rte_errno = trace.register_errno;
@@ -83,6 +87,7 @@ eal_trace_fini(void)
 {
 	if (rte_trace_global_is_disabled())
 		return;
+	trace_mem_per_thread_free();
 	trace_metadata_destroy();
 }
 
@@ -327,6 +332,98 @@ rte_trace_by_name(const char *name)
 	return NULL;
 }
 
+static inline size_t
+list_sz(uint32_t index)
+{
+	return sizeof(struct thread_mem_meta) * (index + 1);
+}
+
+void
+__rte_trace_mem_per_thread_alloc(void)
+{
+	struct trace *trace = trace_obj_get();
+	struct __rte_trace_header *header;
+	uint32_t count;
+
+	if (rte_trace_global_is_disabled())
+		return;
+
+	if (RTE_PER_LCORE(trace_mem))
+		return;
+
+	rte_spinlock_lock(&trace->lock);
+
+	count = trace->nb_trace_mem_list;
+
+	/* Allocate room for storing the thread trace mem meta */
+	trace->lcore_meta = realloc(trace->lcore_meta, list_sz(count));
+
+	/* Provide dummy space for fastpath to consume */
+	if (trace->lcore_meta == NULL) {
+		trace_crit("trace mem meta memory realloc failed");
+		header = NULL; goto fail;
+	}
+
+	/* First attempt from huge page */
+	header = rte_malloc(NULL, trace_mem_sz(trace->buff_len), 8);
+	if (header) {
+		trace->lcore_meta[count].area = TRACE_AREA_HUGEPAGE;
+		goto found;
+	}
+
+	/* Second attempt from heap */
+	header = malloc(trace_mem_sz(trace->buff_len));
+	if (header == NULL) {
+		trace_crit("trace mem malloc attempt failed");
+		header = NULL; goto fail;
+
+	}
+
+	/* Second attempt from heap is success */
+	trace->lcore_meta[count].area = TRACE_AREA_HEAP;
+
+	/* Initialize the trace header */
+found:
+	header->offset = 0;
+	header->len = trace->buff_len;
+	header->stream_header.magic = TRACE_CTF_MAGIC;
+	rte_uuid_copy(header->stream_header.uuid, trace->uuid);
+	header->stream_header.lcore_id = rte_lcore_id();
+
+	/* Store the thread name */
+	char *name = header->stream_header.thread_name;
+	memset(name, 0, __RTE_TRACE_EMIT_STRING_LEN_MAX);
+	rte_thread_getname(pthread_self(), name,
+			   __RTE_TRACE_EMIT_STRING_LEN_MAX);
+
+	trace->lcore_meta[count].mem = header;
+	trace->nb_trace_mem_list++;
+fail:
+	RTE_PER_LCORE(trace_mem) = header;
+	rte_spinlock_unlock(&trace->lock);
+}
+
+void
+trace_mem_per_thread_free(void)
+{
+	struct trace *trace = trace_obj_get();
+	uint32_t count;
+	void *mem;
+
+	if (rte_trace_global_is_disabled())
+		return;
+
+	rte_spinlock_lock(&trace->lock);
+	for (count = 0; count < trace->nb_trace_mem_list; count++) {
+		mem = trace->lcore_meta[count].mem;
+		if (trace->lcore_meta[count].area == TRACE_AREA_HUGEPAGE)
+			rte_free(mem);
+		else if (trace->lcore_meta[count].area == TRACE_AREA_HEAP)
+			free(mem);
+	}
+	rte_spinlock_unlock(&trace->lock);
+}
+
 int
 __rte_trace_point_register(rte_trace_t *handle, const char *name,
 			   uint32_t level, void (*register_fn)(void))
diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
index f65672119..b288a72f0 100644
--- a/lib/librte_eal/common/eal_common_trace_utils.c
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -14,6 +14,26 @@
 #include "eal_filesystem.h"
 #include "eal_trace.h"
 
+const char *
+trace_mode_to_string(enum rte_trace_mode mode)
+{
+	switch (mode) {
+	case RTE_TRACE_MODE_OVERWRITE: return "overwrite";
+	case RTE_TRACE_MODE_DISCARD: return "discard";
+	default: return "unknown";
+	}
+}
+
+const char *
+trace_area_to_string(enum trace_area_e area)
+{
+	switch (area) {
+	case TRACE_AREA_HEAP: return "heap";
+	case TRACE_AREA_HUGEPAGE: return "hugepage";
+	default: return "unknown";
+	}
+}
+
 static bool
 trace_entry_compare(const char *name)
 {
diff --git a/lib/librte_eal/common/eal_trace.h b/lib/librte_eal/common/eal_trace.h
index 4c77796ce..848d1dfc0 100644
--- a/lib/librte_eal/common/eal_trace.h
+++ b/lib/librte_eal/common/eal_trace.h
@@ -6,10 +6,15 @@
 #define __EAL_TRACE_H
 
 #include <rte_cycles.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
 #include <rte_spinlock.h>
 #include <rte_trace.h>
 #include <rte_uuid.h>
 
+#include "eal_private.h"
+#include "eal_thread.h"
+
 #define trace_err(fmt, args...)\
 	RTE_LOG(ERR, EAL, "%s():%u " fmt "\n",\
 		__func__, __LINE__, ## args)
@@ -22,6 +27,8 @@
 #define TRACE_DIR_STR_LEN (sizeof("YYYY-mm-dd-AM-HH-MM-SS") + TRACE_PREFIX_LEN)
 #define TRACE_CTF_FIELD_SIZE 384
 #define TRACE_POINT_NAME_SIZE 64
+#define TRACE_CTF_MAGIC 0xC1FC1FC1
+
 
 struct trace_point {
 	STAILQ_ENTRY(trace_point) next;
@@ -30,6 +37,16 @@ struct trace_point {
 	char ctf_field[TRACE_CTF_FIELD_SIZE];
 };
 
+enum trace_area_e {
+	TRACE_AREA_HEAP,
+	TRACE_AREA_HUGEPAGE,
+};
+
+struct thread_mem_meta {
+	void *mem;
+	enum trace_area_e area;
+};
+
 struct trace {
 	char dir[PATH_MAX];
 	int dir_offset;
@@ -37,8 +54,11 @@ struct trace {
 	bool global_status;
 	enum rte_trace_mode mode;
 	rte_uuid_t uuid;
+	uint32_t buff_len;
 	uint32_t level;
 	uint32_t nb_trace_points;
+	uint32_t nb_trace_mem_list;
+	struct thread_mem_meta *lcore_meta;
 	uint64_t epoch_sec;
 	uint64_t epoch_nsec;
 	uint64_t uptime_ticks;
@@ -58,6 +78,12 @@ trace_id_get(rte_trace_t *trace)
 		__RTE_TRACE_FIELD_ID_SHIFT;
 }
 
+static inline size_t
+trace_mem_sz(uint32_t len)
+{
+	return len + sizeof(struct __rte_trace_header);
+}
+
 /* Trace object functions */
 struct trace *trace_obj_get(void);
 
@@ -66,12 +92,15 @@ STAILQ_HEAD(trace_point_head, trace_point);
 struct trace_point_head *trace_list_head_get(void);
 
 /* Util functions */
+const char *trace_mode_to_string(enum rte_trace_mode mode);
+const char *trace_area_to_string(enum trace_area_e area);
 bool trace_has_duplicate_entry(void);
 void trace_uuid_generate(void);
 int trace_metadata_create(void);
 void trace_metadata_destroy(void);
 int trace_mkdir(void);
 int trace_epoch_time_save(void);
+void trace_mem_per_thread_free(void);
 
 /* EAL interface */
 int eal_trace_init(void);
diff --git a/lib/librte_eal/common/include/rte_trace.h b/lib/librte_eal/common/include/rte_trace.h
index 90b9d5894..8293c23c8 100644
--- a/lib/librte_eal/common/include/rte_trace.h
+++ b/lib/librte_eal/common/include/rte_trace.h
@@ -515,6 +515,19 @@ _tp _args \
 
 #endif /* __DOXYGEN__ */
 
+/** @internal Macro to define maximum emit length of string datatype. */
+#define __RTE_TRACE_EMIT_STRING_LEN_MAX 32
+
+/**
+ * @internal @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Allocate trace memory buffer per thread.
+ *
+ */
+__rte_experimental
+void __rte_trace_mem_per_thread_alloc(void);
+
 /**
  * @internal @warning
  * @b EXPERIMENTAL: this API may change without prior notice
diff --git a/lib/librte_eal/common/include/rte_trace_provider.h b/lib/librte_eal/common/include/rte_trace_provider.h
index b4da87ba1..2257de85b 100644
--- a/lib/librte_eal/common/include/rte_trace_provider.h
+++ b/lib/librte_eal/common/include/rte_trace_provider.h
@@ -9,6 +9,10 @@
 #ifndef _RTE_TRACE_PROVIDER_H_
 #define _RTE_TRACE_PROVIDER_H_
 
+#include <rte_per_lcore.h>
+#include <rte_string_fns.h>
+#include <rte_uuid.h>
+
 #define __RTE_TRACE_EVENT_HEADER_ID_SHIFT (48)
 
 #define __RTE_TRACE_FIELD_ENABLE_MASK (1ULL << 63)
@@ -20,5 +24,20 @@
 #define __RTE_TRACE_FIELD_LEVEL_SHIFT (32)
 #define __RTE_TRACE_FIELD_LEVEL_MASK (0xffULL << __RTE_TRACE_FIELD_LEVEL_SHIFT)
 
+struct __rte_trace_stream_header {
+	uint32_t magic;
+	rte_uuid_t uuid;
+	uint32_t lcore_id;
+	char thread_name[__RTE_TRACE_EMIT_STRING_LEN_MAX];
+} __rte_packed;
+
+struct __rte_trace_header {
+	uint32_t offset;
+	uint32_t len;
+	struct __rte_trace_stream_header stream_header;
+	uint8_t mem[];
+};
+
+RTE_DECLARE_PER_LCORE(void *, trace_mem);
 
 #endif /* _RTE_TRACE_PROVIDER_H_ */
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index ca1f2cc86..c4f87af3b 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -338,7 +338,9 @@ EXPERIMENTAL {
 
 	# added in 20.05
 	rte_thread_getname;
+	__rte_trace_mem_per_thread_alloc;
 	__rte_trace_point_register;
+	per_lcore_trace_mem;
 	rte_trace_global_is_enabled;
 	rte_trace_global_is_disabled;
 	rte_trace_is_id_invalid;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 10/32] eal/trace: implement debug dump function
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (8 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 09/32] eal/trace: implement trace memory allocation jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 11/32] eal/trace: implement trace save jerinj
                     ` (22 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Implement rte_trace_metadata_dump() and rte_trace_dump()
functions. Former one used to dump the CTF metadata file and
the latter one to dump all the registered events and its status.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 lib/librte_eal/common/eal_common_log.c       |  9 +--
 lib/librte_eal/common/eal_common_trace.c     | 63 ++++++++++++++++++
 lib/librte_eal/common/eal_common_trace_ctf.c | 67 ++++++++++++++++++++
 lib/librte_eal/common/eal_private.h          |  3 +
 lib/librte_eal/rte_eal_version.map           |  2 +
 5 files changed, 140 insertions(+), 4 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
index c0efd5214..d8f7feb32 100644
--- a/lib/librte_eal/common/eal_common_log.c
+++ b/lib/librte_eal/common/eal_common_log.c
@@ -372,8 +372,8 @@ RTE_INIT_PRIO(rte_log_init, LOG)
 	rte_logs.dynamic_types_len = RTE_LOGTYPE_FIRST_EXT_ID;
 }
 
-static const char *
-loglevel_to_string(uint32_t level)
+const char *
+eal_loglevel_to_string(uint32_t level)
 {
 	switch (level) {
 	case 0: return "disabled";
@@ -396,14 +396,15 @@ rte_log_dump(FILE *f)
 	size_t i;
 
 	fprintf(f, "global log level is %s\n",
-		loglevel_to_string(rte_log_get_global_level()));
+		eal_loglevel_to_string(rte_log_get_global_level()));
 
 	for (i = 0; i < rte_logs.dynamic_types_len; i++) {
 		if (rte_logs.dynamic_types[i].name == NULL)
 			continue;
 		fprintf(f, "id %zu: %s, level is %s\n",
 			i, rte_logs.dynamic_types[i].name,
-			loglevel_to_string(rte_logs.dynamic_types[i].loglevel));
+			eal_loglevel_to_string(
+					rte_logs.dynamic_types[i].loglevel));
 	}
 }
 
diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index 4f032273c..2c2f6c440 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -332,6 +332,69 @@ rte_trace_by_name(const char *name)
 	return NULL;
 }
 
+static void
+trace_point_dump(FILE *f, struct trace_point *tp)
+{
+	rte_trace_t *handle = tp->handle;
+	uint32_t level;
+
+	level = rte_trace_level_get(handle);
+	fprintf(f, "\tid %d, %s, size is %d, level is %s, mode is %s, %s\n",
+		trace_id_get(handle), tp->name,
+		(uint16_t)(*handle & __RTE_TRACE_FIELD_SIZE_MASK),
+		eal_loglevel_to_string(level),
+		trace_mode_to_string(rte_trace_mode_get(handle)),
+		rte_trace_is_enabled(handle) ? "enabled" : "disabled");
+}
+
+static void
+trace_lcore_mem_dump(FILE *f)
+{
+	struct trace *trace = trace_obj_get();
+	struct __rte_trace_header *header;
+	uint32_t count;
+
+	if (trace->nb_trace_mem_list == 0)
+		return;
+
+	rte_spinlock_lock(&trace->lock);
+	fprintf(f, "nb_trace_mem_list = %d\n", trace->nb_trace_mem_list);
+	fprintf(f, "\nTrace mem info\n--------------\n");
+	for (count = 0; count < trace->nb_trace_mem_list; count++) {
+		header = trace->lcore_meta[count].mem;
+		fprintf(f, "\tid %d, mem=%p, area=%s, lcore_id=%d, name=%s\n",
+		count, header,
+		trace_area_to_string(trace->lcore_meta[count].area),
+		header->stream_header.lcore_id,
+		header->stream_header.thread_name);
+	}
+	rte_spinlock_unlock(&trace->lock);
+}
+
+void
+rte_trace_dump(FILE *f)
+{
+	struct trace_point_head *tp_list = trace_list_head_get();
+	struct trace *trace = trace_obj_get();
+	struct trace_point *tp;
+
+	fprintf(f, "\nGlobal info\n-----------\n");
+	fprintf(f, "status = %s\n",
+		rte_trace_global_is_enabled() ? "enabled" : "disabled");
+	fprintf(f, "log level = %s\n",
+		eal_loglevel_to_string(rte_trace_global_level_get()));
+	fprintf(f, "mode = %s\n",
+		trace_mode_to_string(rte_trace_global_mode_get()));
+	fprintf(f, "dir = %s\n", trace->dir);
+	fprintf(f, "buffer len = %d\n", trace->buff_len);
+	fprintf(f, "number of trace points = %d\n", trace->nb_trace_points);
+
+	trace_lcore_mem_dump(f);
+	fprintf(f, "\nTrace point info\n----------------\n");
+	STAILQ_FOREACH(tp, tp_list, next)
+		trace_point_dump(f, tp);
+}
+
 static inline size_t
 list_sz(uint32_t index)
 {
diff --git a/lib/librte_eal/common/eal_common_trace_ctf.c b/lib/librte_eal/common/eal_common_trace_ctf.c
index c4f00bf22..0dde8fe14 100644
--- a/lib/librte_eal/common/eal_common_trace_ctf.c
+++ b/lib/librte_eal/common/eal_common_trace_ctf.c
@@ -419,3 +419,70 @@ trace_metadata_destroy(void)
 	}
 }
 
+static void
+meta_fix_freq(struct trace *trace, char *meta)
+{
+	char *str;
+	int rc;
+
+	str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq);
+	rc = sprintf(str, "%20"PRIu64"", rte_get_timer_hz());
+	str[rc] = ';';
+}
+
+static void
+meta_fix_freq_offset(struct trace *trace, char *meta)
+{
+	uint64_t uptime_tickes_floor, uptime_ticks, freq, uptime_sec;
+	uint64_t offset, offset_s;
+	char *str;
+	int rc;
+
+	uptime_ticks = trace->uptime_ticks &
+			((1ULL << __RTE_TRACE_EVENT_HEADER_ID_SHIFT) - 1);
+	freq = rte_get_tsc_hz();
+	uptime_tickes_floor = RTE_ALIGN_MUL_FLOOR(uptime_ticks, freq);
+
+	uptime_sec = uptime_tickes_floor / freq;
+	offset_s = trace->epoch_sec - uptime_sec;
+
+	offset = uptime_ticks - uptime_tickes_floor;
+	offset += trace->epoch_nsec * (freq / NSEC_PER_SEC);
+
+	str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq_off_s);
+	rc = sprintf(str, "%20"PRIu64"", offset_s);
+	str[rc] = ';';
+	str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq_off);
+	rc = sprintf(str, "%20"PRIu64"", offset);
+	str[rc] = ';';
+}
+
+static void
+meta_fixup(struct trace *trace, char *meta)
+{
+	meta_fix_freq(trace, meta);
+	meta_fix_freq_offset(trace, meta);
+}
+
+int
+rte_trace_metadata_dump(FILE *f)
+{
+	struct trace *trace = trace_obj_get();
+	char *ctf_meta = trace->ctf_meta;
+	int rc;
+
+	if (rte_trace_global_is_disabled())
+		return 0;
+
+	if (ctf_meta == NULL)
+		return -EINVAL;
+
+	if (!__atomic_load_n(&trace->ctf_fixup_done, __ATOMIC_SEQ_CST) &&
+				rte_get_timer_hz()) {
+		meta_fixup(trace, ctf_meta);
+		__atomic_store_n(&trace->ctf_fixup_done, 1, __ATOMIC_SEQ_CST);
+	}
+
+	rc = fprintf(f, "%s", ctf_meta);
+	return rc < 0 ? rc : 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index ddcfbe2e4..81694616b 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -443,4 +443,7 @@ rte_option_usage(void);
 uint64_t
 eal_get_baseaddr(void);
 
+const char *
+eal_loglevel_to_string(uint32_t level);
+
 #endif /* _EAL_PRIVATE_H_ */
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index c4f87af3b..594223749 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -359,4 +359,6 @@ EXPERIMENTAL {
 	rte_trace_pattern;
 	rte_trace_regexp;
 	rte_trace_by_name;
+	rte_trace_metadata_dump;
+	rte_trace_dump;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v2 11/32] eal/trace: implement trace save
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (9 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 10/32] eal/trace: implement debug dump function jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 12/32] eal/trace: implement registration payload jerinj
                     ` (21 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Implement rte_trace_save(), which will save the metadata
file and trace memory snapshot to the trace directory.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 .../common/eal_common_trace_utils.c           | 80 +++++++++++++++++++
 lib/librte_eal/rte_eal_version.map            |  1 +
 2 files changed, 81 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c
index b288a72f0..64e7a7cfa 100644
--- a/lib/librte_eal/common/eal_common_trace_utils.c
+++ b/lib/librte_eal/common/eal_common_trace_utils.c
@@ -213,3 +213,83 @@ trace_mkdir(void)
 	return 0;
 }
 
+static int
+trace_meta_save(struct trace *trace)
+{
+	char file_name[PATH_MAX];
+	FILE *f;
+	int rc;
+
+	rc = snprintf(file_name, PATH_MAX, "%s/metadata", trace->dir);
+	if (rc < 0)
+		return rc;
+
+	f = fopen(file_name, "w");
+	if (f == NULL)
+		return -errno;
+
+	rc = rte_trace_metadata_dump(f);
+
+	if (fclose(f))
+		rc = -errno;
+
+	return rc;
+}
+
+
+static inline int
+trace_file_sz(struct __rte_trace_header *hdr)
+{
+	return sizeof(struct __rte_trace_stream_header) + hdr->offset;
+}
+
+static int
+trace_mem_save(struct trace *trace, struct __rte_trace_header *hdr,
+	       uint32_t cnt)
+{
+	char file_name[PATH_MAX];
+	FILE *f;
+	int rc;
+
+	rc = snprintf(file_name, PATH_MAX, "%s/channel0_%d", trace->dir, cnt);
+	if (rc < 0)
+		return rc;
+
+	f = fopen(file_name, "w");
+	if (f == NULL)
+		return -errno;
+
+	rc = fwrite(&hdr->stream_header, trace_file_sz(hdr), 1, f);
+	rc = (rc == 1) ?  0 : -EACCES;
+
+	if (fclose(f))
+		rc = -errno;
+
+	return rc;
+}
+
+int
+rte_trace_save(void)
+{
+	struct trace *trace = trace_obj_get();
+	struct __rte_trace_header *header;
+	uint32_t count;
+	int rc = 0;
+
+	if (trace->nb_trace_mem_list == 0)
+		return rc;
+
+	rc = trace_meta_save(trace);
+	if (rc)
+		return rc;
+
+	rte_spinlock_lock(&trace->lock);
+	for (count = 0; count < trace->nb_trace_mem_list; count++) {
+		header = trace->lcore_meta[count].mem;
+		rc =  trace_mem_save(trace, header, count);
+		if (rc)
+			break;
+	}
+	rte_spinlock_unlock(&trace->lock);
+	return rc;
+}
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 594223749..f84b7fd35 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -359,6 +359,7 @@ EXPERIMENTAL {
 	rte_trace_pattern;
 	rte_trace_regexp;
 	rte_trace_by_name;
+	rte_trace_save;
 	rte_trace_metadata_dump;
 	rte_trace_dump;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 12/32] eal/trace: implement registration payload
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (10 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 11/32] eal/trace: implement trace save jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 13/32] eal/trace: implement provider payload jerinj
                     ` (20 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

The trace function payloads such as rte_trace_ctf_* have
dual functions. The first to emit the payload for the registration
function and the second one to act as trace memory emitters.

When it used as registration payload, it will do the following to
fulfill the registration job.
- Find out the size of the event
- Generate metadata field string using __rte_trace_emit_ctf_field().

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 lib/librte_eal/common/eal_common_trace.c      | 19 +++++++++++
 lib/librte_eal/common/include/rte_trace.h     | 20 +++++++++++
 .../common/include/rte_trace_register.h       | 33 +++++++++++++++++++
 lib/librte_eal/rte_eal_version.map            |  2 ++
 4 files changed, 74 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
index 2c2f6c440..6b1600758 100644
--- a/lib/librte_eal/common/eal_common_trace.c
+++ b/lib/librte_eal/common/eal_common_trace.c
@@ -487,6 +487,25 @@ trace_mem_per_thread_free(void)
 	rte_spinlock_unlock(&trace->lock);
 }
 
+void
+__rte_trace_emit_ctf_field(size_t sz, const char *in, const char *datatype)
+{
+	char *field = RTE_PER_LCORE(ctf_field);
+	int count = RTE_PER_LCORE(ctf_count);
+	int rc;
+
+	RTE_PER_LCORE(trace_point_sz) += sz;
+	rc = snprintf(RTE_PTR_ADD(field, count),
+		      RTE_MAX(0, TRACE_CTF_FIELD_SIZE - 1 - count),
+		      "%s %s;", datatype, in);
+	if (rc <= 0) {
+		RTE_PER_LCORE(trace_point_sz) = 0;
+		trace_crit("CTF field is too long");
+		return;
+	}
+	RTE_PER_LCORE(ctf_count) += rc;
+}
+
 int
 __rte_trace_point_register(rte_trace_t *handle, const char *name,
 			   uint32_t level, void (*register_fn)(void))
diff --git a/lib/librte_eal/common/include/rte_trace.h b/lib/librte_eal/common/include/rte_trace.h
index 8293c23c8..efd7c4636 100644
--- a/lib/librte_eal/common/include/rte_trace.h
+++ b/lib/librte_eal/common/include/rte_trace.h
@@ -517,6 +517,8 @@ _tp _args \
 
 /** @internal Macro to define maximum emit length of string datatype. */
 #define __RTE_TRACE_EMIT_STRING_LEN_MAX 32
+/** @internal Macro to define event header size. */
+#define __RTE_TRACE_EVENT_HEADER_SZ sizeof(uint64_t)
 
 /**
  * @internal @warning
@@ -550,6 +552,24 @@ void __rte_trace_mem_per_thread_alloc(void);
 __rte_experimental
 int __rte_trace_point_register(rte_trace_t *trace, const char *name,
 			     uint32_t level, void (*register_fn)(void));
+/**
+ * @internal @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Helper function to emit ctf field.
+ *
+ * @param sz
+ *   The tracepoint size.
+ * @param field
+ *   The name of the trace event.
+ * @param type
+ *   The datatype of the trace event as string.
+ * @return
+ *   - 0: Success.
+ *   - <0: Failure.
+ */
+__rte_experimental
+void __rte_trace_emit_ctf_field(size_t sz, const char *field, const char *type);
 
 #ifdef RTE_TRACE_POINT_REGISTER_SELECT
 #include <rte_trace_register.h>
diff --git a/lib/librte_eal/common/include/rte_trace_register.h b/lib/librte_eal/common/include/rte_trace_register.h
index e9940b414..0d9d20266 100644
--- a/lib/librte_eal/common/include/rte_trace_register.h
+++ b/lib/librte_eal/common/include/rte_trace_register.h
@@ -10,6 +10,7 @@
 #define _RTE_TRACE_REGISTER_H_
 
 #include <rte_per_lcore.h>
+#include <rte_log.h>
 
 RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz);
 
@@ -17,4 +18,36 @@ RTE_DECLARE_PER_LCORE(volatile int, trace_point_sz);
 	__rte_trace_point_register(&__##trace, RTE_STR(name),\
 			RTE_LOG_ ## level, (void (*)(void)) trace)
 
+#define __rte_trace_emit_header_generic(t)\
+	RTE_PER_LCORE(trace_point_sz) = __RTE_TRACE_EVENT_HEADER_SZ
+
+#define __rte_trace_emit_header_dp(t) __rte_trace_emit_header_generic(t)
+
+#define __rte_trace_emit_datatype(in, type)\
+do {\
+	RTE_BUILD_BUG_ON(sizeof(type) != sizeof(typeof(in)));\
+	__rte_trace_emit_ctf_field(sizeof(type), RTE_STR(in), RTE_STR(type));\
+} while (0)
+
+#define rte_trace_ctf_u64(in) __rte_trace_emit_datatype(in, uint64_t)
+#define rte_trace_ctf_i64(in) __rte_trace_emit_datatype(in, int64_t)
+#define rte_trace_ctf_u32(in) __rte_trace_emit_datatype(in, uint32_t)
+#define rte_trace_ctf_i32(in) __rte_trace_emit_datatype(in, int32_t)
+#define rte_trace_ctf_u16(in) __rte_trace_emit_datatype(in, uint16_t)
+#define rte_trace_ctf_i16(in) __rte_trace_emit_datatype(in, int16_t)
+#define rte_trace_ctf_u8(in) __rte_trace_emit_datatype(in, uint8_t)
+#define rte_trace_ctf_i8(in) __rte_trace_emit_datatype(in, int8_t)
+#define rte_trace_ctf_int(in) __rte_trace_emit_datatype(in, int32_t)
+#define rte_trace_ctf_long(in) __rte_trace_emit_datatype(in, long)
+#define rte_trace_ctf_float(in) __rte_trace_emit_datatype(in, float)
+#define rte_trace_ctf_double(in) __rte_trace_emit_datatype(in, double)
+#define rte_trace_ctf_ptr(in) __rte_trace_emit_datatype(in, uintptr_t)
+
+#define rte_trace_ctf_string(in)\
+do {\
+	RTE_SET_USED(in);\
+	__rte_trace_emit_ctf_field(__RTE_TRACE_EMIT_STRING_LEN_MAX,\
+				   RTE_STR(in)"[32]", "string_bounded_t");\
+} while (0)
+
 #endif /* _RTE_TRACE_REGISTER_H_ */
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index f84b7fd35..e54e7637c 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -339,7 +339,9 @@ EXPERIMENTAL {
 	# added in 20.05
 	rte_thread_getname;
 	__rte_trace_mem_per_thread_alloc;
+	__rte_trace_emit_ctf_field;
 	__rte_trace_point_register;
+	per_lcore_trace_point_sz;
 	per_lcore_trace_mem;
 	rte_trace_global_is_enabled;
 	rte_trace_global_is_disabled;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 13/32] eal/trace: implement provider payload
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (11 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 12/32] eal/trace: implement registration payload jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 14/32] eal/trace: hook internal trace APIs to Linux jerinj
                     ` (19 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

The trace function payloads such as rte_trace_ctf_* have
dual functions. The first to emit the payload for the registration
function and the second one to act as trace mem emitters aka
provider payload.

When it used as provider payload, those function copy the trace
field to trace memory based on the tracing mode.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 .../common/include/rte_trace_provider.h       | 94 +++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_trace_provider.h b/lib/librte_eal/common/include/rte_trace_provider.h
index 2257de85b..d3d7a922b 100644
--- a/lib/librte_eal/common/include/rte_trace_provider.h
+++ b/lib/librte_eal/common/include/rte_trace_provider.h
@@ -9,6 +9,9 @@
 #ifndef _RTE_TRACE_PROVIDER_H_
 #define _RTE_TRACE_PROVIDER_H_
 
+#include <rte_branch_prediction.h>
+#include <rte_cycles.h>
+#include <rte_log.h>
 #include <rte_per_lcore.h>
 #include <rte_string_fns.h>
 #include <rte_uuid.h>
@@ -40,4 +43,95 @@ struct __rte_trace_header {
 
 RTE_DECLARE_PER_LCORE(void *, trace_mem);
 
+static __rte_always_inline void*
+__rte_trace_mem_get(uint64_t in)
+{
+	struct __rte_trace_header *trace = RTE_PER_LCORE(trace_mem);
+	const uint16_t sz = in & __RTE_TRACE_FIELD_SIZE_MASK;
+
+	/* Trace memory is not initialized for this thread */
+	if (unlikely(trace == NULL)) {
+		__rte_trace_mem_per_thread_alloc();
+		trace = RTE_PER_LCORE(trace_mem);
+		if (unlikely(trace == NULL))
+			return NULL;
+	}
+	/* Check the wrap around case */
+	uint32_t offset = trace->offset;
+	if (unlikely((offset + sz) >= trace->len)) {
+		/* Disable the trace event if it in DISCARD mode */
+		if (unlikely(in & __RTE_TRACE_FIELD_ENABLE_DISCARD))
+			return NULL;
+
+		offset = 0;
+	}
+	/* Align to event header size */
+	offset = RTE_ALIGN_CEIL(offset, __RTE_TRACE_EVENT_HEADER_SZ);
+	void *mem = RTE_PTR_ADD(&trace->mem[0], offset);
+	offset += sz;
+	trace->offset = offset;
+
+	return mem;
+}
+
+static __rte_always_inline void*
+__rte_trace_emit_ev_header(void *mem, uint64_t in)
+{
+	uint64_t val;
+
+	/* Event header [63:0] = id [63:48] | timestamp [47:0] */
+	val = rte_get_tsc_cycles() &
+		~(0xffffULL << __RTE_TRACE_EVENT_HEADER_ID_SHIFT);
+	val |= ((in & __RTE_TRACE_FIELD_ID_MASK) <<
+	      (__RTE_TRACE_EVENT_HEADER_ID_SHIFT - __RTE_TRACE_FIELD_ID_SHIFT));
+
+	*(uint64_t *)mem = val;
+	return RTE_PTR_ADD(mem, __RTE_TRACE_EVENT_HEADER_SZ);
+}
+
+#define __rte_trace_emit_header_generic(t)\
+void *mem;\
+do {\
+	const uint64_t val = __atomic_load_n(t, __ATOMIC_ACQUIRE);\
+	if (likely(!(val & __RTE_TRACE_FIELD_ENABLE_MASK)))\
+		return;\
+	mem = __rte_trace_mem_get(val);\
+	if (unlikely(mem == NULL)) \
+		return;\
+	mem = __rte_trace_emit_ev_header(mem, val);\
+} while (0)
+
+#define __rte_trace_emit_header_dp(t)\
+	if (rte_trace_is_dp_enabled())\
+		return;\
+	__rte_trace_emit_header_generic(t);
+
+#define __rte_trace_emit_datatype(in)\
+do {\
+	memcpy(mem, &(in), sizeof(in));\
+	mem = RTE_PTR_ADD(mem, sizeof(in));\
+} while (0)
+
+#define rte_trace_ctf_u64(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_i64(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_u32(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_i32(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_u16(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_i16(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_u8(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_i8(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_int(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_long(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_float(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_ptr(in) __rte_trace_emit_datatype(in)
+#define rte_trace_ctf_double(in) __rte_trace_emit_datatype(in)
+
+#define rte_trace_ctf_string(in)\
+do {\
+	if (unlikely(in == NULL))\
+		return;\
+	rte_strscpy(mem, in, __RTE_TRACE_EMIT_STRING_LEN_MAX);\
+	mem = RTE_PTR_ADD(mem, __RTE_TRACE_EMIT_STRING_LEN_MAX);\
+} while (0)
+
 #endif /* _RTE_TRACE_PROVIDER_H_ */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 14/32] eal/trace: hook internal trace APIs to Linux
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (12 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 13/32] eal/trace: implement provider payload jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 15/32] eal/trace: hook internal trace APIs to FreeBSD jerinj
                     ` (18 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
	skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Connect the internal trace interface API to Linux EAL.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/common/eal_common_thread.c | 3 ++-
 lib/librte_eal/linux/eal/eal.c            | 9 +++++++++
 lib/librte_eal/linux/eal/eal_thread.c     | 3 +++
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c
index 99fe1aa4e..bc9732d88 100644
--- a/lib/librte_eal/common/eal_common_thread.c
+++ b/lib/librte_eal/common/eal_common_thread.c
@@ -15,6 +15,7 @@
 #include <rte_lcore.h>
 #include <rte_memory.h>
 #include <rte_log.h>
+#include <rte_trace.h>
 
 #include "eal_internal_cfg.h"
 #include "eal_private.h"
@@ -165,7 +166,7 @@ static void *rte_thread_init(void *arg)
 		pthread_barrier_destroy(&params->configured);
 		free(params);
 	}
-
+	__rte_trace_mem_per_thread_alloc();
 	return start_routine(routine_arg);
 }
 
diff --git a/lib/librte_eal/linux/eal/eal.c b/lib/librte_eal/linux/eal/eal.c
index 9530ee55f..ee777b0cd 100644
--- a/lib/librte_eal/linux/eal/eal.c
+++ b/lib/librte_eal/linux/eal/eal.c
@@ -58,6 +58,7 @@
 #include "eal_filesystem.h"
 #include "eal_hugepages.h"
 #include "eal_memcfg.h"
+#include "eal_trace.h"
 #include "eal_options.h"
 #include "eal_vfio.h"
 #include "hotplug_mp.h"
@@ -1012,6 +1013,12 @@ rte_eal_init(int argc, char **argv)
 		return -1;
 	}
 
+	if (eal_trace_init() < 0) {
+		rte_eal_init_alert("Cannot init trace");
+		rte_errno = EFAULT;
+		return -1;
+	}
+
 	if (eal_option_device_parse()) {
 		rte_errno = ENODEV;
 		rte_atomic32_clear(&run_once);
@@ -1327,6 +1334,8 @@ rte_eal_cleanup(void)
 		rte_memseg_walk(mark_freeable, NULL);
 	rte_service_finalize();
 	rte_mp_channel_cleanup();
+	rte_trace_save();
+	eal_trace_fini();
 	eal_cleanup_config(&internal_config);
 	return 0;
 }
diff --git a/lib/librte_eal/linux/eal/eal_thread.c b/lib/librte_eal/linux/eal/eal_thread.c
index 3f82b286c..45f4dce44 100644
--- a/lib/librte_eal/linux/eal/eal_thread.c
+++ b/lib/librte_eal/linux/eal/eal_thread.c
@@ -20,6 +20,7 @@
 #include <rte_per_lcore.h>
 #include <rte_eal.h>
 #include <rte_lcore.h>
+#include <rte_trace.h>
 
 #include "eal_private.h"
 #include "eal_thread.h"
@@ -124,6 +125,8 @@ eal_thread_loop(__attribute__((unused)) void *arg)
 	RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%zx;cpuset=[%s%s])\n",
 		lcore_id, (uintptr_t)thread_id, cpuset, ret == 0 ? "" : "...");
 
+	__rte_trace_mem_per_thread_alloc();
+
 	/* read on our pipe to get commands */
 	while (1) {
 		void *fct_arg;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev] [PATCH v2 15/32] eal/trace: hook internal trace APIs to FreeBSD
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (13 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 14/32] eal/trace: hook internal trace APIs to Linux jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 16/32] eal/trace: add generic tracepoints jerinj
                     ` (17 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom, skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Connect the internal trace interface API to FreeBSD EAL.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 lib/librte_eal/freebsd/eal/eal.c        | 10 ++++++++++
 lib/librte_eal/freebsd/eal/eal_thread.c |  3 +++
 2 files changed, 13 insertions(+)

diff --git a/lib/librte_eal/freebsd/eal/eal.c b/lib/librte_eal/freebsd/eal/eal.c
index 6ae37e7e6..c453e11f2 100644
--- a/lib/librte_eal/freebsd/eal/eal.c
+++ b/lib/librte_eal/freebsd/eal/eal.c
@@ -52,6 +52,7 @@
 #include "eal_hugepages.h"
 #include "eal_options.h"
 #include "eal_memcfg.h"
+#include "eal_trace.h"
 
 #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
 
@@ -751,6 +752,13 @@ rte_eal_init(int argc, char **argv)
 		return -1;
 	}
 
+	if (eal_trace_init() < 0) {
+		rte_eal_init_alert("Cannot init trace");
+		rte_errno = EFAULT;
+		rte_atomic32_clear(&run_once);
+		return -1;
+	}
+
 	if (eal_option_device_parse()) {
 		rte_errno = ENODEV;
 		rte_atomic32_clear(&run_once);
@@ -966,6 +974,8 @@ rte_eal_cleanup(void)
 {
 	rte_service_finalize();
 	rte_mp_channel_cleanup();
+	rte_trace_save();
+	eal_trace_fini();
 	eal_cleanup_config(&internal_config);
 	return 0;
 }
diff --git a/lib/librte_eal/freebsd/eal/eal_thread.c b/lib/librte_eal/freebsd/eal/eal_thread.c
index ae7b57672..aaccb4926 100644
--- a/lib/librte_eal/freebsd/eal/eal_thread.c
+++ b/lib/librte_eal/freebsd/eal/eal_thread.c
@@ -20,6 +20,7 @@
 #include <rte_per_lcore.h>
 #include <rte_eal.h>
 #include <rte_lcore.h>
+#include <rte_trace.h>
 
 #include "eal_private.h"
 #include "eal_thread.h"
@@ -124,6 +125,8 @@ eal_thread_loop(__attribute__((unused)) void *arg)
 	RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%p;cpuset=[%s%s])\n",
 		lcore_id, thread_id, cpuset, ret == 0 ? "" : "...");
 
+	__rte_trace_mem_per_thread_alloc();
+
 	/* read on our pipe to get commands */
 	while (1) {
 		void *fct_arg;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v2 16/32] eal/trace: add generic tracepoints
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (14 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 15/32] eal/trace: hook internal trace APIs to FreeBSD jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 17/32] eal/trace: add alarm tracepoints jerinj
                     ` (16 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom, skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

This patch creates the following generic tracepoint for
generic tracing when there is no dedicated tracepoint is
available.

rte_trace_lib_eal_generic_void()
rte_trace_lib_eal_generic_u64()
rte_trace_lib_eal_generic_u32()
rte_trace_lib_eal_generic_u16()
rte_trace_lib_eal_generic_u8()
rte_trace_lib_eal_generic_i64()
rte_trace_lib_eal_generic_i32()
rte_trace_lib_eal_generic_i16()
rte_trace_lib_eal_generic_i8()
rte_trace_lib_eal_generic_int()
rte_trace_lib_eal_generic_long()
rte_trace_lib_eal_generic_float()
rte_trace_lib_eal_generic_double()
rte_trace_lib_eal_generic_ptr()
rte_trace_lib_eal_generic_str()

For example, if an application wishes to emit an int datatype,
it can call rte_trace_lib_eal_generic_int(val) to emit the trace.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
 lib/librte_eal/common/Makefile                |   2 +-
 .../common/eal_common_trace_points.c          |  60 +++++++++
 lib/librte_eal/common/include/rte_trace_eal.h | 122 ++++++++++++++++++
 lib/librte_eal/common/meson.build             |   2 +
 lib/librte_eal/freebsd/eal/Makefile           |   1 +
 lib/librte_eal/linux/eal/Makefile             |   1 +
 lib/librte_eal/rte_eal_version.map            |  17 +++
 7 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/common/eal_common_trace_points.c
 create mode 100644 lib/librte_eal/common/include/rte_trace_eal.h

diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 8f2f25c1d..452e5e93d 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -9,7 +9,7 @@ INC += rte_debug.h rte_eal.h rte_eal_interrupts.h
 INC += rte_errno.h rte_launch.h rte_lcore.h
 INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
-INC += rte_trace.h rte_trace_provider.h rte_trace_register.h
+INC += rte_trace.h rte_trace_eal.h rte_trace_provider.h rte_trace_register.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h
diff --git a/lib/librte_eal/common/eal_common_trace_points.c b/lib/librte_eal/common/eal_common_trace_points.c
new file mode 100644
index 000000000..ff521c981
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_trace_points.c
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#define RTE_TRACE_POINT_REGISTER_SELECT /* Select trace point register macros */
+
+#include <rte_trace_eal.h>
+
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_void);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_u64);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_u32);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_u16);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_u8);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_i64);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_i32);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_i16);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_i8);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_int);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_long);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_float);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_double);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_ptr);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_str);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_func);
+
+RTE_INIT(eal_trace_init)
+{
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_void,
+				 lib.eal.generic.void, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_u64,
+				 lib.eal.generic.u64, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_u32,
+				 lib.eal.generic.u32, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_u16,
+				 lib.eal.generic.u16, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_u8,
+				 lib.eal.generic.u8, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_i64,
+				 lib.eal.generic.i64, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_i32,
+				 lib.eal.generic.i32, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_i16,
+				 lib.eal.generic.i16, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_i8,
+				 lib.eal.generic.i8, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_int,
+				 lib.eal.generic.int, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_long,
+				 lib.eal.generic.long, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_float,
+				 lib.eal.generic.float, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_double,
+				 lib.eal.generic.double, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_ptr,
+				 lib.eal.generic.ptr, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_str,
+				 lib.eal.generic.string, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_func,
+				 lib.eal.generic.func, INFO);
+}
diff --git a/lib/librte_eal/common/include/rte_trace_eal.h b/lib/librte_eal/common/include/rte_trace_eal.h
new file mode 100644
index 000000000..269ef7502
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_trace_eal.h
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_TRACE_EAL_H_
+#define _RTE_TRACE_EAL_H_
+
+/**
+ * @file
+ *
+ * API for EAL trace support
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_trace.h>
+
+/* Generic */
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_void,
+	RTE_TRACE_POINT_ARGS(void),
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_u64,
+	RTE_TRACE_POINT_ARGS(uint64_t in),
+	rte_trace_ctf_u64(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_u32,
+	RTE_TRACE_POINT_ARGS(uint32_t in),
+	rte_trace_ctf_u32(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_u16,
+	RTE_TRACE_POINT_ARGS(uint16_t in),
+	rte_trace_ctf_u16(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_u8,
+	RTE_TRACE_POINT_ARGS(uint8_t in),
+	rte_trace_ctf_u8(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_i64,
+	RTE_TRACE_POINT_ARGS(int64_t in),
+	rte_trace_ctf_i64(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_i32,
+	RTE_TRACE_POINT_ARGS(int32_t in),
+	rte_trace_ctf_i32(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_i16,
+	RTE_TRACE_POINT_ARGS(int16_t in),
+	rte_trace_ctf_i16(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_i8,
+	RTE_TRACE_POINT_ARGS(int8_t in),
+	rte_trace_ctf_i8(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_int,
+	RTE_TRACE_POINT_ARGS(int in),
+	rte_trace_ctf_int(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_long,
+	RTE_TRACE_POINT_ARGS(long in),
+	rte_trace_ctf_long(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_float,
+	RTE_TRACE_POINT_ARGS(float in),
+	rte_trace_ctf_float(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_double,
+	RTE_TRACE_POINT_ARGS(double in),
+	rte_trace_ctf_double(in);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_ptr,
+	RTE_TRACE_POINT_ARGS(const void *ptr),
+	rte_trace_ctf_ptr(ptr);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_str,
+	RTE_TRACE_POINT_ARGS(const char *str),
+	rte_trace_ctf_string(str);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_generic_func,
+	RTE_TRACE_POINT_ARGS(const char *func),
+	rte_trace_ctf_string(func);
+)
+
+#define RTE_TRACE_LIB_EAL_GENERIC_FUNC rte_trace_lib_eal_generic_func(__func__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TRACE_EAL_H_ */
diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
index 4ccdf1eee..7f11377b3 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -30,6 +30,7 @@ common_sources = files(
 	'eal_common_timer.c',
 	'eal_common_trace.c',
 	'eal_common_trace_ctf.c',
+	'eal_common_trace_points.c',
 	'eal_common_trace_utils.c',
 	'eal_common_uuid.c',
 	'hotplug_mp.c',
@@ -88,6 +89,7 @@ common_headers = files(
 	'include/rte_string_fns.h',
 	'include/rte_tailq.h',
 	'include/rte_trace.h',
+	'include/rte_trace_eal.h',
 	'include/rte_trace_provider.h',
 	'include/rte_trace_register.h',
 	'include/rte_time.h',
diff --git a/lib/librte_eal/freebsd/eal/Makefile b/lib/librte_eal/freebsd/eal/Makefile
index 546d79514..07232ba97 100644
--- a/lib/librte_eal/freebsd/eal/Makefile
+++ b/lib/librte_eal/freebsd/eal/Makefile
@@ -62,6 +62,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_ctf.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_points.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_trace_utils.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c
diff --git a/lib/librte_eal/linux/eal/Makefile b/lib/librte_eal/linux/eal/Makefile
index 1980e9fc5..6158eb0b8 100644
--- a/lib/librte_eal/linux/eal/Makefile
+++ b/lib/librte_eal/linux/eal/Makefile
@@ -70,6 +70,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_ctf.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_points.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_trace_utils.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index e54e7637c..9d56715b6 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -364,4 +364,21 @@ EXPERIMENTAL {
 	rte_trace_save;
 	rte_trace_metadata_dump;
 	rte_trace_dump;
+
+	__rte_trace_lib_eal_generic_void;
+	__rte_trace_lib_eal_generic_u64;
+	__rte_trace_lib_eal_generic_u32;
+	__rte_trace_lib_eal_generic_u16;
+	__rte_trace_lib_eal_generic_u8;
+	__rte_trace_lib_eal_generic_i64;
+	__rte_trace_lib_eal_generic_i32;
+	__rte_trace_lib_eal_generic_i16;
+	__rte_trace_lib_eal_generic_i8;
+	__rte_trace_lib_eal_generic_int;
+	__rte_trace_lib_eal_generic_long;
+	__rte_trace_lib_eal_generic_float;
+	__rte_trace_lib_eal_generic_double;
+	__rte_trace_lib_eal_generic_ptr;
+	__rte_trace_lib_eal_generic_str;
+	__rte_trace_lib_eal_generic_func;
 };
-- 
2.25.1


^ permalink raw reply	[flat|nested] 142+ messages in thread

* [dpdk-dev]  [PATCH v2 17/32] eal/trace: add alarm tracepoints
  2020-03-25 21:15 ` [dpdk-dev] [PATCH v2 00/32] DPDK Trace support jerinj
                     ` (15 preceding siblings ...)
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 16/32] eal/trace: add generic tracepoints jerinj
@ 2020-03-25 21:15   ` jerinj
  2020-03-25 21:15   ` [dpdk-dev] [PATCH v2 18/32] eal/trace: add memory tracepoints jerinj
                     ` (15 subsequent siblings)
  32 siblings, 0 replies; 142+ messages in thread
From: jerinj @ 2020-03-25 21:15 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: dev, thomas, david.marchand, mattias.ronnblom, skori, Jerin Jacob

From: Jerin Jacob <jerinj@marvell.com>

Add following alarm related trace points.

rte_trace_lib_eal_alarm_set()
rte_trace_lib_eal_alarm_cancel()

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
---
 .../common/eal_common_trace_points.c           |  9 +++++++++
 lib/librte_eal/common/include/rte_trace_eal.h  | 18 ++++++++++++++++++
 lib/librte_eal/freebsd/eal/eal_alarm.c         |  3 +++
 lib/librte_eal/linux/eal/eal_alarm.c           |  4 ++++
 lib/librte_eal/rte_eal_version.map             |  2 ++
 5 files changed, 36 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_trace_points.c b/lib/librte_eal/common/eal_common_trace_points.c
index ff521c981..16261b1d6 100644
--- a/lib/librte_eal/common/eal_common_trace_points.c
+++ b/lib/librte_eal/common/eal_common_trace_points.c
@@ -23,6 +23,9 @@ RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_ptr);
 RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_str);
 RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_generic_func);
 
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_alarm_set);
+RTE_TRACE_POINT_DEFINE(rte_trace_lib_eal_alarm_cancel);
+
 RTE_INIT(eal_trace_init)
 {
 	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_void,
@@ -57,4 +60,10 @@ RTE_INIT(eal_trace_init)
 				 lib.eal.generic.string, INFO);
 	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_generic_func,
 				 lib.eal.generic.func, INFO);
+
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_alarm_set,
+				 lib.eal.alarm.set, INFO);
+	RTE_TRACE_POINT_REGISTER(rte_trace_lib_eal_alarm_cancel,
+				 lib.eal.alarm.cancel, INFO);
+
 }
diff --git a/lib/librte_eal/common/include/rte_trace_eal.h b/lib/librte_eal/common/include/rte_trace_eal.h
index 269ef7502..df1b3854b 100644
--- a/lib/librte_eal/common/include/rte_trace_eal.h
+++ b/lib/librte_eal/common/include/rte_trace_eal.h
@@ -15,6 +15,7 @@
 extern "C" {
 #endif
 
+#include <rte_alarm.h>
 #include <rte_trace.h>
 
 /* Generic */
@@ -115,6 +116,23 @@ RTE_TRACE_POINT(
 
 #define RTE_TRACE_LIB_EAL_GENERIC_FUNC rte_trace_lib_eal_generic_func(__func__)
 
+/* Alarm */
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_alarm_set,
+	RTE_TRACE_POINT_ARGS(uint64_t us, rte_eal_alarm_callback cb_fn,
+			     void *cb_arg, int rc),
+	rte_trace_ctf_u64(us); rte_trace_ctf_ptr(cb_fn);
+	rte_trace_ctf_ptr(cb_arg); rte_trace_ctf_int(rc);
+)
+
+RTE_TRACE_POINT(
+	rte_trace_lib_eal_alarm_cancel,
+	RTE_TRACE_POINT_ARGS(rte_eal_alarm_callback cb_fn, void *cb_arg,
+			     int count),
+	rte_trace_ctf_ptr(cb_fn); rte_trace_ctf_ptr(cb_arg);
+	rte_trace_ctf_int(count);
+)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/freebsd/eal/eal_alarm.c b/lib/librte_eal/freebsd/eal/eal_alarm.c
index 51ea4b8c0..5f03ab4c4 100644
--- a/lib/librte_eal/freebsd/eal/eal_alarm.c
+++ b/lib/librte_eal/freebsd/eal/eal_alarm.c
@@ -17,6 +17,7 @@
 #include <rte_errno.h>
 #include <rte_interrupts.h>
 #include <rte_spinlock.h>
+#include <rte_trace_eal.h>
 
 #include "eal_private.h"
 #include "eal_alarm_private.h"
@@ -223,6 +224,7 @@ rte_eal_alarm_set(uint64_t us, rte_eal_alarm_callback cb_fn, void *cb_arg)
 
 	rte_spinlock_unlock(&alarm_list_lk);
 
+	rte_trace_lib_eal_alarm_set(us, cb_fn, cb_arg, ret);
 	return ret;
 }
 
@@ -310,5 +312,6 @@ rte_eal_alarm_cancel(rte_eal_alarm_callback cb_fn, void *cb_arg)
 
 	rte_spinlock_unlock(&alarm_list_lk);
 
+	rte_trace_lib_eal_alarm_cancel(cb_fn, cb_arg, count);
 	return count;
 }
diff --git a/lib/librte_eal/linux/eal/eal_alarm.c b/lib/librte_eal/linux/eal/eal_alarm.c
index 0924c9205..9fef3e6c8 100644
--- a/lib/librte_eal/linux/eal/eal_alarm.c
+++ b/lib/librte_eal/linux/eal/eal_alarm.c
@@ -20,6 +20,8 @@
 #include <rte_lcore.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
+#include <rte_trace_eal.h>
+
 #include <eal_private.h>
 
 #ifndef	TFD_NONBLOCK
@@ -172,6 +174,7 @@ rte_eal_alarm_set(uint64_t us, rte_eal_alarm_callback cb_fn, void *cb_arg)
 	}
 	rte_spinlock_unlock(&alarm_list_lk);
 
+	rte_trace_lib_eal_alarm_set(us, cb_fn, cb_arg, ret);
 	return ret;
 }
 
@@ -240,5 +243,6 @@ rte_eal_alarm_cancel(rte_eal_alarm_callback cb_fn, void *cb_arg)
 	else if (err)
 		rte_errno = err;
 
+	rte_trace