eventdev/eth_rx: fix telemetry Rx stats reset
[dpdk.git] / examples / ipsec-secgw / event_helper.c
index fe047ab..172ab8e 100644 (file)
 #include <stdbool.h>
 
 #include "event_helper.h"
+#include "ipsec-secgw.h"
+
+#define DEFAULT_VECTOR_SIZE  16
+#define DEFAULT_VECTOR_TMO   102400
 
 static volatile bool eth_core_running;
 
@@ -100,12 +104,15 @@ static inline bool
 eh_dev_has_rx_internal_port(uint8_t eventdev_id)
 {
        bool flag = true;
-       int j;
+       int j, ret;
 
        RTE_ETH_FOREACH_DEV(j) {
                uint32_t caps = 0;
 
-               rte_event_eth_rx_adapter_caps_get(eventdev_id, j, &caps);
+               ret = rte_event_eth_rx_adapter_caps_get(eventdev_id, j, &caps);
+               if (ret < 0)
+                       return false;
+
                if (!(caps & RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT))
                        flag = false;
        }
@@ -116,12 +123,15 @@ static inline bool
 eh_dev_has_tx_internal_port(uint8_t eventdev_id)
 {
        bool flag = true;
-       int j;
+       int j, ret;
 
        RTE_ETH_FOREACH_DEV(j) {
                uint32_t caps = 0;
 
-               rte_event_eth_tx_adapter_caps_get(eventdev_id, j, &caps);
+               ret = rte_event_eth_tx_adapter_caps_get(eventdev_id, j, &caps);
+               if (ret < 0)
+                       return false;
+
                if (!(caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT))
                        flag = false;
        }
@@ -323,6 +333,7 @@ eh_set_default_conf_rx_adapter(struct eventmode_conf *em_conf)
        int nb_eth_dev;
        int adapter_id;
        int conn_id;
+       int ret;
        int i;
 
        /* Create one adapter with eth queues mapped to event queue(s) */
@@ -385,7 +396,12 @@ eh_set_default_conf_rx_adapter(struct eventmode_conf *em_conf)
                conn->ethdev_rx_qid = -1;
 
                /* Get Rx adapter capabilities */
-               rte_event_eth_rx_adapter_caps_get(eventdev_id, i, &caps);
+               ret = rte_event_eth_rx_adapter_caps_get(eventdev_id, i, &caps);
+               if (ret < 0) {
+                       EH_LOG_ERR("Failed to get event device %d eth rx adapter"
+                                  " capabilities for port %d", eventdev_id, i);
+                       return ret;
+               }
                if (!(caps & RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT))
                        rx_internal_port = false;
 
@@ -420,6 +436,7 @@ eh_set_default_conf_tx_adapter(struct eventmode_conf *em_conf)
        int adapter_id;
        int nb_eth_dev;
        int conn_id;
+       int ret;
        int i;
 
        /*
@@ -479,7 +496,12 @@ eh_set_default_conf_tx_adapter(struct eventmode_conf *em_conf)
                conn->ethdev_tx_qid = -1;
 
                /* Get Tx adapter capabilities */
-               rte_event_eth_tx_adapter_caps_get(eventdev_id, i, &caps);
+               ret = rte_event_eth_tx_adapter_caps_get(eventdev_id, i, &caps);
+               if (ret < 0) {
+                       EH_LOG_ERR("Failed to get event device %d eth tx adapter"
+                                  " capabilities for port %d", eventdev_id, i);
+                       return ret;
+               }
                if (!(caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT))
                        tx_internal_port = false;
 
@@ -694,6 +716,16 @@ eh_initialize_eventdev(struct eventmode_conf *em_conf)
                }
        }
 
