From patchwork Fri Aug 12 09:54:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Dumitrescu X-Patchwork-Id: 114884 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 21E55A0543; Fri, 12 Aug 2022 11:54:54 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 37FEE427F2; Fri, 12 Aug 2022 11:54:50 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mails.dpdk.org (Postfix) with ESMTP id 7A031406A2 for ; Fri, 12 Aug 2022 11:54:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660298088; x=1691834088; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VZHBFK/c7fRdHBb3/M6Q2uuAW/CWkUESAf0imZnsf8c=; b=Qdekp7hkxU3CoSilEAZrMKtBLCtEdOLPRtv83NY4Nay8MOMffHLu7PdN gDYpGEYFDJVTc5q6llWE0TUvwZlkf9Gq+y27Bed8aLXmHSEOYo7omKmrw lg01sINFLb3hxS6Vny93m7w/fHvXuFG7ZvK3CqCmo4aV+tmb6CCQLE1wf jZxavuG9YtiNQXamRNhWJhu9i8N0rvB+1laD2cH1nP/h/sGKR+1sUQ7QE 8RW6+GxNjXVTBYk3t/FOjIpKdWHUTk0BN2HK3HO4d9c8Xd+L7/yY5rn4J Bt48qe/6GH4WDUL5+QyLHgZFSmbuTXd5AJml1V0c+ORfFZtyYIh+5NYl/ Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10436"; a="289135014" X-IronPort-AV: E=Sophos;i="5.93,231,1654585200"; d="scan'208";a="289135014" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 02:54:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,231,1654585200"; d="scan'208";a="634589076" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com.) ([10.237.223.157]) by orsmga008.jf.intel.com with ESMTP; 12 Aug 2022 02:54:46 -0700 From: Cristian Dumitrescu To: dev@dpdk.org Cc: Harshad Suresh Narayane Subject: [PATCH 1/4] pipeline: remove the 64-bit limit for structure fields Date: Fri, 12 Aug 2022 09:54:42 +0000 Message-Id: <20220812095445.1253138-2-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220812095445.1253138-1-cristian.dumitrescu@intel.com> References: <20220812095445.1253138-1-cristian.dumitrescu@intel.com> 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 Remove the generic limitation of structure fields to 64 bits or less and push this restriction to the instructions that require it. Signed-off-by: Cristian Dumitrescu Signed-off-by: Harshad Suresh Narayane --- lib/pipeline/rte_swx_pipeline.c | 104 ++++++++++++++------------- lib/pipeline/rte_swx_pipeline_spec.c | 3 +- 2 files changed, 56 insertions(+), 51 deletions(-) diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c index 12e156b00b..15c840b352 100644 --- a/lib/pipeline/rte_swx_pipeline.c +++ b/lib/pipeline/rte_swx_pipeline.c @@ -138,12 +138,10 @@ rte_swx_pipeline_struct_type_register(struct rte_swx_pipeline *p, for (i = 0; i < n_fields; i++) { struct rte_swx_field_params *f = &fields[i]; - int var_size = ((i == n_fields - 1) && last_field_has_variable_size) ? 1 : 0; uint32_t j; CHECK_NAME(f->name, EINVAL); CHECK(f->n_bits, EINVAL); - CHECK((f->n_bits <= 64) || var_size, EINVAL); CHECK((f->n_bits & 7) == 0, EINVAL); for (j = 0; j < i; j++) { @@ -1728,6 +1726,7 @@ instr_rx_translate(struct rte_swx_pipeline *p, f = metadata_field_parse(p, tokens[1]); CHECK(f, EINVAL); + CHECK(f->n_bits <= 64, EINVAL); instr->type = INSTR_RX; instr->io.io.offset = f->offset / 8; @@ -1754,6 +1753,7 @@ instr_tx_translate(struct rte_swx_pipeline *p, f = metadata_field_parse(p, port); if (f) { + CHECK(f->n_bits <= 64, EINVAL); instr->type = INSTR_TX; instr->io.io.offset = f->offset / 8; instr->io.io.n_bits = f->n_bits; @@ -1843,12 +1843,12 @@ instr_mirror_translate(struct rte_swx_pipeline *p, fdst = struct_field_parse(p, action, dst, &dst_struct_id); CHECK(fdst, EINVAL); CHECK(dst[0] != 'h', EINVAL); - CHECK(!fdst->var_size, EINVAL); + CHECK(!fdst->var_size && (fdst->n_bits <= 64), EINVAL); fsrc = struct_field_parse(p, action, src, &src_struct_id); CHECK(fsrc, EINVAL); CHECK(src[0] != 'h', EINVAL); - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_MIRROR; instr->mirror.dst.struct_id = (uint8_t)dst_struct_id; @@ -1904,6 +1904,7 @@ instr_recircid_translate(struct rte_swx_pipeline *p, f = metadata_field_parse(p, tokens[1]); CHECK(f, EINVAL); + CHECK(f->n_bits <= 64, EINVAL); instr->type = INSTR_RECIRCID; instr->io.io.offset = f->offset / 8; @@ -1968,7 +1969,7 @@ instr_hdr_extract_translate(struct rte_swx_pipeline *p, mf = metadata_field_parse(p, tokens[2]); CHECK(mf, EINVAL); - CHECK(!mf->var_size, EINVAL); + CHECK(mf->n_bits <= 64, EINVAL); instr->type = INSTR_HDR_EXTRACT_M; instr->io.io.offset = mf->offset / 8; @@ -2693,6 +2694,7 @@ instr_learn_translate(struct rte_swx_pipeline *p, if (mf_first_arg_name) { mf_first_arg = metadata_field_parse(p, mf_first_arg_name); CHECK(mf_first_arg, EINVAL); + CHECK(mf_first_arg->n_bits <= 64, EINVAL); } /* Timeout ID. */ @@ -2700,6 +2702,7 @@ instr_learn_translate(struct rte_swx_pipeline *p, CHECK_NAME(mf_timeout_id_name, EINVAL); mf_timeout_id = metadata_field_parse(p, mf_timeout_id_name); CHECK(mf_timeout_id, EINVAL); + CHECK(mf_timeout_id->n_bits <= 64, EINVAL); /* Instruction. */ instr->type = INSTR_LEARNER_LEARN; @@ -2751,6 +2754,7 @@ instr_rearm_translate(struct rte_swx_pipeline *p, CHECK_NAME(mf_timeout_id_name, EINVAL); mf_timeout_id = metadata_field_parse(p, mf_timeout_id_name); CHECK(mf_timeout_id, EINVAL); + CHECK(mf_timeout_id->n_bits <= 64, EINVAL); instr->type = INSTR_LEARNER_REARM_NEW; instr->learn.mf_timeout_id_offset = mf_timeout_id->offset / 8; @@ -2910,12 +2914,14 @@ instr_hash_translate(struct rte_swx_pipeline *p, dst = metadata_field_parse(p, tokens[2]); CHECK(dst, EINVAL); + CHECK(dst->n_bits <= 64, EINVAL); src_first = struct_field_parse(p, action, tokens[3], &src_struct_id_first); CHECK(src_first, EINVAL); src_last = struct_field_parse(p, action, tokens[4], &src_struct_id_last); CHECK(src_last, EINVAL); + CHECK(!src_last->var_size, EINVAL); CHECK(src_struct_id_first == src_struct_id_last, EINVAL); instr->type = INSTR_HASH_FUNC; @@ -2963,12 +2969,12 @@ instr_mov_translate(struct rte_swx_pipeline *p, fdst = struct_field_parse(p, NULL, dst, &dst_struct_id); CHECK(fdst, EINVAL); - CHECK(!fdst->var_size, EINVAL); + CHECK(!fdst->var_size && (fdst->n_bits <= 64), EINVAL); /* MOV, MOV_MH, MOV_HM or MOV_HH. */ fsrc = struct_field_parse(p, action, src, &src_struct_id); if (fsrc) { - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_MOV; if (dst[0] != 'h' && src[0] == 'h') @@ -3181,12 +3187,12 @@ instr_alu_add_translate(struct rte_swx_pipeline *p, fdst = struct_field_parse(p, NULL, dst, &dst_struct_id); CHECK(fdst, EINVAL); - CHECK(!fdst->var_size, EINVAL); + CHECK(!fdst->var_size && (fdst->n_bits <= 64), EINVAL); /* ADD, ADD_HM, ADD_MH, ADD_HH. */ fsrc = struct_field_parse(p, action, src, &src_struct_id); if (fsrc) { - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_ALU_ADD; if (dst[0] == 'h' && src[0] != 'h') @@ -3237,12 +3243,12 @@ instr_alu_sub_translate(struct rte_swx_pipeline *p, fdst = struct_field_parse(p, NULL, dst, &dst_struct_id); CHECK(fdst, EINVAL); - CHECK(!fdst->var_size, EINVAL); + CHECK(!fdst->var_size && (fdst->n_bits <= 64), EINVAL); /* SUB, SUB_HM, SUB_MH, SUB_HH. */ fsrc = struct_field_parse(p, action, src, &src_struct_id); if (fsrc) { - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_ALU_SUB; if (dst[0] == 'h' && src[0] != 'h') @@ -3297,7 +3303,7 @@ instr_alu_ckadd_translate(struct rte_swx_pipeline *p, /* CKADD_FIELD. */ fsrc = header_field_parse(p, src, &hsrc); if (fsrc) { - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_ALU_CKADD_FIELD; instr->alu.dst.struct_id = (uint8_t)hdst->struct_id; @@ -3346,7 +3352,7 @@ instr_alu_cksub_translate(struct rte_swx_pipeline *p, fsrc = header_field_parse(p, src, &hsrc); CHECK(fsrc, EINVAL); - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_ALU_CKSUB_FIELD; instr->alu.dst.struct_id = (uint8_t)hdst->struct_id; @@ -3375,12 +3381,12 @@ instr_alu_shl_translate(struct rte_swx_pipeline *p, fdst = struct_field_parse(p, NULL, dst, &dst_struct_id); CHECK(fdst, EINVAL); - CHECK(!fdst->var_size, EINVAL); + CHECK(!fdst->var_size && (fdst->n_bits <= 64), EINVAL); /* SHL, SHL_HM, SHL_MH, SHL_HH. */ fsrc = struct_field_parse(p, action, src, &src_struct_id); if (fsrc) { - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_ALU_SHL; if (dst[0] == 'h' && src[0] != 'h') @@ -3431,12 +3437,12 @@ instr_alu_shr_translate(struct rte_swx_pipeline *p, fdst = struct_field_parse(p, NULL, dst, &dst_struct_id); CHECK(fdst, EINVAL); - CHECK(!fdst->var_size, EINVAL); + CHECK(!fdst->var_size && (fdst->n_bits <= 64), EINVAL); /* SHR, SHR_HM, SHR_MH, SHR_HH. */ fsrc = struct_field_parse(p, action, src, &src_struct_id); if (fsrc) { - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_ALU_SHR; if (dst[0] == 'h' && src[0] != 'h') @@ -3487,12 +3493,12 @@ instr_alu_and_translate(struct rte_swx_pipeline *p, fdst = struct_field_parse(p, NULL, dst, &dst_struct_id); CHECK(fdst, EINVAL); - CHECK(!fdst->var_size, EINVAL); + CHECK(!fdst->var_size && (fdst->n_bits <= 64), EINVAL); /* AND, AND_MH, AND_HM, AND_HH. */ fsrc = struct_field_parse(p, action, src, &src_struct_id); if (fsrc) { - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_ALU_AND; if (dst[0] != 'h' && src[0] == 'h') @@ -3543,12 +3549,12 @@ instr_alu_or_translate(struct rte_swx_pipeline *p, fdst = struct_field_parse(p, NULL, dst, &dst_struct_id); CHECK(fdst, EINVAL); - CHECK(!fdst->var_size, EINVAL); + CHECK(!fdst->var_size && (fdst->n_bits <= 64), EINVAL); /* OR, OR_MH, OR_HM, OR_HH. */ fsrc = struct_field_parse(p, action, src, &src_struct_id); if (fsrc) { - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_ALU_OR; if (dst[0] != 'h' && src[0] == 'h') @@ -3599,12 +3605,12 @@ instr_alu_xor_translate(struct rte_swx_pipeline *p, fdst = struct_field_parse(p, NULL, dst, &dst_struct_id); CHECK(fdst, EINVAL); - CHECK(!fdst->var_size, EINVAL); + CHECK(!fdst->var_size && (fdst->n_bits <= 64), EINVAL); /* XOR, XOR_MH, XOR_HM, XOR_HH. */ fsrc = struct_field_parse(p, action, src, &src_struct_id); if (fsrc) { - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_ALU_XOR; if (dst[0] != 'h' && src[0] == 'h') @@ -4224,7 +4230,7 @@ instr_regprefetch_translate(struct rte_swx_pipeline *p, /* REGPREFETCH_RH, REGPREFETCH_RM. */ fidx = struct_field_parse(p, action, idx, &idx_struct_id); if (fidx) { - CHECK(!fidx->var_size, EINVAL); + CHECK(!fidx->var_size && (fidx->n_bits <= 64), EINVAL); instr->type = INSTR_REGPREFETCH_RM; if (idx[0] == 'h') @@ -4269,12 +4275,12 @@ instr_regrd_translate(struct rte_swx_pipeline *p, fdst = struct_field_parse(p, NULL, dst, &dst_struct_id); CHECK(fdst, EINVAL); - CHECK(!fdst->var_size, EINVAL); + CHECK(!fdst->var_size && (fdst->n_bits <= 64), EINVAL); /* REGRD_HRH, REGRD_HRM, REGRD_MRH, REGRD_MRM. */ fidx = struct_field_parse(p, action, idx, &idx_struct_id); if (fidx) { - CHECK(!fidx->var_size, EINVAL); + CHECK(!fidx->var_size && (fidx->n_bits <= 64), EINVAL); instr->type = INSTR_REGRD_MRM; if (dst[0] == 'h' && idx[0] != 'h') @@ -4333,8 +4339,8 @@ instr_regwr_translate(struct rte_swx_pipeline *p, fidx = struct_field_parse(p, action, idx, &idx_struct_id); fsrc = struct_field_parse(p, action, src, &src_struct_id); if (fidx && fsrc) { - CHECK(!fidx->var_size, EINVAL); - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fidx->var_size && (fidx->n_bits <= 64), EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_REGWR_RMM; if (idx[0] == 'h' && src[0] != 'h') @@ -4356,7 +4362,7 @@ instr_regwr_translate(struct rte_swx_pipeline *p, /* REGWR_RHI, REGWR_RMI. */ if (fidx && !fsrc) { - CHECK(!fidx->var_size, EINVAL); + CHECK(!fidx->var_size && (fidx->n_bits <= 64), EINVAL); src_val = strtoull(src, &src, 0); CHECK(!src[0], EINVAL); @@ -4378,7 +4384,7 @@ instr_regwr_translate(struct rte_swx_pipeline *p, idx_val = strtoul(idx, &idx, 0); CHECK(!idx[0], EINVAL); - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_REGWR_RIM; if (src[0] == 'h') @@ -4429,8 +4435,8 @@ instr_regadd_translate(struct rte_swx_pipeline *p, fidx = struct_field_parse(p, action, idx, &idx_struct_id); fsrc = struct_field_parse(p, action, src, &src_struct_id); if (fidx && fsrc) { - CHECK(!fidx->var_size, EINVAL); - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fidx->var_size && (fidx->n_bits <= 64), EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_REGADD_RMM; if (idx[0] == 'h' && src[0] != 'h') @@ -4452,7 +4458,7 @@ instr_regadd_translate(struct rte_swx_pipeline *p, /* REGADD_RHI, REGADD_RMI. */ if (fidx && !fsrc) { - CHECK(!fidx->var_size, EINVAL); + CHECK(!fidx->var_size && (fidx->n_bits <= 64), EINVAL); src_val = strtoull(src, &src, 0); CHECK(!src[0], EINVAL); @@ -4474,7 +4480,7 @@ instr_regadd_translate(struct rte_swx_pipeline *p, idx_val = strtoul(idx, &idx, 0); CHECK(!idx[0], EINVAL); - CHECK(!fsrc->var_size, EINVAL); + CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); instr->type = INSTR_REGADD_RIM; if (src[0] == 'h') @@ -4879,7 +4885,7 @@ instr_metprefetch_translate(struct rte_swx_pipeline *p, /* METPREFETCH_H, METPREFETCH_M. */ fidx = struct_field_parse(p, action, idx, &idx_struct_id); if (fidx) { - CHECK(!fidx->var_size, EINVAL); + CHECK(!fidx->var_size && (fidx->n_bits <= 64), EINVAL); instr->type = INSTR_METPREFETCH_M; if (idx[0] == 'h') @@ -4926,18 +4932,18 @@ instr_meter_translate(struct rte_swx_pipeline *p, flength = struct_field_parse(p, action, length, &length_struct_id); CHECK(flength, EINVAL); - CHECK(!flength->var_size, EINVAL); + CHECK(!flength->var_size && (flength->n_bits <= 64), EINVAL); fcin = struct_field_parse(p, action, color_in, &color_in_struct_id); fcout = struct_field_parse(p, NULL, color_out, &color_out_struct_id); CHECK(fcout, EINVAL); - CHECK(!fcout->var_size, EINVAL); + CHECK(!fcout->var_size && (fcout->n_bits <= 64), EINVAL); /* index = HMEFT, length = HMEFT, color_in = MEFT, color_out = MEF. */ if (fidx && fcin) { - CHECK(!fidx->var_size, EINVAL); - CHECK(!fcin->var_size, EINVAL); + CHECK(!fidx->var_size && (fidx->n_bits <= 64), EINVAL); + CHECK(!fcin->var_size && (fcin->n_bits <= 64), EINVAL); instr->type = INSTR_METER_MMM; if (idx[0] == 'h' && length[0] == 'h') @@ -4970,7 +4976,7 @@ instr_meter_translate(struct rte_swx_pipeline *p, if (fidx && !fcin) { uint32_t color_in_val; - CHECK(!fidx->var_size, EINVAL); + CHECK(!fidx->var_size && (fidx->n_bits <= 64), EINVAL); color_in_val = strtoul(color_in, &color_in, 0); CHECK(!color_in[0], EINVAL); @@ -5007,7 +5013,7 @@ instr_meter_translate(struct rte_swx_pipeline *p, idx_val = strtoul(idx, &idx, 0); CHECK(!idx[0], EINVAL); - CHECK(!fcin->var_size, EINVAL); + CHECK(!fcin->var_size && (fcin->n_bits <= 64), EINVAL); instr->type = INSTR_METER_IMM; if (length[0] == 'h') @@ -5426,12 +5432,12 @@ instr_jmp_eq_translate(struct rte_swx_pipeline *p, fa = struct_field_parse(p, action, a, &a_struct_id); CHECK(fa, EINVAL); - CHECK(!fa->var_size, EINVAL); + CHECK(!fa->var_size && (fa->n_bits <= 64), EINVAL); /* JMP_EQ, JMP_EQ_MH, JMP_EQ_HM, JMP_EQ_HH. */ fb = struct_field_parse(p, action, b, &b_struct_id); if (fb) { - CHECK(!fb->var_size, EINVAL); + CHECK(!fb->var_size && (fb->n_bits <= 64), EINVAL); instr->type = INSTR_JMP_EQ; if (a[0] != 'h' && b[0] == 'h') @@ -5486,12 +5492,12 @@ instr_jmp_neq_translate(struct rte_swx_pipeline *p, fa = struct_field_parse(p, action, a, &a_struct_id); CHECK(fa, EINVAL); - CHECK(!fa->var_size, EINVAL); + CHECK(!fa->var_size && (fa->n_bits <= 64), EINVAL); /* JMP_NEQ, JMP_NEQ_MH, JMP_NEQ_HM, JMP_NEQ_HH. */ fb = struct_field_parse(p, action, b, &b_struct_id); if (fb) { - CHECK(!fb->var_size, EINVAL); + CHECK(!fb->var_size && (fb->n_bits <= 64), EINVAL); instr->type = INSTR_JMP_NEQ; if (a[0] != 'h' && b[0] == 'h') @@ -5546,12 +5552,12 @@ instr_jmp_lt_translate(struct rte_swx_pipeline *p, fa = struct_field_parse(p, action, a, &a_struct_id); CHECK(fa, EINVAL); - CHECK(!fa->var_size, EINVAL); + CHECK(!fa->var_size && (fa->n_bits <= 64), EINVAL); /* JMP_LT, JMP_LT_MH, JMP_LT_HM, JMP_LT_HH. */ fb = struct_field_parse(p, action, b, &b_struct_id); if (fb) { - CHECK(!fb->var_size, EINVAL); + CHECK(!fb->var_size && (fb->n_bits <= 64), EINVAL); instr->type = INSTR_JMP_LT; if (a[0] == 'h' && b[0] != 'h') @@ -5606,12 +5612,12 @@ instr_jmp_gt_translate(struct rte_swx_pipeline *p, fa = struct_field_parse(p, action, a, &a_struct_id); CHECK(fa, EINVAL); - CHECK(!fa->var_size, EINVAL); + CHECK(!fa->var_size && (fa->n_bits <= 64), EINVAL); /* JMP_GT, JMP_GT_MH, JMP_GT_HM, JMP_GT_HH. */ fb = struct_field_parse(p, action, b, &b_struct_id); if (fb) { - CHECK(!fb->var_size, EINVAL); + CHECK(!fb->var_size && (fb->n_bits <= 64), EINVAL); instr->type = INSTR_JMP_GT; if (a[0] == 'h' && b[0] != 'h') diff --git a/lib/pipeline/rte_swx_pipeline_spec.c b/lib/pipeline/rte_swx_pipeline_spec.c index 3c16daf7de..1b4183ef55 100644 --- a/lib/pipeline/rte_swx_pipeline_spec.c +++ b/lib/pipeline/rte_swx_pipeline_spec.c @@ -228,8 +228,7 @@ struct_block_parse(struct struct_spec *s, n_bits = strtoul(p, &p, 0); if ((p[0]) || !n_bits || - (n_bits % 8) || - ((n_bits > 64) && !varbit)) { + (n_bits % 8)) { error = -EINVAL; error_size_invalid = 1; goto error; From patchwork Fri Aug 12 09:54:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Dumitrescu X-Patchwork-Id: 114885 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 B0027A0543; Fri, 12 Aug 2022 11:54:59 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id F104042C04; Fri, 12 Aug 2022 11:54:50 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mails.dpdk.org (Postfix) with ESMTP id C2A8C410E7 for ; Fri, 12 Aug 2022 11:54:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660298089; x=1691834089; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EvnaB5jnOVA2lUTYDU1Sf47PjzYptVLmCUNFa2tLbCQ=; b=n5sz6BaZSn/3PPovdaJA8m9AjmraxzLjm3iwnammvKXMQZfiEg0N37ol JQfjO2BuGr0Wi9pn7zS0oYvMxBl08tzNAJ1jPr74WRfRJOelc3vvutExv Btyj/YI0mGfGQ9gWT4SALwHyDvoa6zr6YsL8Q70SJQ3mo1ZDyemsmxWRZ yeAiy5VJOUzbXHGihOl8AWcB9liZvh7ZoHnlCPEz2cx9v1tJIYDA0AmDP u9Fwq997n8p+Jrkf7wByxHTUv5LsikSBho2r5XezAwL+EMwWpci+ng/Ap I1z0MC6cHbOnERgvYUVVrQ8Y+BcN9H6Sjjb2ceBpGyi1+m7fkA7WPoMJQ Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10436"; a="289135016" X-IronPort-AV: E=Sophos;i="5.93,231,1654585200"; d="scan'208";a="289135016" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 02:54:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,231,1654585200"; d="scan'208";a="634589086" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com.) ([10.237.223.157]) by orsmga008.jf.intel.com with ESMTP; 12 Aug 2022 02:54:48 -0700 From: Cristian Dumitrescu To: dev@dpdk.org Cc: Harshad Suresh Narayane Subject: [PATCH 2/4] pipeline: read large structure fields on the control path Date: Fri, 12 Aug 2022 09:54:43 +0000 Message-Id: <20220812095445.1253138-3-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220812095445.1253138-1-cristian.dumitrescu@intel.com> References: <20220812095445.1253138-1-cristian.dumitrescu@intel.com> 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 Support reading structure fields that are bigger than 64 bits on the control path for the table update operations. Signed-off-by: Cristian Dumitrescu Signed-off-by: Harshad Suresh Narayane --- lib/pipeline/rte_swx_ctl.c | 357 +++++++++++++++++++++++++++++++------ 1 file changed, 298 insertions(+), 59 deletions(-) diff --git a/lib/pipeline/rte_swx_ctl.c b/lib/pipeline/rte_swx_ctl.c index 1b776fc543..bdbcd8f50a 100644 --- a/lib/pipeline/rte_swx_ctl.c +++ b/lib/pipeline/rte_swx_ctl.c @@ -2694,6 +2694,270 @@ mask_to_prefix(uint64_t mask, uint32_t mask_length, uint32_t *prefix_length) return 0; } +static int +large_mask_to_prefix(uint8_t *mask, uint32_t n_mask_bytes, uint32_t *prefix_length) +{ + uint32_t pl, i; + + /* Check input arguments. */ + if (!mask || !n_mask_bytes || !prefix_length) + return -EINVAL; + + /* Count leading bits of one. */ + for (i = 0; i < n_mask_bytes * 8; i++) { + uint32_t byte_id = i / 8; + uint32_t bit_id = i & 7; + + uint32_t byte = mask[byte_id]; + uint32_t bit = byte & (1 << (7 - bit_id)); + + if (!bit) + break; + } + + /* Save the potential prefix length. */ + pl = i; + + /* Check that all remaining bits are zeros. */ + for ( ; i < n_mask_bytes * 8; i++) { + uint32_t byte_id = i / 8; + uint32_t bit_id = i & 7; + + uint32_t byte = mask[byte_id]; + uint32_t bit = byte & (1 << (7 - bit_id)); + + if (bit) + break; + } + + if (i < n_mask_bytes * 8) + return -EINVAL; + + *prefix_length = pl; + return 0; +} + +static int +char_to_hex(char c, uint8_t *val) +{ + if (c >= '0' && c <= '9') { + *val = c - '0'; + return 0; + } + + if (c >= 'A' && c <= 'F') { + *val = c - 'A' + 10; + return 0; + } + + if (c >= 'a' && c <= 'f') { + *val = c - 'a' + 10; + return 0; + } + + return -EINVAL; +} + +static int +hex_string_parse(char *src, uint8_t *dst, uint32_t n_dst_bytes) +{ + uint32_t i; + + /* Check input arguments. */ + if (!src || !src[0] || !dst || !n_dst_bytes) + return -EINVAL; + + /* Skip any leading "0x" or "0X" in the src string. */ + if ((src[0] == '0') && (src[1] == 'x' || src[1] == 'X')) + src += 2; + + /* Convert each group of two hex characters in the src string to one byte in dst array. */ + for (i = 0; i < n_dst_bytes; i++) { + uint8_t a, b; + int status; + + status = char_to_hex(*src, &a); + if (status) + return status; + src++; + + status = char_to_hex(*src, &b); + if (status) + return status; + src++; + + dst[i] = a * 16 + b; + } + + /* Check for the end of the src string. */ + if (*src) + return -EINVAL; + + return 0; +} + +static int +table_entry_match_field_read(struct table *table, + struct rte_swx_table_entry *entry, + uint32_t mf_id, + char *mf_val, + char *mf_mask, + int *lpm, + uint32_t *lpm_prefix_length_max, + uint32_t *lpm_prefix_length) +{ + struct rte_swx_ctl_table_match_field_info *mf = &table->mf[mf_id]; + uint64_t val, mask = UINT64_MAX; + uint32_t offset = (mf->offset - table->mf_first->offset) / 8; + + /* + * Mask. + */ + if (mf_mask) { + /* Parse. */ + mask = strtoull(mf_mask, &mf_mask, 0); + if (mf_mask[0]) + return -EINVAL; + + /* LPM. */ + if (mf->match_type == RTE_SWX_TABLE_MATCH_LPM) { + int status; + + *lpm = 1; + + *lpm_prefix_length_max = mf->n_bits; + + status = mask_to_prefix(mask, mf->n_bits, lpm_prefix_length); + if (status) + return status; + } + + /* Endianness conversion. */ + if (mf->is_header) + mask = field_hton(mask, mf->n_bits); + } + + /* Copy to entry. */ + if (entry->key_mask) + memcpy(&entry->key_mask[offset], (uint8_t *)&mask, mf->n_bits / 8); + + /* + * Value. + */ + /* Parse. */ + val = strtoull(mf_val, &mf_val, 0); + if (mf_val[0]) + return -EINVAL; + + /* Endianness conversion. */ + if (mf->is_header) + val = field_hton(val, mf->n_bits); + + /* Copy to entry. */ + memcpy(&entry->key[offset], (uint8_t *)&val, mf->n_bits / 8); + + return 0; +} + +static int +table_entry_action_argument_read(struct action *action, + struct rte_swx_table_entry *entry, + uint32_t arg_id, + uint32_t arg_offset, + char *arg_val) +{ + struct rte_swx_ctl_action_arg_info *arg = &action->args[arg_id]; + uint64_t val; + + val = strtoull(arg_val, &arg_val, 0); + if (arg_val[0]) + return -EINVAL; + + /* Endianness conversion. */ + if (arg->is_network_byte_order) + val = field_hton(val, arg->n_bits); + + /* Copy to entry. */ + memcpy(&entry->action_data[arg_offset], + (uint8_t *)&val, + arg->n_bits / 8); + + return 0; +} + +static int +table_entry_large_match_field_read(struct table *table, + struct rte_swx_table_entry *entry, + uint32_t mf_id, + char *mf_val, + char *mf_mask, + int *lpm, + uint32_t *lpm_prefix_length_max, + uint32_t *lpm_prefix_length) +{ + struct rte_swx_ctl_table_match_field_info *mf = &table->mf[mf_id]; + uint32_t offset = (mf->offset - table->mf_first->offset) / 8; + int status; + + /* + * Mask. + */ + if (!entry->key_mask) + goto value; + + if (!mf_mask) { + /* Set mask to all-ones. */ + memset(&entry->key_mask[offset], 0xFF, mf->n_bits / 8); + goto value; + } + + /* Parse. */ + status = hex_string_parse(mf_mask, &entry->key_mask[offset], mf->n_bits / 8); + if (status) + return -EINVAL; + + /* LPM. */ + if (mf->match_type == RTE_SWX_TABLE_MATCH_LPM) { + *lpm = 1; + + *lpm_prefix_length_max = mf->n_bits; + + status = large_mask_to_prefix(&entry->key_mask[offset], + mf->n_bits / 8, + lpm_prefix_length); + if (status) + return status; + } + + /* + * Value. + */ +value: + /* Parse. */ + status = hex_string_parse(mf_val, &entry->key[offset], mf->n_bits / 8); + if (status) + return -EINVAL; + + return 0; +} + +static int +table_entry_large_action_argument_read(struct action *action, + struct rte_swx_table_entry *entry, + uint32_t arg_id, + uint32_t arg_offset, + char *arg_val) +{ + struct rte_swx_ctl_action_arg_info *arg = &action->args[arg_id]; + int status; + + status = hex_string_parse(arg_val, &entry->action_data[arg_offset], arg->n_bits / 8); + if (status) + return -EINVAL; + + return 0; +} + static int token_is_comment(const char *token) { @@ -2778,62 +3042,35 @@ rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl, for (i = 0; i < table->info.n_match_fields; i++) { struct rte_swx_ctl_table_match_field_info *mf = &table->mf[i]; char *mf_val = tokens[1 + i], *mf_mask = NULL; - uint64_t val, mask = UINT64_MAX; - uint32_t offset = (mf->offset - table->mf_first->offset) / 8; + int status; - /* - * Mask. - */ mf_mask = strchr(mf_val, '/'); if (mf_mask) { *mf_mask = 0; mf_mask++; - - /* Parse. */ - mask = strtoull(mf_mask, &mf_mask, 0); - if (mf_mask[0]) - goto error; - - /* LPM. */ - if (mf->match_type == RTE_SWX_TABLE_MATCH_LPM) { - int status; - - lpm = 1; - - lpm_prefix_length_max = mf->n_bits; - - status = mask_to_prefix(mask, mf->n_bits, &lpm_prefix_length); - if (status) - goto error; - } - - /* Endianness conversion. */ - if (mf->is_header) - mask = field_hton(mask, mf->n_bits); } - /* Copy to entry. */ - if (entry->key_mask) - memcpy(&entry->key_mask[offset], - (uint8_t *)&mask, - mf->n_bits / 8); - - /* - * Value. - */ - /* Parse. */ - val = strtoull(mf_val, &mf_val, 0); - if (mf_val[0]) + if (mf->n_bits <= 64) + status = table_entry_match_field_read(table, + entry, + i, + mf_val, + mf_mask, + &lpm, + &lpm_prefix_length_max, + &lpm_prefix_length); + else + status = table_entry_large_match_field_read(table, + entry, + i, + mf_val, + mf_mask, + &lpm, + &lpm_prefix_length_max, + &lpm_prefix_length); + if (status) goto error; - /* Endianness conversion. */ - if (mf->is_header) - val = field_hton(val, mf->n_bits); - - /* Copy to entry. */ - memcpy(&entry->key[offset], - (uint8_t *)&val, - mf->n_bits / 8); } tokens += 1 + table->info.n_match_fields; @@ -2889,7 +3126,7 @@ rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl, for (i = 0; i < action->info.n_args; i++) { struct rte_swx_ctl_action_arg_info *arg = &action->args[i]; char *arg_name, *arg_val; - uint64_t val; + int status; arg_name = tokens[2 + i * 2]; arg_val = tokens[2 + i * 2 + 1]; @@ -2897,19 +3134,21 @@ rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl, if (strcmp(arg_name, arg->name)) goto error; - val = strtoull(arg_val, &arg_val, 0); - if (arg_val[0]) + if (arg->n_bits <= 64) + status = table_entry_action_argument_read(action, + entry, + i, + arg_offset, + arg_val); + else + status = table_entry_large_action_argument_read(action, + entry, + i, + arg_offset, + arg_val); + if (status) goto error; - /* Endianness conversion. */ - if (arg->is_network_byte_order) - val = field_hton(val, arg->n_bits); - - /* Copy to entry. */ - memcpy(&entry->action_data[arg_offset], - (uint8_t *)&val, - arg->n_bits / 8); - arg_offset += arg->n_bits / 8; } From patchwork Fri Aug 12 09:54:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Dumitrescu X-Patchwork-Id: 114886 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 3817FA0543; Fri, 12 Aug 2022 11:55:06 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1CE4B42C15; Fri, 12 Aug 2022 11:54:53 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mails.dpdk.org (Postfix) with ESMTP id DABC7410E7 for ; Fri, 12 Aug 2022 11:54:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660298091; x=1691834091; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cE8rODZCkPv1vlpC/wQGWIJa6ugz/lPWmiZo79mP12c=; b=eUubNfNsIbeXmUIQvFFTj0B/DM3lAsLPwdb+r/Ajeux5ucxn3NNeFNFj u6adJYjtIk3K9ssO10Blmr22Xqu0YsZOfScXet6OUI8oTCE5+rszaADBj 9RQKybIGMw2csxRxZBj4DZicHjvQs+dHkgkYX9fPYQJrLNB3EulBkpkQr SGNPj24agfem525hlv0eSfu0C66QnEA8il1188pRXgAbzXTv0lxi3SKUq 2u3TZhoKi8OYjyb8YJRtP/mft5e7D2bGc0jYmgwYS5S6E7KsH/dbgEc1v 2rQX/UlnmwtCI4QqFyCCKACYZTEiGd4w6kVELUhguuju951Y29ClCEYMx A==; X-IronPort-AV: E=McAfee;i="6400,9594,10436"; a="289135020" X-IronPort-AV: E=Sophos;i="5.93,231,1654585200"; d="scan'208";a="289135020" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 02:54:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,231,1654585200"; d="scan'208";a="634589094" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com.) ([10.237.223.157]) by orsmga008.jf.intel.com with ESMTP; 12 Aug 2022 02:54:49 -0700 From: Cristian Dumitrescu To: dev@dpdk.org Cc: Harshad Suresh Narayane Subject: [PATCH 3/4] pipeline: support large default action arguments Date: Fri, 12 Aug 2022 09:54:44 +0000 Message-Id: <20220812095445.1253138-4-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220812095445.1253138-1-cristian.dumitrescu@intel.com> References: <20220812095445.1253138-1-cristian.dumitrescu@intel.com> 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 Support structure fields bigger than 64 bits as default action arguments. Signed-off-by: Cristian Dumitrescu Signed-off-by: Harshad Suresh Narayane --- lib/pipeline/rte_swx_pipeline.c | 89 +++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 11 deletions(-) diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c index 15c840b352..48b9df0fef 100644 --- a/lib/pipeline/rte_swx_pipeline.c +++ b/lib/pipeline/rte_swx_pipeline.c @@ -7576,6 +7576,65 @@ action_arg_src_mov_count(struct action *a, return n_users; } +static int +char_to_hex(char c, uint8_t *val) +{ + if (c >= '0' && c <= '9') { + *val = c - '0'; + return 0; + } + + if (c >= 'A' && c <= 'F') { + *val = c - 'A' + 10; + return 0; + } + + if (c >= 'a' && c <= 'f') { + *val = c - 'a' + 10; + return 0; + } + + return -EINVAL; +} + +static int +hex_string_parse(char *src, uint8_t *dst, uint32_t n_dst_bytes) +{ + uint32_t i; + + /* Check input arguments. */ + if (!src || !src[0] || !dst || !n_dst_bytes) + return -EINVAL; + + /* Skip any leading "0x" or "0X" in the src string. */ + if ((src[0] == '0') && (src[1] == 'x' || src[1] == 'X')) + src += 2; + + /* Convert each group of two hex characters in the src string to one byte in dst array. */ + for (i = 0; i < n_dst_bytes; i++) { + uint8_t a, b; + int status; + + status = char_to_hex(*src, &a); + if (status) + return status; + src++; + + status = char_to_hex(*src, &b); + if (status) + return status; + src++; + + dst[i] = a * 16 + b; + } + + /* Check for the end of the src string. */ + if (*src) + return -EINVAL; + + return 0; +} + #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN #define field_ntoh(val, n_bits) (ntoh64((val) << (64 - n_bits))) #define field_hton(val, n_bits) (hton64((val) << (64 - n_bits))) @@ -7634,25 +7693,33 @@ action_args_parse(struct action *a, const char *args, uint8_t *data) struct field *f = &a->st->fields[i]; char *arg_name = tokens[i * 2]; char *arg_val = tokens[i * 2 + 1]; - uint64_t val; if (strcmp(arg_name, f->name)) { status = -EINVAL; goto error; } - val = strtoull(arg_val, &arg_val, 0); - if (arg_val[0]) { - status = -EINVAL; - goto error; - } + if (f->n_bits <= 64) { + uint64_t val; - /* Endianness conversion. */ - if (a->args_endianness[i]) - val = field_hton(val, f->n_bits); + val = strtoull(arg_val, &arg_val, 0); + if (arg_val[0]) { + status = -EINVAL; + goto error; + } + + /* Endianness conversion. */ + if (a->args_endianness[i]) + val = field_hton(val, f->n_bits); + + /* Copy to entry. */ + memcpy(&data[offset], (uint8_t *)&val, f->n_bits / 8); + } else { + status = hex_string_parse(arg_val, &data[offset], f->n_bits / 8); + if (status) + goto error; + } - /* Copy to entry. */ - memcpy(&data[offset], (uint8_t *)&val, f->n_bits / 8); offset += f->n_bits / 8; } From patchwork Fri Aug 12 09:54:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Dumitrescu X-Patchwork-Id: 114887 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 F2ACAA0543; Fri, 12 Aug 2022 11:55:10 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E126842C0D; Fri, 12 Aug 2022 11:54:53 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mails.dpdk.org (Postfix) with ESMTP id 25AAE42C14 for ; Fri, 12 Aug 2022 11:54:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660298092; x=1691834092; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=11zWIaxIq2VxwFcumCoqO5OeyLpXxUZxPHyyG9Uya2Q=; b=fTjCIrtj/gLLCvZp8d1Tz02TXhZgs9HjoXkUAcdPI6ytoThP4Z6YjStz IlflzGoD6gu67h3ZhnrYUHFA3p7koz7+wOvYsQHa0uU01VjyW83vxMtAi JI3iQZfFOr+4GhbhAKtM0uUM0Ws1/nW7WvRzJwvsX8hAxPPog1/0d2UiX W3dIHwizJ43K6vcvaGJgOVZZ3Coh3sBmb71BhPp3sXOtkjp/zo2rskO5D qzkmgkZ1mc8SWgeBbgrWMoWUdDXzCdvIpkp8HmkVoN1QuN4Q5S/Td11hs LLX8qiaGgAqqd3rMZjzO1cy6lg0gjAYcxWg1r+NSXPx3pXe2MNkKPIfHz g==; X-IronPort-AV: E=McAfee;i="6400,9594,10436"; a="289135021" X-IronPort-AV: E=Sophos;i="5.93,231,1654585200"; d="scan'208";a="289135021" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 02:54:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,231,1654585200"; d="scan'208";a="634589102" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com.) ([10.237.223.157]) by orsmga008.jf.intel.com with ESMTP; 12 Aug 2022 02:54:50 -0700 From: Cristian Dumitrescu To: dev@dpdk.org Cc: Harshad Suresh Narayane Subject: [PATCH 4/4] pipeline: add instruction support for moving large structure fields Date: Fri, 12 Aug 2022 09:54:45 +0000 Message-Id: <20220812095445.1253138-5-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220812095445.1253138-1-cristian.dumitrescu@intel.com> References: <20220812095445.1253138-1-cristian.dumitrescu@intel.com> 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 Add support to the move instruction for operands bigger than 64 bits. Signed-off-by: Cristian Dumitrescu Signed-off-by: Harshad Suresh Narayane --- lib/pipeline/rte_swx_pipeline.c | 71 +++++++++++++++++---- lib/pipeline/rte_swx_pipeline_internal.h | 78 ++++++++++++++++++++++-- 2 files changed, 131 insertions(+), 18 deletions(-) diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c index 48b9df0fef..2cac4caa95 100644 --- a/lib/pipeline/rte_swx_pipeline.c +++ b/lib/pipeline/rte_swx_pipeline.c @@ -2969,20 +2969,28 @@ instr_mov_translate(struct rte_swx_pipeline *p, fdst = struct_field_parse(p, NULL, dst, &dst_struct_id); CHECK(fdst, EINVAL); - CHECK(!fdst->var_size && (fdst->n_bits <= 64), EINVAL); + CHECK(!fdst->var_size, EINVAL); - /* MOV, MOV_MH, MOV_HM or MOV_HH. */ + /* MOV, MOV_MH, MOV_HM, MOV_HH, MOV16, MOVDMA. */ fsrc = struct_field_parse(p, action, src, &src_struct_id); if (fsrc) { - CHECK(!fsrc->var_size && (fsrc->n_bits <= 64), EINVAL); + CHECK(!fsrc->var_size, EINVAL); + + if (fdst->n_bits <= 64 && fsrc->n_bits <= 64) { + instr->type = INSTR_MOV; + if (dst[0] != 'h' && src[0] == 'h') + instr->type = INSTR_MOV_MH; + if (dst[0] == 'h' && src[0] != 'h') + instr->type = INSTR_MOV_HM; + if (dst[0] == 'h' && src[0] == 'h') + instr->type = INSTR_MOV_HH; + } else { + CHECK(fdst->n_bits == fsrc->n_bits, EINVAL); - instr->type = INSTR_MOV; - if (dst[0] != 'h' && src[0] == 'h') - instr->type = INSTR_MOV_MH; - if (dst[0] == 'h' && src[0] != 'h') - instr->type = INSTR_MOV_HM; - if (dst[0] == 'h' && src[0] == 'h') - instr->type = INSTR_MOV_HH; + instr->type = INSTR_MOV_DMA; + if (fdst->n_bits == 128) + instr->type = INSTR_MOV_128; + } instr->mov.dst.struct_id = (uint8_t)dst_struct_id; instr->mov.dst.n_bits = fdst->n_bits; @@ -2994,6 +3002,7 @@ instr_mov_translate(struct rte_swx_pipeline *p, } /* MOV_I. */ + CHECK(fdst->n_bits <= 64, EINVAL); src_val = strtoull(src, &src, 0); CHECK(!src[0], EINVAL); @@ -3056,6 +3065,30 @@ instr_mov_hh_exec(struct rte_swx_pipeline *p) thread_ip_inc(p); } +static inline void +instr_mov_dma_exec(struct rte_swx_pipeline *p) +{ + struct thread *t = &p->threads[p->thread_id]; + struct instruction *ip = t->ip; + + __instr_mov_dma_exec(p, t, ip); + + /* Thread. */ + thread_ip_inc(p); +} + +static inline void +instr_mov_128_exec(struct rte_swx_pipeline *p) +{ + struct thread *t = &p->threads[p->thread_id]; + struct instruction *ip = t->ip; + + __instr_mov_128_exec(p, t, ip); + + /* Thread. */ + thread_ip_inc(p); +} + static inline void instr_mov_i_exec(struct rte_swx_pipeline *p) { @@ -6781,12 +6814,14 @@ instr_pattern_validate_mov_all_search(struct rte_swx_pipeline *p, if (!a || !a->st) return 0; - /* First instruction: HDR_VALIDATE. Second instruction: MOV_HM. */ + /* First instruction: HDR_VALIDATE. Second instruction: MOV_HM, MOV_DMA or MOV_128. */ if (data[0].invalid || (instr[0].type != INSTR_HDR_VALIDATE) || (n_instr < 2) || data[1].invalid || - (instr[1].type != INSTR_MOV_HM) || + (instr[1].type != INSTR_MOV_HM && + instr[1].type != INSTR_MOV_DMA && + instr[1].type != INSTR_MOV_128) || instr[1].mov.src.struct_id) return 0; @@ -6807,7 +6842,9 @@ instr_pattern_validate_mov_all_search(struct rte_swx_pipeline *p, for (i = 0; i < h->st->n_fields; i++) if (data[1 + i].invalid || data[1 + i].n_users || - (instr[1 + i].type != INSTR_MOV_HM) || + (instr[1 + i].type != INSTR_MOV_HM && + instr[1 + i].type != INSTR_MOV_DMA && + instr[1 + i].type != INSTR_MOV_128) || (instr[1 + i].mov.dst.struct_id != h->struct_id) || (instr[1 + i].mov.dst.offset != h->st->fields[i].offset / 8) || (instr[1 + i].mov.dst.n_bits != h->st->fields[i].n_bits) || @@ -7147,6 +7184,8 @@ static instr_exec_t instruction_table[] = { [INSTR_MOV_MH] = instr_mov_mh_exec, [INSTR_MOV_HM] = instr_mov_hm_exec, [INSTR_MOV_HH] = instr_mov_hh_exec, + [INSTR_MOV_DMA] = instr_mov_dma_exec, + [INSTR_MOV_128] = instr_mov_128_exec, [INSTR_MOV_I] = instr_mov_i_exec, [INSTR_DMA_HT] = instr_dma_ht_exec, @@ -10950,6 +10989,8 @@ instr_type_to_name(struct instruction *instr) case INSTR_MOV_MH: return "INSTR_MOV_MH"; case INSTR_MOV_HM: return "INSTR_MOV_HM"; 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_I: return "INSTR_MOV_I"; case INSTR_DMA_HT: return "INSTR_DMA_HT"; @@ -11938,6 +11979,8 @@ static instruction_export_t export_table[] = { [INSTR_MOV_MH] = instr_mov_export, [INSTR_MOV_HM] = instr_mov_export, [INSTR_MOV_HH] = instr_mov_export, + [INSTR_MOV_DMA] = instr_mov_export, + [INSTR_MOV_128] = instr_mov_export, [INSTR_MOV_I] = instr_mov_export, [INSTR_DMA_HT] = instr_dma_ht_export, @@ -12162,6 +12205,8 @@ instr_type_to_func(struct instruction *instr) case INSTR_MOV_MH: return "__instr_mov_mh_exec"; case INSTR_MOV_HM: return "__instr_mov_hm_exec"; 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_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 588cad62b5..6d65b635c6 100644 --- a/lib/pipeline/rte_swx_pipeline_internal.h +++ b/lib/pipeline/rte_swx_pipeline_internal.h @@ -307,11 +307,13 @@ enum instruction_type { * dst = src * dst = HMEF, src = HMEFTI */ - INSTR_MOV, /* dst = MEF, src = MEFT */ - INSTR_MOV_MH, /* dst = MEF, src = H */ - INSTR_MOV_HM, /* dst = H, src = MEFT */ - INSTR_MOV_HH, /* dst = H, src = H */ - INSTR_MOV_I, /* dst = HMEF, src = I */ + INSTR_MOV, /* dst = MEF, src = MEFT; size(dst) <= 64 bits, size(src) <= 64 bits. */ + 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_I, /* dst = HMEF, src = I; size(dst) <= 64 bits. */ /* dma h.header t.field * memcpy(h.header, t.field, sizeof(h.header)) @@ -2485,6 +2487,72 @@ __instr_mov_hh_exec(struct rte_swx_pipeline *p __rte_unused, MOV_HH(t, ip); } +static inline void +__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 *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; + + 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; + + for (i = 0; i < n >> 2; i++) + *dst32_ptr++ = *src32_ptr++; + + /* 2-byte transfers. */ + n &= 3; + dst16_ptr = (uint16_t *)dst32_ptr; + src16_ptr = (uint16_t *)src32_ptr; + + 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; +} + +static inline void +__instr_mov_128_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]; + + uint8_t *src_struct = t->structs[ip->mov.src.struct_id]; + uint64_t *src64_ptr = (uint64_t *)&src_struct[ip->mov.src.offset]; + + TRACE("[Thread %2u] mov (128)\n", p->thread_id); + + dst64_ptr[0] = src64_ptr[0]; + dst64_ptr[1] = src64_ptr[1]; +} + static inline void __instr_mov_i_exec(struct rte_swx_pipeline *p __rte_unused, struct thread *t,