From dfa9491a187a04ffc67bf0cd812cb53a0422da2f Mon Sep 17 00:00:00 2001 From: Cristian Dumitrescu Date: Mon, 13 Sep 2021 17:44:37 +0100 Subject: [PATCH] pipeline: introduce custom instructions For better performance, the option to create custom instructions when the program is translated and add them on-the-fly to the pipeline is now provided. Multiple regular instructions can now be consolidated into a single C function optimized by the C compiler directly. Signed-off-by: Cristian Dumitrescu --- lib/pipeline/rte_swx_pipeline.c | 39 ++++++++++++++++++++++-- lib/pipeline/rte_swx_pipeline_internal.h | 10 ++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c index 0d02548137..9afe42ed25 100644 --- a/lib/pipeline/rte_swx_pipeline.c +++ b/lib/pipeline/rte_swx_pipeline.c @@ -6590,8 +6590,6 @@ error: return err; } -typedef void (*instr_exec_t)(struct rte_swx_pipeline *); - static instr_exec_t instruction_table[] = { [INSTR_RX] = instr_rx_exec, [INSTR_TX] = instr_tx_exec, @@ -6782,12 +6780,41 @@ static instr_exec_t instruction_table[] = { [INSTR_RETURN] = instr_return_exec, }; +static int +instruction_table_build(struct rte_swx_pipeline *p) +{ + p->instruction_table = calloc(RTE_SWX_PIPELINE_INSTRUCTION_TABLE_SIZE_MAX, + sizeof(struct instr_exec_t *)); + if (!p->instruction_table) + return -EINVAL; + + memcpy(p->instruction_table, instruction_table, sizeof(instruction_table)); + + return 0; +} + +static void +instruction_table_build_free(struct rte_swx_pipeline *p) +{ + if (!p->instruction_table) + return; + + free(p->instruction_table); + p->instruction_table = NULL; +} + +static void +instruction_table_free(struct rte_swx_pipeline *p) +{ + instruction_table_build_free(p); +} + static inline void instr_exec(struct rte_swx_pipeline *p) { struct thread *t = &p->threads[p->thread_id]; struct instruction *ip = t->ip; - instr_exec_t instr = instruction_table[ip->type]; + instr_exec_t instr = p->instruction_table[ip->type]; instr(p); } @@ -8916,6 +8943,7 @@ rte_swx_pipeline_free(struct rte_swx_pipeline *p) selector_free(p); table_free(p); action_free(p); + instruction_table_free(p); metadata_free(p); header_free(p); extern_func_free(p); @@ -8985,6 +9013,10 @@ rte_swx_pipeline_build(struct rte_swx_pipeline *p) if (status) goto error; + status = instruction_table_build(p); + if (status) + goto error; + status = action_build(p); if (status) goto error; @@ -9024,6 +9056,7 @@ error: selector_build_free(p); table_build_free(p); action_build_free(p); + instruction_table_build_free(p); metadata_build_free(p); header_build_free(p); extern_func_build_free(p); diff --git a/lib/pipeline/rte_swx_pipeline_internal.h b/lib/pipeline/rte_swx_pipeline_internal.h index 3578a10501..64625b40c6 100644 --- a/lib/pipeline/rte_swx_pipeline_internal.h +++ b/lib/pipeline/rte_swx_pipeline_internal.h @@ -541,6 +541,9 @@ enum instruction_type { * Return from action */ INSTR_RETURN, + + /* Start of custom instructions. */ + INSTR_CUSTOM_0, }; struct instr_operand { @@ -686,6 +689,8 @@ struct instruction_data { int invalid; }; +typedef void (*instr_exec_t)(struct rte_swx_pipeline *); + /* * Action. */ @@ -1363,6 +1368,10 @@ instr_operand_nbo(struct thread *t, const struct instr_operand *x) #define RTE_SWX_PIPELINE_THREADS_MAX 16 #endif +#ifndef RTE_SWX_PIPELINE_INSTRUCTION_TABLE_SIZE_MAX +#define RTE_SWX_PIPELINE_INSTRUCTION_TABLE_SIZE_MAX 256 +#endif + struct rte_swx_pipeline { struct struct_type_tailq struct_types; struct port_in_type_tailq port_in_types; @@ -1396,6 +1405,7 @@ struct rte_swx_pipeline { struct metarray_runtime *metarray_runtime; struct instruction *instructions; struct instruction_data *instruction_data; + instr_exec_t *instruction_table; struct thread threads[RTE_SWX_PIPELINE_THREADS_MAX]; uint32_t n_structs; -- 2.20.1