#include "test_pipeline_common.h"
-static int32_t
-pipeline_event_tx_burst_service_func(void *args)
-{
-
- int i;
- struct tx_service_data *tx = args;
- const uint8_t dev = tx->dev_id;
- const uint8_t port = tx->port_id;
- struct rte_event ev[BURST_SIZE + 1];
-
- uint16_t nb_rx = rte_event_dequeue_burst(dev, port, ev, BURST_SIZE, 0);
-
- if (!nb_rx) {
- for (i = 0; i < tx->nb_ethports; i++)
- rte_eth_tx_buffer_flush(i, 0, tx->tx_buf[i]);
- return 0;
- }
-
- for (i = 0; i < nb_rx; i++) {
- struct rte_mbuf *m = ev[i].mbuf;
- rte_eth_tx_buffer(m->port, 0, tx->tx_buf[m->port], m);
- }
- tx->processed_pkts += nb_rx;
-
- return 0;
-}
-
-static int32_t
-pipeline_event_tx_service_func(void *args)
-{
-
- int i;
- struct tx_service_data *tx = args;
- const uint8_t dev = tx->dev_id;
- const uint8_t port = tx->port_id;
- struct rte_event ev;
-
- uint16_t nb_rx = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
-
- if (!nb_rx) {
- for (i = 0; i < tx->nb_ethports; i++)
- rte_eth_tx_buffer_flush(i, 0, tx->tx_buf[i]);
- return 0;
- }
-
- struct rte_mbuf *m = ev.mbuf;
- rte_eth_tx_buffer(m->port, 0, tx->tx_buf[m->port], m);
- tx->processed_pkts++;
-
- return 0;
-}
-
int
pipeline_test_result(struct evt_test *test, struct evt_options *opt)
{
uint64_t total = 0;
struct test_pipeline *t = evt_test_priv(test);
- printf("Packet distribution across worker cores :\n");
+ evt_info("Packet distribution across worker cores :");
for (i = 0; i < t->nb_workers; i++)
total += t->worker[i].processed_pkts;
for (i = 0; i < t->nb_workers; i++)
- printf("Worker %d packets: "CLGRN"%"PRIx64" "CLNRM"percentage:"
- CLGRN" %3.2f\n"CLNRM, i,
+ evt_info("Worker %d packets: "CLGRN"%"PRIx64""CLNRM" percentage:"
+ CLGRN" %3.2f"CLNRM, i,
t->worker[i].processed_pkts,
(((double)t->worker[i].processed_pkts)/total)
* 100);
uint64_t total = 0;
rte_smp_rmb();
- if (t->mt_unsafe)
- total = t->tx_service.processed_pkts;
- else
- for (i = 0; i < t->nb_workers; i++)
- total += t->worker[i].processed_pkts;
+ for (i = 0; i < t->nb_workers; i++)
+ total += t->worker[i].processed_pkts;
return total;
}
*/
lcores = 2;
+ if (opt->prod_type != EVT_PROD_TYPE_ETH_RX_ADPTR) {
+ evt_err("Invalid producer type '%s' valid producer '%s'",
+ evt_prod_id_to_name(opt->prod_type),
+ evt_prod_id_to_name(EVT_PROD_TYPE_ETH_RX_ADPTR));
+ return -1;
+ }
+
if (!rte_eth_dev_count_avail()) {
evt_err("test needs minimum 1 ethernet dev");
return -1;
pipeline_ethdev_setup(struct evt_test *test, struct evt_options *opt)
{
uint16_t i;
+ int ret;
uint8_t nb_queues = 1;
- uint8_t mt_state = 0;
struct test_pipeline *t = evt_test_priv(test);
struct rte_eth_rxconf rx_conf;
struct rte_eth_conf port_conf = {
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
- .max_rx_pkt_len = ETHER_MAX_LEN,
- .offloads = DEV_RX_OFFLOAD_CRC_STRIP,
- .ignore_offload_bitfield = 1,
},
.rx_adv_conf = {
.rss_conf = {
},
};
- RTE_SET_USED(opt);
if (!rte_eth_dev_count_avail()) {
- evt_err("No ethernet ports found.\n");
+ evt_err("No ethernet ports found.");
return -ENODEV;
}
+ if (opt->max_pkt_sz < RTE_ETHER_MIN_LEN) {
+ evt_err("max_pkt_sz can not be less than %d",
+ RTE_ETHER_MIN_LEN);
+ return -EINVAL;
+ }
+
+ port_conf.rxmode.max_rx_pkt_len = opt->max_pkt_sz;
+ if (opt->max_pkt_sz > RTE_ETHER_MAX_LEN)
+ port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
+
+ t->internal_port = 1;
RTE_ETH_FOREACH_DEV(i) {
struct rte_eth_dev_info dev_info;
+ struct rte_eth_conf local_port_conf = port_conf;
+ uint32_t caps = 0;
+
+ ret = rte_event_eth_tx_adapter_caps_get(opt->dev_id, i, &caps);
+ if (ret != 0) {
+ evt_err("failed to get event tx adapter[%d] caps", i);
+ return ret;
+ }
+
+ if (!(caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT))
+ t->internal_port = 0;
+
+ ret = rte_eth_dev_info_get(i, &dev_info);
+ if (ret != 0) {
+ evt_err("Error during getting device (port %u) info: %s\n",
+ i, strerror(-ret));
+ return ret;
+ }
- memset(&dev_info, 0, sizeof(struct rte_eth_dev_info));
- rte_eth_dev_info_get(i, &dev_info);
- mt_state = !(dev_info.tx_offload_capa &
- DEV_TX_OFFLOAD_MT_LOCKFREE);
rx_conf = dev_info.default_rxconf;
rx_conf.offloads = port_conf.rxmode.offloads;
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
+ dev_info.flow_type_rss_offloads;
+ if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
+ port_conf.rx_adv_conf.rss_conf.rss_hf) {
+ evt_info("Port %u modified RSS hash function based on hardware support,"
+ "requested:%#"PRIx64" configured:%#"PRIx64"",
+ i,
+ port_conf.rx_adv_conf.rss_conf.rss_hf,
+ local_port_conf.rx_adv_conf.rss_conf.rss_hf);
+ }
+
if (rte_eth_dev_configure(i, nb_queues, nb_queues,
- &port_conf)
+ &local_port_conf)
< 0) {
- evt_err("Failed to configure eth port [%d]\n", i);
+ evt_err("Failed to configure eth port [%d]", i);
return -EINVAL;
}
if (rte_eth_rx_queue_setup(i, 0, NB_RX_DESC,
rte_socket_id(), &rx_conf, t->pool) < 0) {
- evt_err("Failed to setup eth port [%d] rx_queue: %d.\n",
+ evt_err("Failed to setup eth port [%d] rx_queue: %d.",
i, 0);
return -EINVAL;
}
if (rte_eth_tx_queue_setup(i, 0, NB_TX_DESC,
rte_socket_id(), NULL) < 0) {
- evt_err("Failed to setup eth port [%d] tx_queue: %d.\n",
+ evt_err("Failed to setup eth port [%d] tx_queue: %d.",
i, 0);
return -EINVAL;
}
- t->mt_unsafe |= mt_state;
- t->tx_service.tx_buf[i] =
- rte_malloc(NULL, RTE_ETH_TX_BUFFER_SIZE(BURST_SIZE), 0);
- if (t->tx_service.tx_buf[i] == NULL)
- rte_panic("Unable to allocate Tx buffer memory.");
- rte_eth_promiscuous_enable(i);
+ ret = rte_eth_promiscuous_enable(i);
+ if (ret != 0) {
+ evt_err("Failed to enable promiscuous mode for eth port [%d]: %s",
+ i, rte_strerror(-ret));
+ return ret;
+ }
}
return 0;
uint8_t *queue_arr, uint8_t nb_queues,
const struct rte_event_port_conf p_conf)
{
- int i;
int ret;
uint8_t port;
struct test_pipeline *t = evt_test_priv(test);
return ret;
}
- if (queue_arr == NULL) {
- if (rte_event_port_link(opt->dev_id, port, NULL, NULL,
- 0) != nb_queues)
- goto link_fail;
- } else {
- for (i = 0; i < nb_queues; i++) {
- if (rte_event_port_link(opt->dev_id, port,
- &queue_arr[i], NULL, 1) != 1)
- goto link_fail;
- }
- }
+ if (rte_event_port_link(opt->dev_id, port, queue_arr, NULL,
+ nb_queues) != nb_queues)
+ goto link_fail;
}
return 0;
link_fail:
- evt_err("failed to link all queues to port %d", port);
+ evt_err("failed to link queues to port %d", port);
return -EINVAL;
}
}
if (!(cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT)) {
- uint32_t service_id;
+ uint32_t service_id = -1U;
rte_event_eth_rx_adapter_service_id_get(prod,
&service_id);
ret = evt_service_setup(service_id);
if (ret) {
evt_err("Failed to setup service core"
- " for Rx adapter\n");
+ " for Rx adapter");
return ret;
}
}
- ret = rte_eth_dev_start(prod);
- if (ret) {
- evt_err("Ethernet dev [%d] failed to start."
- " Using synthetic producer", prod);
- return ret;
- }
-
- ret = rte_event_eth_rx_adapter_start(prod);
- if (ret) {
- evt_err("Rx adapter[%d] start failed", prod);
- return ret;
- }
- printf("%s: Port[%d] using Rx adapter[%d] started\n", __func__,
- prod, prod);
+ evt_info("Port[%d] using Rx adapter[%d] configured", prod,
+ prod);
}
return ret;
}
int
-pipeline_event_tx_service_setup(struct evt_test *test, struct evt_options *opt,
- uint8_t tx_queue_id, uint8_t tx_port_id,
- const struct rte_event_port_conf p_conf)
+pipeline_event_tx_adapter_setup(struct evt_options *opt,
+ struct rte_event_port_conf port_conf)
{
- int ret;
- struct rte_service_spec serv;
- struct test_pipeline *t = evt_test_priv(test);
- struct tx_service_data *tx = &t->tx_service;
+ int ret = 0;
+ uint16_t consm;
- ret = rte_event_port_setup(opt->dev_id, tx_port_id, &p_conf);
- if (ret) {
- evt_err("failed to setup port %d", tx_port_id);
- return ret;
- }
+ RTE_ETH_FOREACH_DEV(consm) {
+ uint32_t cap;
- if (rte_event_port_link(opt->dev_id, tx_port_id, &tx_queue_id,
- NULL, 1) != 1) {
- evt_err("failed to link queues to port %d", tx_port_id);
- return -EINVAL;
- }
+ ret = rte_event_eth_tx_adapter_caps_get(opt->dev_id,
+ consm, &cap);
+ if (ret) {
+ evt_err("failed to get event tx adapter[%d] caps",
+ consm);
+ return ret;
+ }
- tx->dev_id = opt->dev_id;
- tx->queue_id = tx_queue_id;
- tx->port_id = tx_port_id;
- tx->nb_ethports = rte_eth_dev_count_avail();
- tx->t = t;
-
- /* Register Tx service */
- memset(&serv, 0, sizeof(struct rte_service_spec));
- snprintf(serv.name, sizeof(serv.name), "Tx_service");
-
- if (evt_has_burst_mode(opt->dev_id))
- serv.callback = pipeline_event_tx_burst_service_func;
- else
- serv.callback = pipeline_event_tx_service_func;
-
- serv.callback_userdata = (void *)tx;
- ret = rte_service_component_register(&serv, &tx->service_id);
- if (ret) {
- evt_err("failed to register Tx service");
- return ret;
- }
+ ret = rte_event_eth_tx_adapter_create(consm, opt->dev_id,
+ &port_conf);
+ if (ret) {
+ evt_err("failed to create tx adapter[%d]", consm);
+ return ret;
+ }
- ret = evt_service_setup(tx->service_id);
- if (ret) {
- evt_err("Failed to setup service core for Tx service\n");
- return ret;
- }
+ ret = rte_event_eth_tx_adapter_queue_add(consm, consm, -1);
+ if (ret) {
+ evt_err("failed to add tx queues to adapter[%d]",
+ consm);
+ return ret;
+ }
- rte_service_runstate_set(tx->service_id, 1);
+ if (!(cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)) {
+ uint32_t service_id = -1U;
- return 0;
-}
+ ret = rte_event_eth_tx_adapter_service_id_get(consm,
+ &service_id);
+ if (ret != -ESRCH && ret != 0) {
+ evt_err("Failed to get Tx adptr service ID");
+ return ret;
+ }
+ ret = evt_service_setup(service_id);
+ if (ret) {
+ evt_err("Failed to setup service core"
+ " for Tx adapter");
+ return ret;
+ }
+ }
+ evt_info("Port[%d] using Tx adapter[%d] Configured", consm,
+ consm);
+ }
+
+ return ret;
+}
void
pipeline_ethdev_destroy(struct evt_test *test, struct evt_options *opt)
uint16_t i;
RTE_SET_USED(test);
RTE_SET_USED(opt);
- struct test_pipeline *t = evt_test_priv(test);
-
- if (t->mt_unsafe) {
- rte_service_component_runstate_set(t->tx_service.service_id, 0);
- rte_service_runstate_set(t->tx_service.service_id, 0);
- rte_service_component_unregister(t->tx_service.service_id);
- }
RTE_ETH_FOREACH_DEV(i) {
rte_event_eth_rx_adapter_stop(i);
+ rte_event_eth_tx_adapter_stop(i);
rte_eth_dev_stop(i);
- rte_eth_dev_close(i);
}
}
pipeline_mempool_setup(struct evt_test *test, struct evt_options *opt)
{
struct test_pipeline *t = evt_test_priv(test);
+ int i, ret;
+
+ if (!opt->mbuf_sz)
+ opt->mbuf_sz = RTE_MBUF_DEFAULT_BUF_SIZE;
+
+ if (!opt->max_pkt_sz)
+ opt->max_pkt_sz = RTE_ETHER_MAX_LEN;
+
+ RTE_ETH_FOREACH_DEV(i) {
+ struct rte_eth_dev_info dev_info;
+ uint16_t data_size = 0;
+
+ memset(&dev_info, 0, sizeof(dev_info));
+ ret = rte_eth_dev_info_get(i, &dev_info);
+ if (ret != 0) {
+ evt_err("Error during getting device (port %u) info: %s\n",
+ i, strerror(-ret));
+ return ret;
+ }
+
+ if (dev_info.rx_desc_lim.nb_mtu_seg_max != UINT16_MAX &&
+ dev_info.rx_desc_lim.nb_mtu_seg_max != 0) {
+ data_size = opt->max_pkt_sz /
+ dev_info.rx_desc_lim.nb_mtu_seg_max;
+ data_size += RTE_PKTMBUF_HEADROOM;
+
+ if (data_size > opt->mbuf_sz)
+ opt->mbuf_sz = data_size;
+ }
+ }
t->pool = rte_pktmbuf_pool_create(test->name, /* mempool name */
opt->pool_sz, /* number of elements*/
512, /* cache size*/
0,
- RTE_MBUF_DEFAULT_BUF_SIZE,
+ opt->mbuf_sz,
opt->socket_id); /* flags */
if (t->pool == NULL) {