+       return 0;
+}
+
+static int
+eh_start_eventdev(struct eventmode_conf *em_conf)
+{
+       struct eventdev_params *eventdev_config;
+       int nb_eventdev = em_conf->nb_eventdev;
+       int i, ret;
+
        /* Start event devices */
        for (i = 0; i < nb_eventdev; i++) {
 
@@ -710,6 +742,45 @@ eh_initialize_eventdev(struct eventmode_conf *em_conf)
        return 0;
 }
 
+static int
+eh_event_vector_limits_validate(struct eventmode_conf *em_conf,
+                               uint8_t ev_dev_id, uint8_t ethdev_id)
+{
+       struct rte_event_eth_rx_adapter_vector_limits limits = {0};
+       uint16_t vector_size = em_conf->ext_params.vector_size;
+       int ret;
+
+       ret = rte_event_eth_rx_adapter_vector_limits_get(ev_dev_id, ethdev_id,
+                                                        &limits);
+       if (ret) {
+               EH_LOG_ERR("failed to get vector limits");
+               return ret;
+       }
+
+       if (vector_size < limits.min_sz || vector_size > limits.max_sz) {
+               EH_LOG_ERR("Vector size [%d] not within limits min[%d] max[%d]",
+                          vector_size, limits.min_sz, limits.max_sz);
+               return -EINVAL;
+       }
+
+       if (limits.log2_sz && !rte_is_power_of_2(vector_size)) {
+               EH_LOG_ERR("Vector size [%d] not power of 2", vector_size);
+               return -EINVAL;
+       }
+
+       if (em_conf->vector_tmo_ns > limits.max_timeout_ns ||
+           em_conf->vector_tmo_ns < limits.min_timeout_ns) {
+               EH_LOG_ERR("Vector timeout [%" PRIu64
+                          "] not within limits max[%" PRIu64
+                          "] min[%" PRIu64 "]",
+                          em_conf->vector_tmo_ns,
+                          limits.max_timeout_ns,
+                          limits.min_timeout_ns);
+               return -EINVAL;
+       }
+       return 0;
+}
+
 static int
 eh_rx_adapter_configure(struct eventmode_conf *em_conf,
                struct rx_adapter_conf *adapter)
@@ -718,9 +789,11 @@ eh_rx_adapter_configure(struct eventmode_conf *em_conf,
        struct rte_event_dev_info evdev_default_conf = {0};
        struct rte_event_port_conf port_conf = {0};
        struct rx_adapter_connection_info *conn;
+       uint32_t service_id, socket_id, nb_elem;
+       struct rte_mempool *vector_pool = NULL;
+       uint32_t lcore_id = rte_lcore_id();
+       int ret, portid, nb_ports = 0;
        uint8_t eventdev_id;
-       uint32_t service_id;
-       int ret;
        int j;
 
        /* Get event dev ID */
@@ -733,6 +806,31 @@ eh_rx_adapter_configure(struct eventmode_conf *em_conf,
                return ret;
        }
 
+       RTE_ETH_FOREACH_DEV(portid)
+               if ((em_conf->eth_portmask & (1 << portid)))
+                       nb_ports++;
+
+       if (em_conf->ext_params.event_vector) {
+               socket_id = rte_lcore_to_socket_id(lcore_id);
+
+               if (em_conf->vector_pool_sz) {
+                       nb_elem = em_conf->vector_pool_sz;
+               } else {
+                       nb_elem = (nb_bufs_in_pool /
+                                  em_conf->ext_params.vector_size) + 1;
+                       if (per_port_pool)
+                               nb_elem = nb_ports * nb_elem;
+               }
+
+               vector_pool = rte_event_vector_pool_create(
+                       "vector_pool", nb_elem, 0,
+                       em_conf->ext_params.vector_size,
+                       socket_id);
+               if (vector_pool == NULL) {
+                       EH_LOG_ERR("failed to create event vector pool");
+                       return -ENOMEM;
+               }
+       }
        /* Setup port conf */
        port_conf.new_event_threshold = 1200;
        port_conf.dequeue_depth =
@@ -758,6 +856,20 @@ eh_rx_adapter_configure(struct eventmode_conf *em_conf,
                queue_conf.ev.sched_type = em_conf->ext_params.sched_type;
                queue_conf.ev.event_type = RTE_EVENT_TYPE_ETHDEV;
 
+               if (em_conf->ext_params.event_vector) {
+                       ret = eh_event_vector_limits_validate(em_conf,
+                                                             eventdev_id,
+                                                             conn->ethdev_id);
+                       if (ret)
+                               return ret;
+
+                       queue_conf.vector_sz = em_conf->ext_params.vector_size;
+                       queue_conf.vector_timeout_ns = em_conf->vector_tmo_ns;
+                       queue_conf.vector_mp = vector_pool;
+                       queue_conf.rx_queue_flags =
+                               RTE_EVENT_ETH_RX_ADAPTER_QUEUE_EVENT_VECTOR;
+               }
+
                /* Add queue to the adapter */
                ret = rte_event_eth_rx_adapter_queue_add(adapter->adapter_id,
                                conn->ethdev_id, conn->ethdev_rx_qid,
@@ -960,6 +1072,8 @@ eh_find_worker(uint32_t lcore_id, struct eh_conf *conf,
        else
                curr_conf.cap.burst = EH_RX_TYPE_NON_BURST;
 
+       curr_conf.cap.ipsec_mode = conf->ipsec_mode;
+
        /* Parse the passed list and see if we have matching capabilities */
 
        /* Initialize the pointer used to traverse the list */
@@ -1260,7 +1374,7 @@ eh_display_rx_adapter_conf(struct eventmode_conf *em_conf)
        for (i = 0; i < nb_rx_adapter; i++) {
                adapter = &(em_conf->rx_adapter[i]);
                sprintf(print_buf,
-                       "\tRx adaper ID: %-2d\tConnections: %-2d\tEvent dev ID: %-2d",
+                       "\tRx adapter ID: %-2d\tConnections: %-2d\tEvent dev ID: %-2d",
                        adapter->adapter_id,
                        adapter->nb_connections,
                        adapter->eventdev_id);
@@ -1379,6 +1493,113 @@ eh_display_link_conf(struct eventmode_conf *em_conf)
        EH_LOG_INFO("");
 }
 
+struct eh_conf *
+eh_conf_init(void)
+{
+       struct eventmode_conf *em_conf = NULL;
+       struct eh_conf *conf = NULL;
+       unsigned int eth_core_id;
+       void *bitmap = NULL;
+       uint32_t nb_bytes;
+
+       /* Allocate memory for config */
+       conf = calloc(1, sizeof(struct eh_conf));
+       if (conf == NULL) {
+               EH_LOG_ERR("Failed to allocate memory for eventmode helper "
+                          "config");
+               return NULL;
+       }
+
+       /* Set default conf */
+
+       /* Packet transfer mode: poll */
+       conf->mode = EH_PKT_TRANSFER_MODE_POLL;
+       conf->ipsec_mode = EH_IPSEC_MODE_TYPE_APP;
+
+       /* Keep all ethernet ports enabled by default */
+       conf->eth_portmask = -1;
+
+       /* Allocate memory for event mode params */
+       conf->mode_params = calloc(1, sizeof(struct eventmode_conf));
+       if (conf->mode_params == NULL) {
+               EH_LOG_ERR("Failed to allocate memory for event mode params");
+               goto free_conf;
+       }
+
+       /* Get eventmode conf */
+       em_conf = conf->mode_params;
+
+       /* Allocate and initialize bitmap for eth cores */
+       nb_bytes = rte_bitmap_get_memory_footprint(RTE_MAX_LCORE);
+       if (!nb_bytes) {
+               EH_LOG_ERR("Failed to get bitmap footprint");
+               goto free_em_conf;
+       }
+
+       bitmap = rte_zmalloc("event-helper-ethcore-bitmap", nb_bytes,
+                            RTE_CACHE_LINE_SIZE);
+       if (!bitmap) {
+               EH_LOG_ERR("Failed to allocate memory for eth cores bitmap\n");
+               goto free_em_conf;
+       }
+
+       em_conf->eth_core_mask = rte_bitmap_init(RTE_MAX_LCORE, bitmap,
+                                                nb_bytes);
+       if (!em_conf->eth_core_mask) {
+               EH_LOG_ERR("Failed to initialize bitmap");
+               goto free_bitmap;
+       }
+
+       /* Set schedule type as not set */
+       em_conf->ext_params.sched_type = SCHED_TYPE_NOT_SET;
+
+       /* Set two cores as eth cores for Rx & Tx */
+
+       /* Use first core other than main core as Rx core */
+       eth_core_id = rte_get_next_lcore(0,     /* curr core */
+                                        1,     /* skip main core */
+                                        0      /* wrap */);
+
+       rte_bitmap_set(em_conf->eth_core_mask, eth_core_id);
+
+       /* Use next core as Tx core */
+       eth_core_id = rte_get_next_lcore(eth_core_id,   /* curr core */
+                                        1,             /* skip main core */
+                                        0              /* wrap */);
+
+       rte_bitmap_set(em_conf->eth_core_mask, eth_core_id);
+
+       em_conf->ext_params.vector_size = DEFAULT_VECTOR_SIZE;
+       em_conf->vector_tmo_ns = DEFAULT_VECTOR_TMO;
+
+       return conf;
+
+free_bitmap:
+       rte_free(bitmap);
+free_em_conf:
+       free(em_conf);
+free_conf:
+       free(conf);
+       return NULL;
+}
+
+void
+eh_conf_uninit(struct eh_conf *conf)
+{
+       struct eventmode_conf *em_conf = NULL;
+
+       if (!conf || !conf->mode_params)
+               return;
+
+       /* Get eventmode conf */
+       em_conf = conf->mode_params;
+
+       /* Free evenmode configuration memory */
+       rte_free(em_conf->eth_core_mask);
+       free(em_conf);
+       free(conf);
+}
+
 void
 eh_display_conf(struct eh_conf *conf)
 {
@@ -1459,7 +1680,12 @@ eh_devs_init(struct eh_conf *conf)
                if ((conf->eth_portmask & (1 << port_id)) == 0)
                        continue;
 
-               rte_eth_dev_stop(port_id);
+               ret = rte_eth_dev_stop(port_id);
+               if (ret != 0) {
+                       EH_LOG_ERR("Failed to stop port %u, err: %d",
+                                       port_id, ret);
+                       return ret;
+               }
        }
 
        /* Setup eventdev */
@@ -1483,6 +1709,13 @@ eh_devs_init(struct eh_conf *conf)
                return ret;
        }
 
+       /* Start eventdev */
+       ret = eh_start_eventdev(em_conf);
+       if (ret < 0) {
+               EH_LOG_ERR("Failed to start event dev %d", ret);
+               return ret;
+       }
+
        /* Start eth devices after setting up adapter */
        RTE_ETH_FOREACH_DEV(port_id) {