From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id A0D9C423AA; Wed, 11 Jan 2023 09:54:12 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 966F941611; Wed, 11 Jan 2023 09:54:12 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 4EB7E4014F for ; Wed, 11 Jan 2023 09:54:11 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 30B15g1e016756 for ; Wed, 11 Jan 2023 00:54:10 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=PBd58DCMuhC6RO0B4IH4C02kEewOkAz9QNIetVhgAqw=; b=dG0R+2rryhTh3jCuhxzGvo/5ia8iBYJUSKYricq9BiWtFdCc2qUrJq0Vedw4Fjpnm5Nf WaxSnCbWiEQJfyWSBksVqYwSBckEfTv67T8AqFBkkcHiV7w1afl3GpS+YhDrmH4Bu75p IiMex+NBe5QnWlP6VHnQMWWmaiTcwUFoDZkfwTgU/f40VNB5cKqcNI+Hz3OkoXKYBbvb himg0XW/f0SvgrDepgsNyBSZ9XwybsRuzkrxVrINjjJWwAlYdjp0iAcpJU1FPyzzU3Th +1CekmRngGaNwjLYF416YQOvHi5gEqHrx//fNCtO3PAVXCMF0b4XYtW8aaz5bxXZ4rpi fQ== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3n1k56sfhg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Wed, 11 Jan 2023 00:54:10 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Wed, 11 Jan 2023 00:54:08 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.42 via Frontend Transport; Wed, 11 Jan 2023 00:54:08 -0800 Received: from localhost.localdomain (unknown [10.28.36.157]) by maili.marvell.com (Postfix) with ESMTP id 4C7253F7055; Wed, 11 Jan 2023 00:54:05 -0800 (PST) From: Amit Prakash Shukla To: Jerin Jacob , Kiran Kumar K , Nithin Dabilpuram CC: , Amit Prakash Shukla Subject: [PATCH v2 2/3] graph: pcap capture for graph nodes Date: Wed, 11 Jan 2023 14:23:41 +0530 Message-ID: <20230111085343.2058993-2-amitprakashs@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230111085343.2058993-1-amitprakashs@marvell.com> References: <20230110115847.1965096-1-amitprakashs@marvell.com> <20230111085343.2058993-1-amitprakashs@marvell.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-ORIG-GUID: UItaADytiy-rFMpIL9TYpeFPnkr0vXf9 X-Proofpoint-GUID: UItaADytiy-rFMpIL9TYpeFPnkr0vXf9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2023-01-11_03,2023-01-10_03,2022-06-22_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Implementation adds support to capture packets at each node with packet metadata and node name. Signed-off-by: Amit Prakash Shukla --- v2: - Fixed code style issue - Fixed CI compilation issue on github-robot lib/graph/graph_pcap_trace.c | 165 +++++++++++++++++++++++++++++++ lib/graph/graph_populate.c | 6 +- lib/graph/graph_private.h | 21 ++++ lib/graph/meson.build | 5 +- lib/graph/rte_graph_pcap_trace.h | 96 ++++++++++++++++++ lib/graph/rte_graph_worker.h | 3 + lib/graph/version.map | 7 ++ 7 files changed, 300 insertions(+), 3 deletions(-) create mode 100644 lib/graph/graph_pcap_trace.c create mode 100644 lib/graph/rte_graph_pcap_trace.h diff --git a/lib/graph/graph_pcap_trace.c b/lib/graph/graph_pcap_trace.c new file mode 100644 index 0000000000..7f29043fcd --- /dev/null +++ b/lib/graph/graph_pcap_trace.c @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2022 Marvell International Ltd. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "rte_graph_worker.h" +#include "graph_private.h" + +#define GRAPH_PCAP_BUF_SZ 128 +#define GRAPH_PCAP_NUM_PACKETS 1024 +#define GRAPH_PCAP_FILE_NAME_SZ 128 +#define GRAPH_PCAP_FILE_NAME "/tmp/graph_pcap_capture.pcapng" + +#define PCAP_DUMP_DATA(dbuf, buf_size, cur_len, sbuf, len) \ +do { \ + if ((cur_len + len) >= buf_size) \ + break; \ + rte_memcpy(dbuf + cur_len, sbuf, len); \ + cur_len += len; \ +} while (0) + +static char file_name[GRAPH_PCAP_FILE_NAME_SZ]; +static uint32_t pkt_buf_sz = RTE_MBUF_DEFAULT_BUF_SIZE; +static uint64_t packet_to_capture = GRAPH_PCAP_NUM_PACKETS; +static rte_pcapng_t *pcapng_fd; +static struct rte_mempool *mp; +static uint16_t port_id; +static uint64_t packet_captured[RTE_MAX_LCORE]; +static int pcap_trace_enable; + +void +rte_num_pkt_to_capture(uint64_t val) +{ + packet_to_capture = val; +} + +void +rte_pcap_trace_enable(int val) +{ + pcap_trace_enable = val; +} + +int +rte_pcap_trace_is_enable(void) +{ + return pcap_trace_enable; +} + +void +rte_filename_to_capture_pkt(const char *filename) +{ + if (filename[0] == '\0') + rte_strscpy(file_name, GRAPH_PCAP_FILE_NAME, + GRAPH_PCAP_FILE_NAME_SZ); + else + rte_strscpy(file_name, filename, GRAPH_PCAP_FILE_NAME_SZ); +} + +void +rte_graph_pcap_trace_exit(void) +{ + rte_pcapng_close(pcapng_fd); +} + +int +rte_graph_pcap_trace_init(void) +{ + int fd; + + port_id = rte_eth_find_next(0); + if (port_id >= RTE_MAX_ETHPORTS) { + fprintf(stderr, "No valid Ether port\n"); + return -1; + } + + if (file_name[0] == '\0') + rte_strscpy(file_name, GRAPH_PCAP_FILE_NAME, + GRAPH_PCAP_FILE_NAME_SZ); + + fd = open(file_name, O_CREAT | O_TRUNC | O_WRONLY, 0664); + if (fd < 0) { + perror("pcap file open failure"); + return -1; + } + + fprintf(stdout, "pcapng: output file %s\n", file_name); + + /* open a test capture file */ + pcapng_fd = rte_pcapng_fdopen(fd, NULL, NULL, "Graph pcap tracer", NULL); + if (pcapng_fd == NULL) { + fprintf(stderr, "Graph rte_pcapng_fdopen failed\n"); + close(fd); + return -1; + } + + /* Make a pool for cloned packets */ + mp = rte_pktmbuf_pool_create_by_ops("pcapng_graph_pool", + IOV_MAX + RTE_GRAPH_BURST_SIZE, + 0, 0, rte_pcapng_mbuf_size(pkt_buf_sz), + SOCKET_ID_ANY, "ring_mp_sc"); + if (mp == NULL) { + fprintf(stderr, "Cannot create mempool for graph pcap capture\n"); + rte_pcapng_close(pcapng_fd); + return -1; + } + + return 0; +} + +uint16_t +rte_graph_pcap_trace_dispatch(struct rte_graph *graph __rte_unused, + struct rte_node *node, void **objs, + uint16_t nb_objs) +{ + uint64_t i, num_packets; + struct rte_mbuf *mbuf_clones[RTE_GRAPH_BURST_SIZE] = { }; + char buffer[GRAPH_PCAP_BUF_SZ] = {0}; + struct rte_mbuf *mbuf; + uint16_t cb_len = 0; + ssize_t len; + uint16_t gid = graph->id; + + if (!nb_objs || (packet_captured[gid] >= packet_to_capture)) + goto done; + + num_packets = packet_to_capture - packet_captured[gid]; + /* nb_objs will never be greater than RTE_GRAPH_BURST_SIZE */ + if (num_packets > nb_objs) + num_packets = nb_objs; + + PCAP_DUMP_DATA(buffer, GRAPH_PCAP_BUF_SZ, cb_len, node->name, + (strlen(node->name) + 1)); + + for (i = 0; i < num_packets; i++) { + struct rte_mbuf *mc; + mbuf = (struct rte_mbuf *)objs[i]; + + mc = rte_pcapng_copy(port_id, 0, mbuf, mp, mbuf->pkt_len, + rte_get_tsc_cycles(), 0, buffer); + if (mc == NULL) + goto done; + + mbuf_clones[i] = mc; + } + + /* write it to capture file */ + len = rte_pcapng_write_packets(pcapng_fd, mbuf_clones, i); + rte_pktmbuf_free_bulk(mbuf_clones, i); + if (len <= 0) + goto done; + + packet_captured[gid] += i; + +done: + return node->original_process(graph, node, objs, nb_objs); +} diff --git a/lib/graph/graph_populate.c b/lib/graph/graph_populate.c index 102fd6c29b..aa26b1c51d 100644 --- a/lib/graph/graph_populate.c +++ b/lib/graph/graph_populate.c @@ -75,7 +75,11 @@ graph_nodes_populate(struct graph *_graph) memset(node, 0, sizeof(*node)); node->fence = RTE_GRAPH_FENCE; node->off = off; - node->process = graph_node->node->process; + if (rte_pcap_trace_is_enable()) { + node->process = rte_graph_pcap_trace_dispatch; + node->original_process = graph_node->node->process; + } else + node->process = graph_node->node->process; memcpy(node->name, graph_node->node->name, RTE_GRAPH_NAMESIZE); pid = graph_node->node->parent_id; if (pid != RTE_NODE_ID_INVALID) { /* Cloned node */ diff --git a/lib/graph/graph_private.h b/lib/graph/graph_private.h index f9a85c8926..3edbb42692 100644 --- a/lib/graph/graph_private.h +++ b/lib/graph/graph_private.h @@ -319,6 +319,27 @@ struct rte_node *graph_node_id_to_ptr(const struct rte_graph *graph, struct rte_node *graph_node_name_to_ptr(const struct rte_graph *graph, const char *node_name); +/** + * @internal + * + * Capture mbuf metadata and node metadata to a pcap file. + * + * When graph pcap trace enabled, this function is invoked prior to each node + * and mbuf, node metadata is parsed and captured in a pcap file. + * + * @param graph + * Pointer to the graph object. + * @param node + * Pointer to the node object. + * @param objs + * Pointer to an array of objects to be processed. + * @param nb_objs + * Number of objects in the array. + */ +uint16_t rte_graph_pcap_trace_dispatch(struct rte_graph *graph __rte_unused, + struct rte_node *node, void **objs, + uint16_t nb_objs); + /* Debug functions */ /** * @internal diff --git a/lib/graph/meson.build b/lib/graph/meson.build index c7327549e8..955c051a20 100644 --- a/lib/graph/meson.build +++ b/lib/graph/meson.build @@ -14,7 +14,8 @@ sources = files( 'graph_debug.c', 'graph_stats.c', 'graph_populate.c', + 'graph_pcap_trace.c', ) -headers = files('rte_graph.h', 'rte_graph_worker.h') +headers = files('rte_graph.h', 'rte_graph_worker.h', 'rte_graph_pcap_trace.h') -deps += ['eal'] +deps += ['eal', 'mbuf', 'ethdev', 'pcapng'] diff --git a/lib/graph/rte_graph_pcap_trace.h b/lib/graph/rte_graph_pcap_trace.h new file mode 100644 index 0000000000..2af807c95b --- /dev/null +++ b/lib/graph/rte_graph_pcap_trace.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2022 Marvell International Ltd. + */ + +#ifndef _RTE_GRAPH_PCAP_TRACE_H_ +#define _RTE_GRAPH_PCAP_TRACE_H_ + +/** + * @file rte_graph_pcap_trace.h + * + * @warning + * @b EXPERIMENTAL: + * All functions in this file may be changed or removed without prior notice. + * + * This API enables to capture packet at each node with mbuf and node metadata. + * + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Pcap trace enable/disable function. + * + * The function is called to enable/disable graph pcap trace functionality. + * + * @param val + * Value to be set to enable/disable graph pcap trace. + */ +__rte_experimental +void rte_pcap_trace_enable(int val); + +/** + * Check graph pcap trace is enable/disable. + * + * The function is called to check if the graph pcap trace is enabled/disabled. + * + * @return + * - 1: Enable + * - 0: Disable + */ +__rte_experimental +int rte_pcap_trace_is_enable(void); + +/** + * Initialise graph pcap trace functionality. + * + * The function invoked when the graph pcap trace is enabled from the + * application. + * + * @return + * 0 on success and -1 on failure. + */ +__rte_experimental +int rte_graph_pcap_trace_init(void); + +/** + * Pcap trace set number of packets to capture. + * + * The function is called to configure total number of packets to be captured. + * + * @param val + * Number of packets to capture. + */ +__rte_experimental +void rte_num_pkt_to_capture(uint64_t val); + +/** + * Pcap trace file name to capture packets. + * + * The function is called to configure file name to capture packets in. + * + * @param filename + * Number of packets to capture. + */ +__rte_experimental +void rte_filename_to_capture_pkt(const char *filename); + +/** + * Exit graph pcap trace functionality. + * + * The function is called to exit graph pcap trace and close open fd's. + */ +__rte_experimental +void rte_graph_pcap_trace_exit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_GRAPH_PCAP_TRACE_H_ */ diff --git a/lib/graph/rte_graph_worker.h b/lib/graph/rte_graph_worker.h index fc6fee48c8..fcaedbdb12 100644 --- a/lib/graph/rte_graph_worker.h +++ b/lib/graph/rte_graph_worker.h @@ -24,6 +24,7 @@ #include #include "rte_graph.h" +#include "rte_graph_pcap_trace.h" #ifdef __cplusplus extern "C" { @@ -64,6 +65,8 @@ struct rte_node { char parent[RTE_NODE_NAMESIZE]; /**< Parent node name. */ char name[RTE_NODE_NAMESIZE]; /**< Name of the node. */ + rte_node_process_t original_process; /**< Pcap enabled node callback */ + /* Fast path area */ #define RTE_NODE_CTX_SZ 16 uint8_t ctx[RTE_NODE_CTX_SZ] __rte_cache_aligned; /**< Node Context. */ diff --git a/lib/graph/version.map b/lib/graph/version.map index 13b838752d..36153a75b2 100644 --- a/lib/graph/version.map +++ b/lib/graph/version.map @@ -43,5 +43,12 @@ EXPERIMENTAL { rte_node_next_stream_put; rte_node_next_stream_move; + rte_pcap_trace_is_enable; + rte_pcap_trace_enable; + rte_graph_pcap_trace_init; + rte_num_pkt_to_capture; + rte_filename_to_capture_pkt; + rte_graph_pcap_trace_exit; + local: *; }; -- 2.25.1