From: <pbhagavatula@marvell.com>
To: <jerinj@marvell.com>
Cc: <dev@dpdk.org>, Pavan Nikhilesh <pbhagavatula@marvell.com>
Subject: [PATCH] app/eventdev: add Tx first option to pipeline mode
Date: Wed, 25 May 2022 14:30:52 +0530 [thread overview]
Message-ID: <20220525090052.5157-1-pbhagavatula@marvell.com> (raw)
From: Pavan Nikhilesh <pbhagavatula@marvell.com>
Add Tx first support to pipeline mode tests, the transmition is done
on all the ethernet ports. This helps in testing eventdev performance
with standalone loopback interfaces.
Example:
./dpdk-test-eventdev ... -- ... --tx_first 512
512 defines the number of packets to transmit.
Add an option Tx packet size, the default packet size is 64.
Example:
./dpdk-test-eventdev ... -- ... --tx_first 512 --tx_pkt_sz 320
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
app/test-eventdev/evt_common.h | 1 +
app/test-eventdev/evt_options.c | 28 ++++
app/test-eventdev/evt_options.h | 2 +
app/test-eventdev/test_pipeline_common.c | 165 ++++++++++++++++++++++-
app/test-eventdev/test_pipeline_common.h | 2 +
doc/guides/tools/testeventdev.rst | 21 ++-
6 files changed, 214 insertions(+), 5 deletions(-)
diff --git a/app/test-eventdev/evt_common.h b/app/test-eventdev/evt_common.h
index 2f301a7e79..e304998cd7 100644
--- a/app/test-eventdev/evt_common.h
+++ b/app/test-eventdev/evt_common.h
@@ -65,6 +65,7 @@ struct evt_options {
uint16_t eth_queues;
uint32_t nb_flows;
uint32_t tx_first;
+ uint16_t tx_pkt_sz;
uint32_t max_pkt_sz;
uint32_t prod_enq_burst_sz;
uint32_t deq_tmo_nsec;
diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c
index d3c704d2b3..fb17f5a159 100644
--- a/app/test-eventdev/evt_options.c
+++ b/app/test-eventdev/evt_options.c
@@ -106,6 +106,26 @@ evt_parse_eth_prod_type(struct evt_options *opt, const char *arg __rte_unused)
return 0;
}
+static int
+evt_parse_tx_first(struct evt_options *opt, const char *arg __rte_unused)
+{
+ int ret;
+
+ ret = parser_read_uint32(&(opt->tx_first), arg);
+
+ return ret;
+}
+
+static int
+evt_parse_tx_pkt_sz(struct evt_options *opt, const char *arg __rte_unused)
+{
+ int ret;
+
+ ret = parser_read_uint16(&(opt->tx_pkt_sz), arg);
+
+ return ret;
+}
+
static int
evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused)
{
@@ -376,6 +396,10 @@ usage(char *program)
"\t--vector_size : Max vector size.\n"
"\t--vector_tmo_ns : Max vector timeout in nanoseconds\n"
"\t--per_port_pool : Configure unique pool per ethdev port\n"
+ "\t--tx_first : Transmit given number of packets\n"
+ " across all the ethernet devices before\n"
+ " event workers start.\n"
+ "\t--tx_pkt_sz : Packet size to use with Tx first."
);
printf("available tests:\n");
evt_test_dump_names();
@@ -456,6 +480,8 @@ static struct option lgopts[] = {
{ EVT_VECTOR_TMO, 1, 0, 0 },
{ EVT_PER_PORT_POOL, 0, 0, 0 },
{ EVT_HELP, 0, 0, 0 },
+ { EVT_TX_FIRST, 1, 0, 0 },
+ { EVT_TX_PKT_SZ, 1, 0, 0 },
{ NULL, 0, 0, 0 }
};
@@ -497,6 +523,8 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt)
{ EVT_VECTOR_SZ, evt_parse_vector_size},
{ EVT_VECTOR_TMO, evt_parse_vector_tmo_ns},
{ EVT_PER_PORT_POOL, evt_parse_per_port_pool},
+ { EVT_TX_FIRST, evt_parse_tx_first},
+ { EVT_TX_PKT_SZ, evt_parse_tx_pkt_sz},
};
for (i = 0; i < RTE_DIM(parsermap); i++) {
diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h
index 2231c58801..4aa06976b7 100644
--- a/app/test-eventdev/evt_options.h
+++ b/app/test-eventdev/evt_options.h
@@ -51,6 +51,8 @@
#define EVT_VECTOR_SZ ("vector_size")
#define EVT_VECTOR_TMO ("vector_tmo_ns")
#define EVT_PER_PORT_POOL ("per_port_pool")
+#define EVT_TX_FIRST ("tx_first")
+#define EVT_TX_PKT_SZ ("tx_pkt_sz")
#define EVT_HELP ("help")
void evt_options_default(struct evt_options *opt);
diff --git a/app/test-eventdev/test_pipeline_common.c b/app/test-eventdev/test_pipeline_common.c
index c66656cd39..82fe04258b 100644
--- a/app/test-eventdev/test_pipeline_common.c
+++ b/app/test-eventdev/test_pipeline_common.c
@@ -56,14 +56,170 @@ processed_pkts(struct test_pipeline *t)
return total;
}
+/* RFC863 discard port */
+#define UDP_SRC_PORT 9
+#define UDP_DST_PORT 9
+
+/* RFC2544 reserved test subnet 192.18.0.0 */
+#define IP_SRC_ADDR(x, y) ((192U << 24) | (18 << 16) | ((x) << 8) | (y))
+#define IP_DST_ADDR(x, y) ((192U << 24) | (18 << 16) | ((x) << 8) | (y))
+
+#define IP_DEFTTL 64 /* from RFC 1340. */
+#define IP_VERSION 0x40
+#define IP_HDRLEN 0x05 /* default IP header length == five 32-bits words. */
+#define IP_VHL_DEF (IP_VERSION | IP_HDRLEN)
+
+static void
+setup_pkt_udp_ip_headers(struct rte_ipv4_hdr *ip_hdr,
+ struct rte_udp_hdr *udp_hdr, uint16_t pkt_data_len,
+ uint8_t port, uint8_t flow)
+{
+ uint16_t *ptr16;
+ uint32_t ip_cksum;
+ uint16_t pkt_len;
+
+ /*
+ * Initialize UDP header.
+ */
+ pkt_len = (uint16_t)(pkt_data_len + sizeof(struct rte_udp_hdr));
+ udp_hdr->src_port = rte_cpu_to_be_16(UDP_SRC_PORT);
+ udp_hdr->dst_port = rte_cpu_to_be_16(UDP_DST_PORT);
+ udp_hdr->dgram_len = rte_cpu_to_be_16(pkt_len);
+ udp_hdr->dgram_cksum = 0; /* No UDP checksum. */
+
+ /*
+ * Initialize IP header.
+ */
+ pkt_len = (uint16_t)(pkt_len + sizeof(struct rte_ipv4_hdr));
+ ip_hdr->version_ihl = IP_VHL_DEF;
+ ip_hdr->type_of_service = 0;
+ ip_hdr->fragment_offset = 0;
+ ip_hdr->time_to_live = IP_DEFTTL;
+ ip_hdr->next_proto_id = IPPROTO_UDP;
+ ip_hdr->packet_id = 0;
+ ip_hdr->total_length = rte_cpu_to_be_16(pkt_len);
+ ip_hdr->src_addr = rte_cpu_to_be_32(IP_SRC_ADDR(port, 1));
+ ip_hdr->dst_addr = rte_cpu_to_be_32(IP_DST_ADDR(port + 1, flow));
+
+ /*
+ * Compute IP header checksum.
+ */
+ ptr16 = (unaligned_uint16_t *)ip_hdr;
+ ip_cksum = 0;
+ ip_cksum += ptr16[0];
+ ip_cksum += ptr16[1];
+ ip_cksum += ptr16[2];
+ ip_cksum += ptr16[3];
+ ip_cksum += ptr16[4];
+ ip_cksum += ptr16[6];
+ ip_cksum += ptr16[7];
+ ip_cksum += ptr16[8];
+ ip_cksum += ptr16[9];
+
+ /*
+ * Reduce 32 bit checksum to 16 bits and complement it.
+ */
+ ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) + (ip_cksum & 0x0000FFFF);
+ if (ip_cksum > 65535)
+ ip_cksum -= 65535;
+ ip_cksum = (~ip_cksum) & 0x0000FFFF;
+ if (ip_cksum == 0)
+ ip_cksum = 0xFFFF;
+ ip_hdr->hdr_checksum = (uint16_t)ip_cksum;
+}
+
+static void
+pipeline_tx_first(struct test_pipeline *t, struct evt_options *opt)
+{
+#define TX_DEF_PACKET_LEN 64
+ uint16_t eth_port_id = 0;
+ uint16_t pkt_sz, rc;
+ uint32_t i;
+
+ pkt_sz = opt->tx_pkt_sz;
+ if (pkt_sz > opt->max_pkt_sz)
+ pkt_sz = opt->max_pkt_sz;
+ if (!pkt_sz)
+ pkt_sz = TX_DEF_PACKET_LEN;
+
+ RTE_ETH_FOREACH_DEV(eth_port_id) {
+ struct rte_ether_addr src_mac;
+ struct rte_ether_addr dst_mac;
+ struct rte_ether_hdr eth_hdr;
+
+ /* Send to the same dest.mac as port mac */
+ rte_eth_macaddr_get(eth_port_id, &dst_mac);
+ rte_eth_random_addr((uint8_t *)&src_mac);
+
+ rte_ether_addr_copy(&dst_mac, ð_hdr.dst_addr);
+ rte_ether_addr_copy(&src_mac, ð_hdr.src_addr);
+ eth_hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
+
+ for (i = 0; i < opt->tx_first; i++) {
+ struct rte_udp_hdr *pkt_udp_hdr;
+ struct rte_ipv4_hdr ip_hdr;
+ struct rte_udp_hdr udp_hdr;
+ struct rte_mbuf *mbuf;
+
+ mbuf = rte_pktmbuf_alloc(
+ opt->per_port_pool ? t->pool[i] : t->pool[0]);
+ if (mbuf == NULL)
+ continue;
+
+ setup_pkt_udp_ip_headers(
+ &ip_hdr, &udp_hdr,
+ pkt_sz - sizeof(struct rte_ether_hdr) -
+ sizeof(struct rte_ipv4_hdr) -
+ sizeof(struct rte_udp_hdr),
+ eth_port_id, i);
+ mbuf->port = eth_port_id;
+ mbuf->data_len = pkt_sz;
+ mbuf->pkt_len = pkt_sz;
+
+ /* Copy Ethernet header */
+ rte_memcpy(rte_pktmbuf_mtod_offset(mbuf, char *, 0),
+ ð_hdr, sizeof(struct rte_ether_hdr));
+
+ /* Copy Ipv4 header */
+ rte_memcpy(rte_pktmbuf_mtod_offset(
+ mbuf, char *,
+ sizeof(struct rte_ether_hdr)),
+ &ip_hdr, sizeof(struct rte_ipv4_hdr));
+
+ /* Copy UDP header */
+ rte_memcpy(
+ rte_pktmbuf_mtod_offset(
+ mbuf, char *,
+ sizeof(struct rte_ipv4_hdr) +
+ sizeof(struct rte_ether_hdr)),
+ &udp_hdr, sizeof(struct rte_udp_hdr));
+ pkt_udp_hdr = rte_pktmbuf_mtod_offset(
+ mbuf, struct rte_udp_hdr *,
+ sizeof(struct rte_ipv4_hdr) +
+ sizeof(struct rte_ether_hdr));
+ pkt_udp_hdr->src_port =
+ rte_cpu_to_be_16(UDP_SRC_PORT + i);
+ pkt_udp_hdr->dst_port =
+ rte_cpu_to_be_16(UDP_SRC_PORT + i);
+
+ rc = rte_eth_tx_burst(eth_port_id, 0, &mbuf, 1);
+ if (rc == 0)
+ rte_pktmbuf_free(mbuf);
+ }
+ }
+}
+
int
pipeline_launch_lcores(struct evt_test *test, struct evt_options *opt,
int (*worker)(void *))
{
- int ret, lcore_id;
struct test_pipeline *t = evt_test_priv(test);
-
+ int ret, lcore_id;
int port_idx = 0;
+
+ if (opt->tx_first)
+ pipeline_tx_first(t, opt);
+
/* launch workers */
RTE_LCORE_FOREACH_WORKER(lcore_id) {
if (!(opt->wlcores[lcore_id]))
@@ -155,6 +311,11 @@ pipeline_opt_check(struct evt_options *opt, uint64_t nb_queues)
return -1;
}
+ if (opt->prod_type != EVT_PROD_TYPE_ETH_RX_ADPTR) {
+ evt_err("Invalid producer type, only --prod_type_ethdev is supported");
+ return -1;
+ }
+
if (evt_has_invalid_stage(opt))
return -1;
diff --git a/app/test-eventdev/test_pipeline_common.h b/app/test-eventdev/test_pipeline_common.h
index a6443faea4..2b7f3e7d0f 100644
--- a/app/test-eventdev/test_pipeline_common.h
+++ b/app/test-eventdev/test_pipeline_common.h
@@ -12,6 +12,7 @@
#include <rte_cycles.h>
#include <rte_ethdev.h>
+#include <rte_ether.h>
#include <rte_event_eth_rx_adapter.h>
#include <rte_event_eth_tx_adapter.h>
#include <rte_eventdev.h>
@@ -22,6 +23,7 @@
#include <rte_service.h>
#include <rte_service_component.h>
#include <rte_spinlock.h>
+#include <rte_udp.h>
#include "evt_common.h"
#include "evt_options.h"
diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst
index f7d813226d..eba0030c44 100644
--- a/doc/guides/tools/testeventdev.rst
+++ b/doc/guides/tools/testeventdev.rst
@@ -195,9 +195,20 @@ The following are the application command-line options:
* ``--per_port_pool``
- Configure unique mempool per ethernet device, the size of each pool
- is equal to `pool_sz`.
- Only applicable for pipeline_atq` and `pipeline_queue` tests.
+ Configure unique mempool per ethernet device, the size of each pool
+ is equal to `pool_sz`.
+ Only applicable for `pipeline_atq` and `pipeline_queue` tests.
+
+* ``--tx_first``
+
+ Transmit given number of packets across all the ethernet device that
+ are enabled in the test.
+ Only applicable for `pipeline_atq` and `pipeline_queue` tests.
+
+* ``--tx_pkt_sz``
+
+ Packet size to use for `--tx_first`.
+ Only applicable for `pipeline_atq` and `pipeline_queue` tests.
Eventdev Tests
@@ -667,6 +678,8 @@ Supported application command line options are following::
--vector_size
--vector_tmo_ns
--per_port_pool
+ --tx_first
+ --tx_pkt_sz
.. Note::
@@ -771,6 +784,8 @@ Supported application command line options are following::
--vector_size
--vector_tmo_ns
--per_port_pool
+ --tx_first
+ --tx_pkt_sz
.. Note::
--
2.25.1
next reply other threads:[~2022-05-25 9:01 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-25 9:00 pbhagavatula [this message]
2022-06-13 5:53 ` Jerin Jacob
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220525090052.5157-1-pbhagavatula@marvell.com \
--to=pbhagavatula@marvell.com \
--cc=dev@dpdk.org \
--cc=jerinj@marvell.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).