From patchwork Tue Jul 27 17:43:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Dumitrescu X-Patchwork-Id: 96338 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 AC325A0C55; Tue, 27 Jul 2021 19:44:10 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9ED0A41124; Tue, 27 Jul 2021 19:43:54 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mails.dpdk.org (Postfix) with ESMTP id C67F2410F2 for ; Tue, 27 Jul 2021 19:43:49 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10058"; a="199677799" X-IronPort-AV: E=Sophos;i="5.84,274,1620716400"; d="scan'208";a="199677799" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jul 2021 10:43:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.84,274,1620716400"; d="scan'208";a="517040399" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com) ([10.237.223.107]) by fmsmga002.fm.intel.com with ESMTP; 27 Jul 2021 10:43:42 -0700 From: Cristian Dumitrescu To: dev@dpdk.org Date: Tue, 27 Jul 2021 18:43:38 +0100 Message-Id: <20210727174340.2125-3-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210727174340.2125-1-cristian.dumitrescu@intel.com> References: <20210727163609.97769-1-cristian.dumitrescu@intel.com> <20210727174340.2125-1-cristian.dumitrescu@intel.com> Subject: [dpdk-dev] [PATCH V2 3/5] pipeline: add variable size headers extract instruction 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" Added a mechanism to extract variable size headers through a special flavor of the extract instruction. The length of the last struct field which has variable size is passed as argument to the instruction. Signed-off-by: Cristian Dumitrescu --- lib/pipeline/rte_swx_pipeline.c | 75 ++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c index 1a8259ffee..d87fe77d91 100644 --- a/lib/pipeline/rte_swx_pipeline.c +++ b/lib/pipeline/rte_swx_pipeline.c @@ -303,6 +303,9 @@ enum instruction_type { INSTR_HDR_EXTRACT7, INSTR_HDR_EXTRACT8, + /* extract h.header m.last_field_size */ + INSTR_HDR_EXTRACT_M, + /* emit h.header */ INSTR_HDR_EMIT, INSTR_HDR_EMIT_TX, @@ -3088,16 +3091,35 @@ instr_hdr_extract_translate(struct rte_swx_pipeline *p, struct header *h; CHECK(!action, EINVAL); - CHECK(n_tokens == 2, EINVAL); + CHECK((n_tokens == 2) || (n_tokens == 3), EINVAL); h = header_parse(p, tokens[1]); CHECK(h, EINVAL); - CHECK(!h->st->var_size, EINVAL); - instr->type = INSTR_HDR_EXTRACT; - instr->io.hdr.header_id[0] = h->id; - instr->io.hdr.struct_id[0] = h->struct_id; - instr->io.hdr.n_bytes[0] = h->st->n_bits / 8; + if (n_tokens == 2) { + CHECK(!h->st->var_size, EINVAL); + + instr->type = INSTR_HDR_EXTRACT; + instr->io.hdr.header_id[0] = h->id; + instr->io.hdr.struct_id[0] = h->struct_id; + instr->io.hdr.n_bytes[0] = h->st->n_bits / 8; + } else { + struct field *mf; + + CHECK(h->st->var_size, EINVAL); + + mf = metadata_field_parse(p, tokens[2]); + CHECK(mf, EINVAL); + CHECK(!mf->var_size, EINVAL); + + instr->type = INSTR_HDR_EXTRACT_M; + instr->io.io.offset = mf->offset / 8; + instr->io.io.n_bits = mf->n_bits; + instr->io.hdr.header_id[0] = h->id; + instr->io.hdr.struct_id[0] = h->struct_id; + instr->io.hdr.n_bytes[0] = h->st->n_bits_min / 8; + } + return 0; } @@ -3237,6 +3259,46 @@ instr_hdr_extract8_exec(struct rte_swx_pipeline *p) thread_ip_inc(p); } +static inline void +instr_hdr_extract_m_exec(struct rte_swx_pipeline *p) +{ + struct thread *t = &p->threads[p->thread_id]; + struct instruction *ip = t->ip; + + uint64_t valid_headers = t->valid_headers; + uint8_t *ptr = t->ptr; + uint32_t offset = t->pkt.offset; + uint32_t length = t->pkt.length; + + uint32_t n_bytes_last = METADATA_READ(t, ip->io.io.offset, ip->io.io.n_bits); + uint32_t header_id = ip->io.hdr.header_id[0]; + uint32_t struct_id = ip->io.hdr.struct_id[0]; + uint32_t n_bytes = ip->io.hdr.n_bytes[0]; + + struct header_runtime *h = &t->headers[header_id]; + + TRACE("[Thread %2u]: extract header %u (%u + %u bytes)\n", + p->thread_id, + header_id, + n_bytes, + n_bytes_last); + + n_bytes += n_bytes_last; + + /* Headers. */ + t->structs[struct_id] = ptr; + t->valid_headers = MASK64_BIT_SET(valid_headers, header_id); + h->n_bytes = n_bytes; + + /* Packet. */ + t->pkt.offset = offset + n_bytes; + t->pkt.length = length - n_bytes; + t->ptr = ptr + n_bytes; + + /* Thread. */ + thread_ip_inc(p); +} + /* * emit. */ @@ -8842,6 +8904,7 @@ static instr_exec_t instruction_table[] = { [INSTR_HDR_EXTRACT6] = instr_hdr_extract6_exec, [INSTR_HDR_EXTRACT7] = instr_hdr_extract7_exec, [INSTR_HDR_EXTRACT8] = instr_hdr_extract8_exec, + [INSTR_HDR_EXTRACT_M] = instr_hdr_extract_m_exec, [INSTR_HDR_EMIT] = instr_hdr_emit_exec, [INSTR_HDR_EMIT_TX] = instr_hdr_emit_tx_exec,