From patchwork Mon Sep 13 16:44:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Dumitrescu X-Patchwork-Id: 98794 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 DEBC0A0C45; Mon, 13 Sep 2021 18:47:30 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CC6F5411C2; Mon, 13 Sep 2021 18:45:17 +0200 (CEST) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mails.dpdk.org (Postfix) with ESMTP id 8AE92411A9 for ; Mon, 13 Sep 2021 18:45:12 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10106"; a="201239232" X-IronPort-AV: E=Sophos;i="5.85,290,1624345200"; d="scan'208";a="201239232" 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:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.85,290,1624345200"; d="scan'208";a="507429289" 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:11 -0700 From: Cristian Dumitrescu To: dev@dpdk.org Date: Mon, 13 Sep 2021 17:44:43 +0100 Message-Id: <20210913164443.16875-24-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 24/24] pipeline: enable pipeline compilation 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" Commit the pipeline changes when the compilation process is successful: change the table lookup instructions to execute the action function for each action, replace the regular pipeline instructions with the custom instructions. Signed-off-by: Cristian Dumitrescu --- V3: -added more checks lib/pipeline/rte_swx_pipeline.c | 94 +++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c index 02519a05a9..31f0029404 100644 --- a/lib/pipeline/rte_swx_pipeline.c +++ b/lib/pipeline/rte_swx_pipeline.c @@ -12177,6 +12177,26 @@ instruction_group_list_codegen(struct instruction_group_list *igl, } } +static uint32_t +instruction_group_list_custom_instructions_count(struct instruction_group_list *igl) +{ + struct instruction_group *g; + uint32_t n_custom_instr = 0; + + /* Groups with a single instruction: no function is generated for this group, the group + * keeps its current instruction. Groups with more than two instructions: one function and + * the associated custom instruction get generated for each such group. + */ + TAILQ_FOREACH(g, igl, node) { + if (g->first_instr_id == g->last_instr_id) + continue; + + n_custom_instr++; + } + + return n_custom_instr; +} + static int pipeline_codegen(struct rte_swx_pipeline *p, struct instruction_group_list *igl) { @@ -12331,6 +12351,73 @@ pipeline_libload(struct rte_swx_pipeline *p, struct instruction_group_list *igl) return status; } +static int +pipeline_adjust_check(struct rte_swx_pipeline *p __rte_unused, + struct instruction_group_list *igl) +{ + uint32_t n_custom_instr = instruction_group_list_custom_instructions_count(igl); + + /* Check that enough space is available within the pipeline instruction table to store all + * the custom instructions. + */ + if (INSTR_CUSTOM_0 + n_custom_instr > RTE_SWX_PIPELINE_INSTRUCTION_TABLE_SIZE_MAX) + return -ENOSPC; + + return 0; +} + +static void +pipeline_adjust(struct rte_swx_pipeline *p, struct instruction_group_list *igl) +{ + struct instruction_group *g; + uint32_t i; + + /* Pipeline table instructions. */ + for (i = 0; i < p->n_instructions; i++) { + struct instruction *instr = &p->instructions[i]; + + if (instr->type == INSTR_TABLE) + instr->type = INSTR_TABLE_AF; + + if (instr->type == INSTR_LEARNER) + instr->type = INSTR_LEARNER_AF; + } + + /* Pipeline custom instructions. */ + i = 0; + TAILQ_FOREACH(g, igl, node) { + struct instruction *instr = &p->instructions[g->first_instr_id]; + uint32_t j; + + if (g->first_instr_id == g->last_instr_id) + continue; + + /* Install a new custom instruction. */ + p->instruction_table[INSTR_CUSTOM_0 + i] = g->func; + + /* First instruction of the group: change its type to the new custom instruction. */ + instr->type = INSTR_CUSTOM_0 + i; + + /* All the subsequent instructions of the group: invalidate. */ + for (j = g->first_instr_id + 1; j <= g->last_instr_id; j++) { + struct instruction_data *data = &p->instruction_data[j]; + + data->invalid = 1; + } + + i++; + } + + /* Remove the invalidated instructions. */ + p->n_instructions = instr_compact(p->instructions, p->instruction_data, p->n_instructions); + + /* Resolve the jump destination for any "standalone" jump instructions (i.e. those jump + * instructions that are the only instruction within their group, so they were left + * unmodified). + */ + instr_jmp_resolve(p->instructions, p->instruction_data, p->n_instructions); +} + static int pipeline_compile(struct rte_swx_pipeline *p) { @@ -12353,6 +12440,13 @@ pipeline_compile(struct rte_swx_pipeline *p) if (status) goto free; + /* Adjust instructions. */ + status = pipeline_adjust_check(p, igl); + if (status) + goto free; + + pipeline_adjust(p, igl); + free: instruction_group_list_free(igl);