From patchwork Mon Sep 13 16:44:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Dumitrescu X-Patchwork-Id: 98788 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 154A1A0C45; Mon, 13 Sep 2021 18:46:53 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 39BFB4119B; Mon, 13 Sep 2021 18:45:10 +0200 (CEST) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mails.dpdk.org (Postfix) with ESMTP id 39F6941178 for ; Mon, 13 Sep 2021 18:45:05 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10106"; a="201239164" X-IronPort-AV: E=Sophos;i="5.85,290,1624345200"; d="scan'208";a="201239164" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Sep 2021 09:45:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.85,290,1624345200"; d="scan'208";a="507429224" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com) ([10.237.223.107]) by fmsmga008.fm.intel.com with ESMTP; 13 Sep 2021 09:45:03 -0700 From: Cristian Dumitrescu To: dev@dpdk.org Date: Mon, 13 Sep 2021 17:44:37 +0100 Message-Id: <20210913164443.16875-18-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210913164443.16875-1-cristian.dumitrescu@intel.com> References: <20210910133713.93103-1-cristian.dumitrescu@intel.com> <20210913164443.16875-1-cristian.dumitrescu@intel.com> Subject: [dpdk-dev] [PATCH V3 18/24] pipeline: introduce custom instructions X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- V3: -created per pipeline instance instruction table 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 @@ instruction_config(struct rte_swx_pipeline *p, 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 @@ rte_swx_pipeline_build(struct rte_swx_pipeline *p) 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;