node: add ethdev control
authorNithin Dabilpuram <ndabilpuram@marvell.com>
Sat, 11 Apr 2020 14:14:17 +0000 (19:44 +0530)
committerThomas Monjalon <thomas@monjalon.net>
Tue, 5 May 2020 21:38:35 +0000 (23:38 +0200)
Add ctrl api to setup ethdev_rx and ethdev_tx node.
This ctrl api clones 'N' number of ethdev_rx and ethdev_tx
nodes with specific (port, queue) pairs updated in their context.
All the ethdev ports and queues are setup before this api
is called.

Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
doc/api/doxy-api-index.md
lib/librte_node/Makefile
lib/librte_node/ethdev_ctrl.c [new file with mode: 0644]
lib/librte_node/meson.build
lib/librte_node/node_private.h
lib/librte_node/rte_node_eth_api.h [new file with mode: 0644]
lib/librte_node/rte_node_version.map

index 2e9241d..a4d57a5 100644 (file)
@@ -161,6 +161,8 @@ The public API headers are grouped by topics:
     [table_action]     (@ref rte_table_action.h)
   * [graph]            (@ref rte_graph.h):
     [graph_worker]     (@ref rte_graph_worker.h)
+  * graph_nodes:
+    [eth_node]         (@ref rte_node_eth_api.h),
 
 - **basic**:
   [approx fraction]    (@ref rte_approx.h),
index e0288e7..3ce1fa6 100644 (file)
@@ -11,7 +11,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 # Strict-aliasing rules are violated by uint8_t[] to context size casts.
 CFLAGS += -fno-strict-aliasing
-LDLIBS += -lrte_eal -lrte_graph -lrte_mbuf -lrte_ethdev
+LDLIBS += -lrte_eal -lrte_graph -lrte_mbuf -lrte_ethdev -lrte_mempool
 
 EXPORT_MAP := rte_node_version.map
 
@@ -20,5 +20,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_NODE) += null.c
 SRCS-$(CONFIG_RTE_LIBRTE_NODE) += log.c
 SRCS-$(CONFIG_RTE_LIBRTE_NODE) += ethdev_rx.c
 SRCS-$(CONFIG_RTE_LIBRTE_NODE) += ethdev_tx.c
+SRCS-$(CONFIG_RTE_LIBRTE_NODE) += ethdev_ctrl.c
+
+# install header files
+SYMLINK-$(CONFIG_RTE_LIBRTE_NODE)-include += rte_node_eth_api.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_node/ethdev_ctrl.c b/lib/librte_node/ethdev_ctrl.c
new file mode 100644 (file)
index 0000000..599d20b
--- /dev/null
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#include <rte_debug.h>
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_graph.h>
+
+#include "rte_node_eth_api.h"
+
+#include "ethdev_rx_priv.h"
+#include "ethdev_tx_priv.h"
+#include "node_private.h"
+
+static struct ethdev_ctrl {
+       uint16_t nb_graphs;
+} ctrl;
+
+int
+rte_node_eth_config(struct rte_node_ethdev_config *conf, uint16_t nb_confs,
+                   uint16_t nb_graphs)
+{
+       struct ethdev_tx_node_main *tx_node_data;
+       uint16_t tx_q_used, rx_q_used, port_id;
+       struct rte_node_register *tx_node;
+       char name[RTE_NODE_NAMESIZE];
+       struct rte_mempool *mp;
+       uint32_t id;
+       int i, j;
+
+       tx_node_data = ethdev_tx_node_data_get();
+       tx_node = ethdev_tx_node_get();
+       for (i = 0; i < nb_confs; i++) {
+               port_id = conf[i].port_id;
+
+               if (!rte_eth_dev_is_valid_port(port_id))
+                       return -EINVAL;
+
+               /* Check for mbuf minimum private size requirement */
+               for (j = 0; j < conf[i].mp_count; j++) {
+                       mp = conf[i].mp[j];
+                       if (!mp)
+                               continue;
+                       /* Check for minimum private space */
+                       if (rte_pktmbuf_priv_size(mp) < NODE_MBUF_PRIV2_SIZE) {
+                               node_err("ethdev",
+                                        "Minimum mbuf priv size requirement not met by mp %s",
+                                        mp->name);
+                               return -EINVAL;
+                       }
+               }
+
+               rx_q_used = conf[i].num_rx_queues;
+               tx_q_used = conf[i].num_tx_queues;
+               /* Check if we have a txq for each worker */
+               if (tx_q_used < nb_graphs)
+                       return -EINVAL;
+
+               /* Create node for each rx port queue pair */
+               for (j = 0; j < rx_q_used; j++) {
+                       struct ethdev_rx_node_main *rx_node_data;
+                       struct rte_node_register *rx_node;
+                       ethdev_rx_node_elem_t *elem;
+
+                       rx_node_data = ethdev_rx_get_node_data_get();
+                       rx_node = ethdev_rx_node_get();
+                       snprintf(name, sizeof(name), "%u-%u", port_id, j);
+                       /* Clone a new rx node with same edges as parent */
+                       id = rte_node_clone(rx_node->id, name);
+                       if (id == RTE_NODE_ID_INVALID)
+                               return -EIO;
+
+                       /* Add it to list of ethdev rx nodes for lookup */
+                       elem = malloc(sizeof(ethdev_rx_node_elem_t));
+                       memset(elem, 0, sizeof(ethdev_rx_node_elem_t));
+                       elem->ctx.port_id = port_id;
+                       elem->ctx.queue_id = j;
+                       elem->nid = id;
+                       elem->next = rx_node_data->head;
+                       rx_node_data->head = elem;
+
+                       node_dbg("ethdev", "Rx node %s-%s: is at %u",
+                                rx_node->name, name, id);
+               }
+
+               /* Create a per port tx node from base node */
+               snprintf(name, sizeof(name), "%u", port_id);
+               /* Clone a new node with same edges as parent */
+               id = rte_node_clone(tx_node->id, name);
+               tx_node_data->nodes[port_id] = id;
+
+               node_dbg("ethdev", "Tx node %s-%s: is at %u", tx_node->name,
+                        name, id);
+       }
+
+       ctrl.nb_graphs = nb_graphs;
+       return 0;
+}
index 6bda53f..0361f8f 100644 (file)
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(C) 2020 Marvell International Ltd.
 
