Add thread data structure and init function to run softnic pipelines
objects.
Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
drivers/net/softnic/Makefile | 1 +
drivers/net/softnic/rte_eth_softnic.c | 8 +++
drivers/net/softnic/rte_eth_softnic_internals.h | 69 +++++++++++++++++++
drivers/net/softnic/rte_eth_softnic_thread.c | 90 +++++++++++++++++++++++++
4 files changed, 168 insertions(+)
create mode 100644 drivers/net/softnic/rte_eth_softnic_thread.c
@@ -31,6 +31,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_tm.c
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_tap.c
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_action.c
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_pipeline.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_thread.c
#
# Export include files
@@ -210,6 +210,7 @@ static void *
pmd_init(struct pmd_params *params)
{
struct pmd_internals *p;
+ int status;
p = rte_zmalloc_socket(params->name,
sizeof(struct pmd_internals),
@@ -231,6 +232,12 @@ pmd_init(struct pmd_params *params)
table_action_profile_init(p);
pipeline_init(p);
+ status = thread_init(p);
+ if (status) {
+ rte_free(p);
+ return NULL;
+ }
+
return p;
}
@@ -240,6 +247,7 @@ pmd_free(struct pmd_internals *p)
if (p == NULL)
return;
+ thread_free(p);
pipeline_free(p);
table_action_profile_free(p);
port_in_action_profile_free(p);
@@ -434,10 +434,68 @@ struct pipeline {
TAILQ_HEAD(pipeline_list, pipeline);
+/**
+ * Thread
+ */
+#ifndef THREAD_PIPELINES_MAX
+#define THREAD_PIPELINES_MAX 256
+#endif
+
+#ifndef THREAD_MSGQ_SIZE
+#define THREAD_MSGQ_SIZE 64
+#endif
+
+#ifndef THREAD_TIMER_PERIOD_MS
+#define THREAD_TIMER_PERIOD_MS 100
+#endif
+
+/**
+ * Master thead: data plane thread context
+ */
+struct thread {
+ struct rte_ring *msgq_req;
+ struct rte_ring *msgq_rsp;
+
+ uint32_t enabled;
+};
+
+/**
+ * Data plane threads: context
+ */
#ifndef TABLE_RULE_ACTION_SIZE_MAX
#define TABLE_RULE_ACTION_SIZE_MAX 2048
#endif
+struct table_data {
+ struct rte_table_action *a;
+};
+
+struct pipeline_data {
+ struct rte_pipeline *p;
+ struct table_data table_data[RTE_PIPELINE_TABLE_MAX];
+ uint32_t n_tables;
+
+ struct rte_ring *msgq_req;
+ struct rte_ring *msgq_rsp;
+ uint64_t timer_period; /* Measured in CPU cycles. */
+ uint64_t time_next;
+
+ uint8_t buffer[TABLE_RULE_ACTION_SIZE_MAX];
+};
+
+struct thread_data {
+ struct rte_pipeline *p[THREAD_PIPELINES_MAX];
+ uint32_t n_pipelines;
+
+ struct pipeline_data pipeline_data[THREAD_PIPELINES_MAX];
+ struct rte_ring *msgq_req;
+ struct rte_ring *msgq_rsp;
+ uint64_t timer_period; /* Measured in CPU cycles. */
+ uint64_t time_next;
+ uint64_t time_next_min;
+ uint64_t iter;
+} __rte_cache_aligned;
+
/**
* PMD Internals
*/
@@ -458,6 +516,8 @@ struct pmd_internals {
struct port_in_action_profile_list port_in_action_profile_list;
struct table_action_profile_list table_action_profile_list;
struct pipeline_list pipeline_list;
+ struct thread thread[RTE_MAX_LCORE];
+ struct thread_data thread_data[RTE_MAX_LCORE];
};
/**
@@ -639,4 +699,13 @@ pipeline_table_create(struct pmd_internals *p,
const char *pipeline_name,
struct table_params *params);
+/**
+ * Thread
+ */
+int
+thread_init(struct pmd_internals *p);
+
+void
+thread_free(struct pmd_internals *p);
+
#endif /* __INCLUDE_RTE_ETH_SOFTNIC_INTERNALS_H__ */
new file mode 100644
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#include <stdlib.h>
+
+#include <rte_cycles.h>
+#include <rte_lcore.h>
+#include <rte_ring.h>
+
+#include "rte_eth_softnic_internals.h"
+
+/**
+ * Master thread: data plane thread init
+ */
+void
+thread_free(struct pmd_internals *softnic)
+{
+ uint32_t i;
+
+ RTE_LCORE_FOREACH_SLAVE(i) {
+ struct thread *t = &softnic->thread[i];
+
+ /* MSGQs */
+ if (t->msgq_req)
+ rte_ring_free(t->msgq_req);
+
+ if (t->msgq_rsp)
+ rte_ring_free(t->msgq_rsp);
+ }
+}
+
+int
+thread_init(struct pmd_internals *softnic)
+{
+ uint32_t i;
+
+ RTE_LCORE_FOREACH_SLAVE(i) {
+ char ring_name[NAME_MAX];
+ struct rte_ring *msgq_req, *msgq_rsp;
+ struct thread *t = &softnic->thread[i];
+ struct thread_data *t_data = &softnic->thread_data[i];
+ uint32_t cpu_id = rte_lcore_to_socket_id(i);
+
+ /* MSGQs */
+ snprintf(ring_name, sizeof(ring_name), "%s-TH%u-REQ",
+ softnic->params.name,
+ i);
+
+ msgq_req = rte_ring_create(ring_name,
+ THREAD_MSGQ_SIZE,
+ cpu_id,
+ RING_F_SP_ENQ | RING_F_SC_DEQ);
+
+ if (msgq_req == NULL) {
+ thread_free(softnic);
+ return -1;
+ }
+
+ snprintf(ring_name, sizeof(ring_name), "%s-TH%u-RSP",
+ softnic->params.name,
+ i);
+
+ msgq_rsp = rte_ring_create(ring_name,
+ THREAD_MSGQ_SIZE,
+ cpu_id,
+ RING_F_SP_ENQ | RING_F_SC_DEQ);
+
+ if (msgq_rsp == NULL) {
+ thread_free(softnic);
+ return -1;
+ }
+
+ /* Master thread records */
+ t->msgq_req = msgq_req;
+ t->msgq_rsp = msgq_rsp;
+ t->enabled = 1;
+
+ /* Data plane thread records */
+ t_data->n_pipelines = 0;
+ t_data->msgq_req = msgq_req;
+ t_data->msgq_rsp = msgq_rsp;
+ t_data->timer_period =
+ (rte_get_tsc_hz() * THREAD_TIMER_PERIOD_MS) / 1000;
+ t_data->time_next = rte_get_tsc_cycles() + t_data->timer_period;
+ t_data->time_next_min = t_data->time_next;
+ }
+
+ return 0;
+}