app/eventdev: add Tx first option to pipeline mode
Add Tx first support to pipeline mode tests, the transmission 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. Following example can change packet size value as 320. Example: ./dpdk-test-eventdev ... -- ... --tx_first 512 --tx_pkt_sz 320 Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> Acked-by: Jerin Jacob <jerinj@marvell.com>
This commit is contained in:
parent
31edfc4af9
commit
c9043624e3
@ -66,6 +66,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;
|
||||
|
@ -107,6 +107,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)
|
||||
{
|
||||
@ -391,6 +411,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();
|
||||
@ -472,6 +496,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 }
|
||||
};
|
||||
|
||||
@ -514,6 +540,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++) {
|
||||
|
@ -52,6 +52,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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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"
|
||||
|
@ -200,9 +200,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
|
||||
@ -672,6 +683,8 @@ Supported application command line options are following::
|
||||
--vector_size
|
||||
--vector_tmo_ns
|
||||
--per_port_pool
|
||||
--tx_first
|
||||
--tx_pkt_sz
|
||||
|
||||
|
||||
.. Note::
|
||||
@ -776,6 +789,8 @@ Supported application command line options are following::
|
||||
--vector_size
|
||||
--vector_tmo_ns
|
||||
--per_port_pool
|
||||
--tx_first
|
||||
--tx_pkt_sz
|
||||
|
||||
|
||||
.. Note::
|
||||
|
Loading…
Reference in New Issue
Block a user