-sources = files('null.c', 'log.c', 'ethdev_rx.c', 'ethdev_tx.c')
+sources = files('null.c', 'log.c', 'ethdev_rx.c', 'ethdev_tx.c', 'ethdev_ctrl.c')
+headers = files('rte_node_eth_api.h')
 # Strict-aliasing rules are violated by uint8_t[] to context size casts.
 cflags += '-fno-strict-aliasing'
-deps += ['graph', 'mbuf', 'ethdev']
+deps += ['graph', 'mbuf', 'lpm', 'ethdev', 'mempool', 'cryptodev']
index f30902a..975b9aa 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <rte_common.h>
 #include <rte_log.h>
+#include <rte_mbuf.h>
 
 extern int rte_node_logtype;
 #define NODE_LOG(level, node_name, ...)                                        \
@@ -19,4 +20,60 @@ extern int rte_node_logtype;
 #define node_info(node_name, ...) NODE_LOG(INFO, node_name, __VA_ARGS__)
 #define node_dbg(node_name, ...) NODE_LOG(DEBUG, node_name, __VA_ARGS__)
 
+/**
+ *
+ * Node mbuf private data to store next hop, ttl and checksum.
+ */
+struct node_mbuf_priv1 {
+       union {
+               /* IP4 rewrite */
+               struct {
+                       uint16_t nh;
+                       uint16_t ttl;
+                       uint32_t cksum;
+               };
+
+               uint64_t u;
+       };
+};
+
+/**
+ * Node mbuf private area 2.
+ */
+struct node_mbuf_priv2 {
+       uint64_t priv_data;
+} __rte_cache_aligned;
+
+#define NODE_MBUF_PRIV2_SIZE sizeof(struct node_mbuf_priv2)
+
+/**
+ * Get mbuf_priv1 pointer from rte_mbuf.
+ *
+ * @param
+ *   Pointer to the rte_mbuf.
+ *
+ * @return
+ *   Pointer to the mbuf_priv1.
+ */
+static __rte_always_inline struct node_mbuf_priv1 *
+node_mbuf_priv1(struct rte_mbuf *m)
+{
+       return (struct node_mbuf_priv1 *)&m->udata64;
+}
+
+/**
+ * Get mbuf_priv2 pointer from rte_mbuf.
+ *
+ * @param
+ *   Pointer to the rte_mbuf.
+ *
+ * @return
+ *   Pointer to the mbuf_priv2.
+ */
+static __rte_always_inline struct node_mbuf_priv2 *
+node_mbuf_priv2(struct rte_mbuf *m)
+{
+       return (struct node_mbuf_priv2 *)rte_mbuf_to_priv(m);
+}
+
 #endif /* __NODE_PRIVATE_H__ */
diff --git a/lib/librte_node/rte_node_eth_api.h b/lib/librte_node/rte_node_eth_api.h
new file mode 100644 (file)
index 0000000..e9a53af
--- /dev/null
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef __INCLUDE_RTE_NODE_ETH_API_H__
+#define __INCLUDE_RTE_NODE_ETH_API_H__
+
+/**
+ * @file rte_node_eth_api.h
+ *
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * This API allows to setup ethdev_rx and ethdev_tx nodes
+ * and its queue associations.
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+#include <rte_mempool.h>
+
+/**
+ * Port config for ethdev_rx and ethdev_tx node.
+ */
+struct rte_node_ethdev_config {
+       uint16_t port_id;
+       /**< Port identifier */
+       uint16_t num_rx_queues;
+       /**< Number of Rx queues. */
+       uint16_t num_tx_queues;
+       /**< Number of Tx queues. */
+       struct rte_mempool **mp;
+       /**< Array of mempools associated to Rx queue. */
+       uint16_t mp_count;
+       /**< Size of mp array. */
+};
+
+/**
+ * Initializes ethdev nodes.
+ *
+ * @param cfg
+ *   Array of ethdev config that identifies which port's
+ *   ethdev_rx and ethdev_tx nodes need to be created
+ *   and queue association.
+ * @param cnt
+ *   Size of cfg array.
+ * @param nb_graphs
+ *   Number of graphs that will be used.
+ *
+ * @return
+ *   0 on successful initialization, negative otherwise.
+ */
+__rte_experimental
+int rte_node_eth_config(struct rte_node_ethdev_config *cfg,
+                       uint16_t cnt, uint16_t nb_graphs);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_RTE_NODE_ETH_API_H__ */
index f87163b..c6c71bd 100644 (file)
@@ -1,6 +1,7 @@
 EXPERIMENTAL {
        global:
 
+       rte_node_eth_config;
        rte_node_logtype;
        local: *;
 };