From patchwork Fri Feb 10 19:51:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Dumitrescu X-Patchwork-Id: 123710 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 3322241C61; Fri, 10 Feb 2023 20:51:25 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C67F0410D3; Fri, 10 Feb 2023 20:51:24 +0100 (CET) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mails.dpdk.org (Postfix) with ESMTP id 6FC7B40687 for ; Fri, 10 Feb 2023 20:51:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676058682; x=1707594682; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=pKhYu8hPzz5XaG/0eA4oJDBIzLG7CLOR3Q2DLNRMJEI=; b=ExsIpSZBdGVwo6NycArs9aF8ETpQRIGYkI4KGNdto5qW5XqoPRA2nS88 CsVWCpO6vosoGylZmSyJX0ca82uEQzgVOsylZjHgixj2AiRl/dFvDJCRq mgvpk1UsnEEDha1ycvl+9tF6dbsnxTHa7n63NqJqhjPwYCytvC+XQJf5p 71E6zaEEzdA5E6GTxfHvh+QBbx5vRcF6v+prVzyNkcAKk+0gEClFSM56E P8HsDL0ymbPzjDUJcjqC0ExtOti+R4YQYHhnlaCuQaT62VFM/wb1PttVq RNyPRbw4ThaZnOUoVdn2xoPJ6VmUXa/gqf8N3WQXTGe8jtJRHFCLyrakG w==; X-IronPort-AV: E=McAfee;i="6500,9779,10617"; a="318530930" X-IronPort-AV: E=Sophos;i="5.97,287,1669104000"; d="scan'208";a="318530930" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Feb 2023 11:51:12 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10617"; a="913657682" X-IronPort-AV: E=Sophos;i="5.97,287,1669104000"; d="scan'208";a="913657682" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com) ([10.237.222.53]) by fmsmga006.fm.intel.com with ESMTP; 10 Feb 2023 11:51:10 -0800 From: Cristian Dumitrescu To: dev@dpdk.org Cc: Kamalakannan R Subject: [PATCH] pipeline: support conversion between big and small fields Date: Fri, 10 Feb 2023 19:51:10 +0000 Message-Id: <20230210195110.683162-1-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 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 While the small fields (size <= 64 bits) can be in either network byte order (header fields) or host byte order (meta-data fields), the big fields (size > 64 bits) are always expected to be in network byte order (big endian), both header and metadata fields. Previously, a big field could be involved in an assignment only when both the destination and the source are big fields of exactly the same size. This restriction is now relaxed significantly: in case a big field is involved as either destination or source, the other field can now be either a big field (of the same or different size) or a small header field, so in either case both destination and source are in the network byte order. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- Depends-on: patch-26863 ("[V4] pipeline: add RSS support") lib/pipeline/rte_swx_pipeline.c | 33 +++++++++- lib/pipeline/rte_swx_pipeline_internal.h | 77 ++++++++++++------------ 2 files changed, 71 insertions(+), 39 deletions(-) diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c index 53d97f0072..dea1378095 100644 --- a/lib/pipeline/rte_swx_pipeline.c +++ b/lib/pipeline/rte_swx_pipeline.c @@ -3218,11 +3218,24 @@ instr_mov_translate(struct rte_swx_pipeline *p, if (dst[0] == 'h' && src[0] == 'h') instr->type = INSTR_MOV_HH; } else { - CHECK(fdst->n_bits == fsrc->n_bits, EINVAL); + /* The big fields (field with size > 64 bits) are always expected in NBO, + * regardless of their type (H or MEFT). In case a big field is involved as + * either dst or src, the other field must also be NBO. + * + * In case the dst field is big, the src field must be either a big field + * (of the same or different size as dst) or a small H field. Similarly, + * in case the src field is big, the dst field must be either a big field + * (of the same or different size as src) or a small H field. Any other case + * involving a big field as either dst or src is rejected. + */ + CHECK(fdst->n_bits > 64 || dst[0] == 'h', EINVAL); + CHECK(fsrc->n_bits > 64 || src[0] == 'h', EINVAL); instr->type = INSTR_MOV_DMA; - if (fdst->n_bits == 128) + if (fdst->n_bits == 128 && fsrc->n_bits == 128) instr->type = INSTR_MOV_128; + if (fdst->n_bits == 128 && fsrc->n_bits == 32) + instr->type = INSTR_MOV_128_32; } instr->mov.dst.struct_id = (uint8_t)dst_struct_id; @@ -3322,6 +3335,18 @@ instr_mov_128_exec(struct rte_swx_pipeline *p) thread_ip_inc(p); } +static inline void +instr_mov_128_32_exec(struct rte_swx_pipeline *p) +{ + struct thread *t = &p->threads[p->thread_id]; + struct instruction *ip = t->ip; + + __instr_mov_128_32_exec(p, t, ip); + + /* Thread. */ + thread_ip_inc(p); +} + static inline void instr_mov_i_exec(struct rte_swx_pipeline *p) { @@ -7435,6 +7460,7 @@ static instr_exec_t instruction_table[] = { [INSTR_MOV_HH] = instr_mov_hh_exec, [INSTR_MOV_DMA] = instr_mov_dma_exec, [INSTR_MOV_128] = instr_mov_128_exec, + [INSTR_MOV_128_32] = instr_mov_128_32_exec, [INSTR_MOV_I] = instr_mov_i_exec, [INSTR_DMA_HT] = instr_dma_ht_exec, @@ -11757,6 +11783,7 @@ instr_type_to_name(struct instruction *instr) case INSTR_MOV_HH: return "INSTR_MOV_HH"; case INSTR_MOV_DMA: return "INSTR_MOV_DMA"; case INSTR_MOV_128: return "INSTR_MOV_128"; + case INSTR_MOV_128_32: return "INSTR_MOV_128_32"; case INSTR_MOV_I: return "INSTR_MOV_I"; case INSTR_DMA_HT: return "INSTR_DMA_HT"; @@ -12797,6 +12824,7 @@ static instruction_export_t export_table[] = { [INSTR_MOV_HH] = instr_mov_export, [INSTR_MOV_DMA] = instr_mov_export, [INSTR_MOV_128] = instr_mov_export, + [INSTR_MOV_128_32] = instr_mov_export, [INSTR_MOV_I] = instr_mov_export, [INSTR_DMA_HT] = instr_dma_ht_export, @@ -13025,6 +13053,7 @@ instr_type_to_func(struct instruction *instr) case INSTR_MOV_HH: return "__instr_mov_hh_exec"; case INSTR_MOV_DMA: return "__instr_mov_dma_exec"; case INSTR_MOV_128: return "__instr_mov_128_exec"; + case INSTR_MOV_128_32: return "__instr_mov_128_32_exec"; case INSTR_MOV_I: return "__instr_mov_i_exec"; case INSTR_DMA_HT: return "__instr_dma_ht_exec"; diff --git a/lib/pipeline/rte_swx_pipeline_internal.h b/lib/pipeline/rte_swx_pipeline_internal.h index ac22d94a93..2f24e1a1c5 100644 --- a/lib/pipeline/rte_swx_pipeline_internal.h +++ b/lib/pipeline/rte_swx_pipeline_internal.h @@ -327,8 +327,9 @@ enum instruction_type { INSTR_MOV_MH, /* dst = MEF, src = H; size(dst) <= 64 bits, size(src) <= 64 bits. */ INSTR_MOV_HM, /* dst = H, src = MEFT; size(dst) <= 64 bits, size(src) <= 64 bits. */ INSTR_MOV_HH, /* dst = H, src = H; size(dst) <= 64 bits, size(src) <= 64 bits. */ - INSTR_MOV_DMA, /* dst = HMEF, src = HMEF; size(dst) = size(src) > 64 bits, NBO format. */ - INSTR_MOV_128, /* dst = HMEF, src = HMEF; size(dst) = size(src) = 128 bits, NBO format. */ + INSTR_MOV_DMA, /* dst and src in NBO format. */ + INSTR_MOV_128, /* dst and src in NBO format, size(dst) = size(src) = 128 bits. */ + INSTR_MOV_128_32, /* dst and src in NBO format, size(dst) = 128 bits, size(src) = 32 b. */ INSTR_MOV_I, /* dst = HMEF, src = I; size(dst) <= 64 bits. */ /* dma h.header t.field @@ -2611,48 +2612,31 @@ __instr_mov_dma_exec(struct rte_swx_pipeline *p __rte_unused, struct thread *t, const struct instruction *ip) { - uint8_t *dst_struct = t->structs[ip->mov.dst.struct_id]; - uint64_t *dst64_ptr = (uint64_t *)&dst_struct[ip->mov.dst.offset]; - uint32_t *dst32_ptr; - uint16_t *dst16_ptr; - uint8_t *dst8_ptr; + uint8_t *dst = t->structs[ip->mov.dst.struct_id] + ip->mov.dst.offset; + uint8_t *src = t->structs[ip->mov.src.struct_id] + ip->mov.src.offset; - uint8_t *src_struct = t->structs[ip->mov.src.struct_id]; - uint64_t *src64_ptr = (uint64_t *)&src_struct[ip->mov.src.offset]; - uint32_t *src32_ptr; - uint16_t *src16_ptr; - uint8_t *src8_ptr; - - uint32_t n = ip->mov.dst.n_bits >> 3, i; + uint32_t n_dst = ip->mov.dst.n_bits >> 3; + uint32_t n_src = ip->mov.src.n_bits >> 3; TRACE("[Thread %2u] mov (dma) %u bytes\n", p->thread_id, n); - /* 8-byte transfers. */ - for (i = 0; i < n >> 3; i++) - *dst64_ptr++ = *src64_ptr++; - - /* 4-byte transfers. */ - n &= 7; - dst32_ptr = (uint32_t *)dst64_ptr; - src32_ptr = (uint32_t *)src64_ptr; + /* Both dst and src are in NBO format. */ + if (n_dst > n_src) { + uint32_t n_dst_zero = n_dst - n_src; - for (i = 0; i < n >> 2; i++) - *dst32_ptr++ = *src32_ptr++; + /* Zero padding the most significant bytes in dst. */ + memset(dst, 0, n_dst_zero); + dst += n_dst_zero; - /* 2-byte transfers. */ - n &= 3; - dst16_ptr = (uint16_t *)dst32_ptr; - src16_ptr = (uint16_t *)src32_ptr; + /* Copy src to dst. */ + memcpy(dst, src, n_src); + } else { + uint32_t n_src_skipped = n_src - n_dst; - for (i = 0; i < n >> 1; i++) - *dst16_ptr++ = *src16_ptr++; - - /* 1-byte transfer. */ - n &= 1; - dst8_ptr = (uint8_t *)dst16_ptr; - src8_ptr = (uint8_t *)src16_ptr; - if (n) - *dst8_ptr = *src8_ptr; + /* Copy src to dst. */ + src += n_src_skipped; + memcpy(dst, src, n_dst); + } } static inline void @@ -2672,6 +2656,25 @@ __instr_mov_128_exec(struct rte_swx_pipeline *p __rte_unused, dst64_ptr[1] = src64_ptr[1]; } +static inline void +__instr_mov_128_32_exec(struct rte_swx_pipeline *p __rte_unused, + struct thread *t, + const struct instruction *ip) +{ + uint8_t *dst = t->structs[ip->mov.dst.struct_id] + ip->mov.dst.offset; + uint8_t *src = t->structs[ip->mov.src.struct_id] + ip->mov.src.offset; + + uint32_t *dst32 = (uint32_t *)dst; + uint32_t *src32 = (uint32_t *)src; + + TRACE("[Thread %2u] mov (128 <- 32)\n", p->thread_id); + + dst32[0] = 0; + dst32[1] = 0; + dst32[2] = 0; + dst32[3] = src32[0]; +} + static inline void __instr_mov_i_exec(struct rte_swx_pipeline *p __rte_unused, struct thread *t,