From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 011F2A04B1; Wed, 30 Sep 2020 08:42:54 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3A5391DB44; Wed, 30 Sep 2020 08:35:47 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 8F59B1DAEA for ; Wed, 30 Sep 2020 08:34:52 +0200 (CEST) IronPort-SDR: Z2LvuWBJr3nWaGFdbf5IsbPtI9o7JvcDsTo+08rNU9FuuCpH9QW2JXd7nYdxj0Cj2wtv9PMRZy hmGb2Vpih5qA== X-IronPort-AV: E=McAfee;i="6000,8403,9759"; a="163238760" X-IronPort-AV: E=Sophos;i="5.77,321,1596524400"; d="scan'208";a="163238760" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Sep 2020 23:34:49 -0700 IronPort-SDR: g4fQRRx5hKRx5avo1G6x151s7LY7qUlvn1E+omTAEkaPuqMpnIsuOMk2jj+UdxmY+Nw6Eo/Pyc XZgS4TwdhTQA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,321,1596524400"; d="scan'208";a="495883055" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com) ([10.237.223.107]) by orsmga005.jf.intel.com with ESMTP; 29 Sep 2020 23:34:49 -0700 From: Cristian Dumitrescu To: dev@dpdk.org Cc: thomas@monjalon.net, david.marchand@redhat.com Date: Wed, 30 Sep 2020 07:33:58 +0100 Message-Id: <20200930063416.68428-25-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200930063416.68428-1-cristian.dumitrescu@intel.com> References: <20200923180645.55852-2-cristian.dumitrescu@intel.com> <20200930063416.68428-1-cristian.dumitrescu@intel.com> Subject: [dpdk-dev] [PATCH v6 24/42] pipeline: introduce SWX extern instruction 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" The extern instruction calls one of the member functions of a given extern object or it calls the given extern function. The function arguments must be written in advance to the mailbox. The results are available in the same place after execution. Signed-off-by: Cristian Dumitrescu --- lib/librte_pipeline/rte_swx_pipeline.c | 175 +++++++++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/lib/librte_pipeline/rte_swx_pipeline.c b/lib/librte_pipeline/rte_swx_pipeline.c index 887668481..aaf2aafa5 100644 --- a/lib/librte_pipeline/rte_swx_pipeline.c +++ b/lib/librte_pipeline/rte_swx_pipeline.c @@ -352,6 +352,12 @@ enum instruction_type { /* table TABLE */ INSTR_TABLE, + + /* extern e.obj.func */ + INSTR_EXTERN_OBJ, + + /* extern f.func */ + INSTR_EXTERN_FUNC, }; struct instr_operand { @@ -383,6 +389,15 @@ struct instr_table { uint8_t table_id; }; +struct instr_extern_obj { + uint8_t ext_obj_id; + uint8_t func_id; +}; + +struct instr_extern_func { + uint8_t ext_func_id; +}; + struct instr_dst_src { struct instr_operand dst; union { @@ -413,6 +428,8 @@ struct instruction { struct instr_dma dma; struct instr_dst_src alu; struct instr_table table; + struct instr_extern_obj ext_obj; + struct instr_extern_func ext_func; }; }; @@ -1271,6 +1288,50 @@ extern_obj_find(struct rte_swx_pipeline *p, const char *name) return NULL; } +static struct extern_type_member_func * +extern_obj_member_func_parse(struct rte_swx_pipeline *p, + const char *name, + struct extern_obj **obj) +{ + struct extern_obj *object; + struct extern_type_member_func *func; + char *object_name, *func_name; + + if (name[0] != 'e' || name[1] != '.') + return NULL; + + object_name = strdup(&name[2]); + if (!object_name) + return NULL; + + func_name = strchr(object_name, '.'); + if (!func_name) { + free(object_name); + return NULL; + } + + *func_name = 0; + func_name++; + + object = extern_obj_find(p, object_name); + if (!object) { + free(object_name); + return NULL; + } + + func = extern_type_member_func_find(object->type, func_name); + if (!func) { + free(object_name); + return NULL; + } + + if (obj) + *obj = object; + + free(object_name); + return func; +} + static struct field * extern_obj_mailbox_field_parse(struct rte_swx_pipeline *p, const char *name, @@ -1553,6 +1614,16 @@ extern_func_find(struct rte_swx_pipeline *p, const char *name) return NULL; } +static struct extern_func * +extern_func_parse(struct rte_swx_pipeline *p, + const char *name) +{ + if (name[0] != 'f' || name[1] != '.') + return NULL; + + return extern_func_find(p, &name[2]); +} + static struct field * extern_func_mailbox_field_parse(struct rte_swx_pipeline *p, const char *name, @@ -2097,6 +2168,12 @@ thread_yield(struct rte_swx_pipeline *p) p->thread_id = (p->thread_id + 1) & (RTE_SWX_PIPELINE_THREADS_MAX - 1); } +static inline void +thread_yield_cond(struct rte_swx_pipeline *p, int cond) +{ + p->thread_id = (p->thread_id + cond) & (RTE_SWX_PIPELINE_THREADS_MAX - 1); +} + /* * rx. */ @@ -2760,6 +2837,94 @@ instr_table_exec(struct rte_swx_pipeline *p) thread_ip_action_call(p, t, action_id); } +/* + * extern. + */ +static int +instr_extern_translate(struct rte_swx_pipeline *p, + struct action *action __rte_unused, + char **tokens, + int n_tokens, + struct instruction *instr, + struct instruction_data *data __rte_unused) +{ + char *token = tokens[1]; + + CHECK(n_tokens == 2, EINVAL); + + if (token[0] == 'e') { + struct extern_obj *obj; + struct extern_type_member_func *func; + + func = extern_obj_member_func_parse(p, token, &obj); + CHECK(func, EINVAL); + + instr->type = INSTR_EXTERN_OBJ; + instr->ext_obj.ext_obj_id = obj->id; + instr->ext_obj.func_id = func->id; + + return 0; + } + + if (token[0] == 'f') { + struct extern_func *func; + + func = extern_func_parse(p, token); + CHECK(func, EINVAL); + + instr->type = INSTR_EXTERN_FUNC; + instr->ext_func.ext_func_id = func->id; + + return 0; + } + + CHECK(0, EINVAL); +} + +static inline void +instr_extern_obj_exec(struct rte_swx_pipeline *p) +{ + struct thread *t = &p->threads[p->thread_id]; + struct instruction *ip = t->ip; + uint32_t obj_id = ip->ext_obj.ext_obj_id; + uint32_t func_id = ip->ext_obj.func_id; + struct extern_obj_runtime *obj = &t->extern_objs[obj_id]; + rte_swx_extern_type_member_func_t func = obj->funcs[func_id]; + + TRACE("[Thread %2u] extern obj %u member func %u\n", + p->thread_id, + obj_id, + func_id); + + /* Extern object member function execute. */ + uint32_t done = func(obj->obj, obj->mailbox); + + /* Thread. */ + thread_ip_inc_cond(t, done); + thread_yield_cond(p, done ^ 1); +} + +static inline void +instr_extern_func_exec(struct rte_swx_pipeline *p) +{ + struct thread *t = &p->threads[p->thread_id]; + struct instruction *ip = t->ip; + uint32_t ext_func_id = ip->ext_func.ext_func_id; + struct extern_func_runtime *ext_func = &t->extern_funcs[ext_func_id]; + rte_swx_extern_func_t func = ext_func->func; + + TRACE("[Thread %2u] extern func %u\n", + p->thread_id, + ext_func_id); + + /* Extern function execute. */ + uint32_t done = func(ext_func->mailbox); + + /* Thread. */ + thread_ip_inc_cond(t, done); + thread_yield_cond(p, done ^ 1); +} + /* * mov. */ @@ -4367,6 +4532,14 @@ instr_translate(struct rte_swx_pipeline *p, instr, data); + if (!strcmp(tokens[tpos], "extern")) + return instr_extern_translate(p, + action, + &tokens[tpos], + n_tokens - tpos, + instr, + data); + CHECK(0, EINVAL); } @@ -4571,6 +4744,8 @@ static instr_exec_t instruction_table[] = { [INSTR_ALU_SHR_HI] = instr_alu_shr_hi_exec, [INSTR_TABLE] = instr_table_exec, + [INSTR_EXTERN_OBJ] = instr_extern_obj_exec, + [INSTR_EXTERN_FUNC] = instr_extern_func_exec, }; static inline void -- 2.17.1