From c0b668e0c6b0024c5d1d0881606a6b2b4641889d Mon Sep 17 00:00:00 2001 From: Jasvinder Singh Date: Thu, 29 Mar 2018 19:31:49 +0100 Subject: [PATCH] examples/ip_pipeline: add threads Add threads data structure and initialisation functions to run the pipeline. Signed-off-by: Cristian Dumitrescu Signed-off-by: Jasvinder Singh --- examples/ip_pipeline/Makefile | 2 +- examples/ip_pipeline/main.c | 8 ++ examples/ip_pipeline/meson.build | 1 + examples/ip_pipeline/thread.c | 156 +++++++++++++++++++++++++++++++ examples/ip_pipeline/thread.h | 13 +++ 5 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 examples/ip_pipeline/thread.c create mode 100644 examples/ip_pipeline/thread.h diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile index 033319dee0..c936d1e0c7 100644 --- a/examples/ip_pipeline/Makefile +++ b/examples/ip_pipeline/Makefile @@ -16,8 +16,8 @@ SRCS-y += parser.c SRCS-y += pipeline.c SRCS-y += swq.c SRCS-y += tap.c +SRCS-y += thread.c SRCS-y += tmgr.c -#SRCS-y += thread.c # Build using pkg-config variables if possible $(shell pkg-config --exists libdpdk) diff --git a/examples/ip_pipeline/main.c b/examples/ip_pipeline/main.c index ab8e2b9d48..45f0739736 100644 --- a/examples/ip_pipeline/main.c +++ b/examples/ip_pipeline/main.c @@ -18,6 +18,7 @@ #include "pipeline.h" #include "swq.h" #include "tap.h" +#include "thread.h" #include "tmgr.h" static const char usage[] = @@ -229,6 +230,13 @@ main(int argc, char **argv) return status; } + /* Thread */ + status = thread_init(); + if (status) { + printf("Error: Thread initialization failed (%d)\n", status); + return status; + } + /* Script */ if (app.script_name) cli_script_process(app.script_name, diff --git a/examples/ip_pipeline/meson.build b/examples/ip_pipeline/meson.build index 2366242688..a9f2ea447a 100644 --- a/examples/ip_pipeline/meson.build +++ b/examples/ip_pipeline/meson.build @@ -20,5 +20,6 @@ sources = files( 'pipeline.c', 'swq.c', 'tap.c', + 'thread.c', 'tmgr.c' ) diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c new file mode 100644 index 0000000000..2c8f84c099 --- /dev/null +++ b/examples/ip_pipeline/thread.c @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2018 Intel Corporation + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" +#include "thread.h" +#include "pipeline.h" + +#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; +}; + +static struct thread thread[RTE_MAX_LCORE]; + +/** + * Data plane threads: context + */ +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; +} __rte_cache_aligned; + +static struct thread_data thread_data[RTE_MAX_LCORE]; + +/** + * Master thread: data plane thread init + */ +static void +thread_free(void) +{ + uint32_t i; + + for (i = 0; i < RTE_MAX_LCORE; i++) { + struct thread *t = &thread[i]; + + if (!rte_lcore_is_enabled(i)) + continue; + + /* MSGQs */ + if (t->msgq_req) + rte_ring_free(t->msgq_req); + + if (t->msgq_rsp) + rte_ring_free(t->msgq_rsp); + } +} + +int +thread_init(void) +{ + uint32_t i; + + RTE_LCORE_FOREACH_SLAVE(i) { + char name[NAME_MAX]; + struct rte_ring *msgq_req, *msgq_rsp; + struct thread *t = &thread[i]; + struct thread_data *t_data = &thread_data[i]; + uint32_t cpu_id = rte_lcore_to_socket_id(i); + + /* MSGQs */ + snprintf(name, sizeof(name), "THREAD-%04x-MSGQ-REQ", i); + + msgq_req = rte_ring_create(name, + THREAD_MSGQ_SIZE, + cpu_id, + RING_F_SP_ENQ | RING_F_SC_DEQ); + + if (msgq_req == NULL) { + thread_free(); + return -1; + } + + snprintf(name, sizeof(name), "THREAD-%04x-MSGQ-RSP", i); + + msgq_rsp = rte_ring_create(name, + THREAD_MSGQ_SIZE, + cpu_id, + RING_F_SP_ENQ | RING_F_SC_DEQ); + + if (msgq_rsp == NULL) { + thread_free(); + 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; +} diff --git a/examples/ip_pipeline/thread.h b/examples/ip_pipeline/thread.h new file mode 100644 index 0000000000..39c0d8959a --- /dev/null +++ b/examples/ip_pipeline/thread.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2018 Intel Corporation + */ + +#ifndef _INCLUDE_THREAD_H_ +#define _INCLUDE_THREAD_H_ + +#include + +int +thread_init(void); + +#endif /* _INCLUDE_THREAD_H_ */ -- 2.20.1