From patchwork Wed Sep 23 18:06:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Dumitrescu X-Patchwork-Id: 78588 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3F64CA04B1; Wed, 23 Sep 2020 20:07:53 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2AD791DB13; Wed, 23 Sep 2020 20:07:14 +0200 (CEST) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by dpdk.org (Postfix) with ESMTP id 6D6921DA20 for ; Wed, 23 Sep 2020 20:06:55 +0200 (CEST) IronPort-SDR: HNCRfTWRAhXtTZRSCw/TBrim8vIpRqxZCIu0cchR+tC4po5b5kunB3YHu+Cb1RiW77ZA6q+wL/ 8H3qX/SEpdnw== X-IronPort-AV: E=McAfee;i="6000,8403,9753"; a="245809503" X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="245809503" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 11:06:55 -0700 IronPort-SDR: dJBrznOoiurS9DU+XzjHzB5OB+F+Kz73PhgkuPJcckDqicYutE0khRflnO8FoU0OaYZfjaro4e lfnzl1xEJ8kQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,293,1596524400"; d="scan'208";a="305477832" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com) ([10.237.223.107]) by orsmga003.jf.intel.com with ESMTP; 23 Sep 2020 11:06:54 -0700 From: Cristian Dumitrescu To: dev@dpdk.org Cc: thomas@monjalon.net, david.marchand@redhat.com Date: Wed, 23 Sep 2020 19:06:10 +0100 Message-Id: <20200923180645.55852-7-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200923180645.55852-1-cristian.dumitrescu@intel.com> References: <20200910152645.9342-2-cristian.dumitrescu@intel.com> <20200923180645.55852-1-cristian.dumitrescu@intel.com> Subject: [dpdk-dev] [PATCH v5 06/41] pipeline: add SWX pipeline action X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" Add SWX actions that are dynamically-defined through instructions as opposed to pre-defined. The actions are subroutines of the pipeline program that triggered by table lookup. The input arguments are the action data from the table entry (format defined by struct), the headers and meta-data are in/out. Signed-off-by: Cristian Dumitrescu --- lib/librte_pipeline/rte_pipeline_version.map | 1 + lib/librte_pipeline/rte_swx_pipeline.c | 147 +++++++++++++++++++ lib/librte_pipeline/rte_swx_pipeline.h | 32 ++++ 3 files changed, 180 insertions(+) diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map index 4297e185d..c701f158d 100644 --- a/lib/librte_pipeline/rte_pipeline_version.map +++ b/lib/librte_pipeline/rte_pipeline_version.map @@ -67,6 +67,7 @@ EXPERIMENTAL { rte_swx_pipeline_struct_type_register; rte_swx_pipeline_packet_header_register; rte_swx_pipeline_packet_metadata_register; + rte_swx_pipeline_action_config; rte_swx_pipeline_build; rte_swx_pipeline_free; }; diff --git a/lib/librte_pipeline/rte_swx_pipeline.c b/lib/librte_pipeline/rte_swx_pipeline.c index 2335831bf..678700050 100644 --- a/lib/librte_pipeline/rte_swx_pipeline.c +++ b/lib/librte_pipeline/rte_swx_pipeline.c @@ -177,6 +177,26 @@ struct header_out_runtime { uint32_t n_bytes; }; +/* + * Instruction. + */ +struct instruction { +}; + +/* + * Action. + */ +struct action { + TAILQ_ENTRY(action) node; + char name[RTE_SWX_NAME_SIZE]; + struct struct_type *st; + struct instruction *instructions; + uint32_t n_instructions; + uint32_t id; +}; + +TAILQ_HEAD(action_tailq, action); + /* * Pipeline. */ @@ -216,9 +236,11 @@ struct rte_swx_pipeline { struct header_tailq headers; struct struct_type *metadata_st; uint32_t metadata_struct_id; + struct action_tailq actions; struct port_in_runtime *in; struct port_out_runtime *out; + struct instruction **action_instructions; struct thread threads[RTE_SWX_PIPELINE_THREADS_MAX]; uint32_t n_structs; @@ -226,6 +248,7 @@ struct rte_swx_pipeline { uint32_t n_ports_out; uint32_t n_extern_objs; uint32_t n_extern_funcs; + uint32_t n_actions; uint32_t n_headers; int build_done; int numa_node; @@ -1267,6 +1290,123 @@ metadata_free(struct rte_swx_pipeline *p) metadata_build_free(p); } +/* + * Instruction. + */ +static int +instruction_config(struct rte_swx_pipeline *p __rte_unused, + struct action *a __rte_unused, + const char **instructions __rte_unused, + uint32_t n_instructions __rte_unused) +{ + return 0; +} + +/* + * Action. + */ +static struct action * +action_find(struct rte_swx_pipeline *p, const char *name) +{ + struct action *elem; + + if (!name) + return NULL; + + TAILQ_FOREACH(elem, &p->actions, node) + if (strcmp(elem->name, name) == 0) + return elem; + + return NULL; +} + +int +rte_swx_pipeline_action_config(struct rte_swx_pipeline *p, + const char *name, + const char *args_struct_type_name, + const char **instructions, + uint32_t n_instructions) +{ + struct struct_type *args_struct_type; + struct action *a; + int err; + + CHECK(p, EINVAL); + + CHECK_NAME(name, EINVAL); + CHECK(!action_find(p, name), EEXIST); + + if (args_struct_type_name) { + CHECK_NAME(args_struct_type_name, EINVAL); + args_struct_type = struct_type_find(p, args_struct_type_name); + CHECK(args_struct_type, EINVAL); + } else { + args_struct_type = NULL; + } + + /* Node allocation. */ + a = calloc(1, sizeof(struct action)); + CHECK(a, ENOMEM); + + /* Node initialization. */ + strcpy(a->name, name); + a->st = args_struct_type; + a->id = p->n_actions; + + /* Instruction translation. */ + err = instruction_config(p, a, instructions, n_instructions); + if (err) { + free(a); + return err; + } + + /* Node add to tailq. */ + TAILQ_INSERT_TAIL(&p->actions, a, node); + p->n_actions++; + + return 0; +} + +static int +action_build(struct rte_swx_pipeline *p) +{ + struct action *action; + + p->action_instructions = calloc(p->n_actions, + sizeof(struct instruction *)); + CHECK(p->action_instructions, ENOMEM); + + TAILQ_FOREACH(action, &p->actions, node) + p->action_instructions[action->id] = action->instructions; + + return 0; +} + +static void +action_build_free(struct rte_swx_pipeline *p) +{ + free(p->action_instructions); + p->action_instructions = NULL; +} + +static void +action_free(struct rte_swx_pipeline *p) +{ + action_build_free(p); + + for ( ; ; ) { + struct action *action; + + action = TAILQ_FIRST(&p->actions); + if (!action) + break; + + TAILQ_REMOVE(&p->actions, action, node); + free(action->instructions); + free(action); + } +} + /* * Pipeline. */ @@ -1292,6 +1432,7 @@ rte_swx_pipeline_config(struct rte_swx_pipeline **p, int numa_node) TAILQ_INIT(&pipeline->extern_objs); TAILQ_INIT(&pipeline->extern_funcs); TAILQ_INIT(&pipeline->headers); + TAILQ_INIT(&pipeline->actions); pipeline->n_structs = 1; /* Struct 0 is reserved for action_data. */ pipeline->numa_node = numa_node; @@ -1306,6 +1447,7 @@ rte_swx_pipeline_free(struct rte_swx_pipeline *p) if (!p) return; + action_free(p); metadata_free(p); header_free(p); extern_func_free(p); @@ -1353,10 +1495,15 @@ rte_swx_pipeline_build(struct rte_swx_pipeline *p) if (status) goto error; + status = action_build(p); + if (status) + goto error; + p->build_done = 1; return 0; error: + action_build_free(p); metadata_build_free(p); header_build_free(p); extern_func_build_free(p); diff --git a/lib/librte_pipeline/rte_swx_pipeline.h b/lib/librte_pipeline/rte_swx_pipeline.h index 2e8a6cdf8..1b20293cb 100644 --- a/lib/librte_pipeline/rte_swx_pipeline.h +++ b/lib/librte_pipeline/rte_swx_pipeline.h @@ -344,6 +344,38 @@ int rte_swx_pipeline_packet_metadata_register(struct rte_swx_pipeline *p, const char *struct_type_name); +/* + * Pipeline action + */ + +/** + * Pipeline action configure + * + * @param[in] p + * Pipeline handle. + * @param[in] name + * Action name. + * @param[in] args_struct_type_name + * The struct type instantiated by the action data. The action data represent + * the action arguments that are stored in the table entry together with the + * action ID. Set to NULL when the action does not have any arguments. + * @param[in] instructions + * Action instructions. + * @param[in] n_instructions + * Number of action instructions. + * @return + * 0 on success or the following error codes otherwise: + * -EINVAL: Invalid argument; + * -ENOMEM: Not enough space/cannot allocate memory; + * -EEXIST: Action with this name already exists. + */ +__rte_experimental +int +rte_swx_pipeline_action_config(struct rte_swx_pipeline *p, + const char *name, + const char *args_struct_type_name, + const char **instructions, + uint32_t n_instructions); /** * Pipeline build