[dpdk-dev] [PATCH v1] net/iavf: support flex desc metadata extraction

Wang, Haiyue haiyue.wang at intel.com
Thu Sep 17 05:00:10 CEST 2020


Hi Jeff,

> -----Original Message-----
> From: dev <dev-bounces at dpdk.org> On Behalf Of Jeff Guo
> Sent: Wednesday, September 9, 2020 10:54
> To: Wu, Jingjing <jingjing.wu at intel.com>; Zhang, Qi Z <qi.z.zhang at intel.com>; Xing, Beilei
> <beilei.xing at intel.com>
> Cc: dev at dpdk.org; Guo, Jia <jia.guo at intel.com>
> Subject: [dpdk-dev] [PATCH v1] net/iavf: support flex desc metadata extraction
> 
> Enable metadata extraction for flexible descriptors in AVF, that would
> allow network function directly get metadata without additional parsing
> which would reduce the CPU cost for VFs. The enabling metadata
> extractions involve the metadata of VLAN/IPv4/IPv6/IPv6-FLOW/TCP/OVS/
> MPLS flexible descriptors, and the VF could negotiate the capability of
> the flexible descriptor with PF and correspondingly configure the
> specific offload at receiving queues.
> 
> Signed-off-by: Jeff Guo <jia.guo at intel.com>
> ---
>  doc/guides/rel_notes/release_20_11.rst |   6 +
>  drivers/net/iavf/Makefile              |   1 +
>  drivers/net/iavf/iavf.h                |  25 +-
>  drivers/net/iavf/iavf_ethdev.c         | 398 +++++++++++++++++++++++++
>  drivers/net/iavf/iavf_rxtx.c           | 230 +++++++++++++-
>  drivers/net/iavf/iavf_rxtx.h           |  17 ++
>  drivers/net/iavf/iavf_vchnl.c          |  22 +-
>  drivers/net/iavf/meson.build           |   2 +
>  drivers/net/iavf/rte_pmd_iavf.h        | 258 ++++++++++++++++
>  9 files changed, 937 insertions(+), 22 deletions(-)
>  create mode 100644 drivers/net/iavf/rte_pmd_iavf.h
> 


>  -------------
> diff --git a/drivers/net/iavf/Makefile b/drivers/net/iavf/Makefile
> index 792cbb7f7..05fcbdc47 100644
> --- a/drivers/net/iavf/Makefile
> +++ b/drivers/net/iavf/Makefile

meson build only now, remove the Makefile


> diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
> index 05a7dd898..fa71b4a80 100644
> --- a/drivers/net/iavf/iavf_rxtx.c
> +++ b/drivers/net/iavf/iavf_rxtx.c
> @@ -26,6 +26,74 @@


> +
> +/* Translate the rx flex descriptor status to pkt flags */
> +static inline void
> +iavf_rxd_to_pkt_fields(struct rte_mbuf *mb,
> +		       volatile union iavf_rx_flex_desc *rxdp, uint8_t rxdid)
> +{
> +	if (rxdid == IAVF_RXDID_COMMS_GENERIC ||
> +	    rxdid == IAVF_RXDID_COMMS_AUX_VLAN ||
> +	    rxdid == IAVF_RXDID_COMMS_AUX_IPV4 ||
> +	    rxdid == IAVF_RXDID_COMMS_AUX_IPV6 ||
> +	    rxdid == IAVF_RXDID_COMMS_AUX_IPV6_FLOW ||
> +	    rxdid == IAVF_RXDID_COMMS_AUX_TCP ||
> +	    rxdid == IAVF_RXDID_COMMS_AUX_IP_OFFSET)
> +		iavf_rxd_to_pkt_fields_aux(mb, rxdp);
> +	else if (rxdid == IAVF_RXDID_COMMS_OVS_1)
> +		iavf_rxd_to_pkt_fields_ovs(mb, rxdp);
> +}

We can optimize this by calling function handle:

  struct iavf_rx_queue *rxq->rxd_to_pkt_fields(mb, rxdp)

and when setup the queue, assign the right handle according to the rxdid.
  if (rxdid == IAVF_RXDID_COMMS_GENERIC ...)
	rxq->rxd_to_pkt_fields = iavf_rxd_to_pkt_fields_aux;
  else if (OVS_1)
	rxq->rxd_to_pkt_fields = iavf_rxd_to_pkt_fields_ovs;


> --- a/drivers/net/iavf/meson.build
> +++ b/drivers/net/iavf/meson.build
> @@ -35,3 +35,5 @@ if arch_subdir == 'x86'
>  		objs += iavf_avx2_lib.extract_objects('iavf_rxtx_vec_avx2.c')
>  	endif
>  endif
> +
> +install_headers('rte_pmd_iavf.h')
> diff --git a/drivers/net/iavf/rte_pmd_iavf.h b/drivers/net/iavf/rte_pmd_iavf.h
> new file mode 100644
> index 000000000..858201bd7
> --- /dev/null
> +++ b/drivers/net/iavf/rte_pmd_iavf.h
> @@ -0,0 +1,258 @@
> +/* SPDX-Liavfnse-Identifier: BSD-3-Clause
> + * Copyright(c) 2019 Intel Corporation
> + */
> +
> +#ifndef _RTE_PMD_IAVF_H_
> +#define _RTE_PMD_IAVF_H_
> +
> +/**
> + * @file rte_pmd_iavf.h
> + *
> + * iavf PMD specific functions.
> + *
> + * @b EXPERIMENTAL: this API may change, or be removed, without prior notiavf
> + *
> + */
> +
> +#include <stdio.h>
> +#include <rte_mbuf.h>
> +#include <rte_mbuf_dyn.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * The supported network flexible descriptor's extraction metadata format.
> + */
> +union rte_net_iavf_flex_desc_metadata {
> +	uint32_t metadata;
> +
> +	struct {
> +		uint16_t data0;
> +		uint16_t data1;
> +	} raw;
> +
> +	struct {
> +		uint16_t stag_vid:12,
> +			 stag_dei:1,
> +			 stag_pcp:3;
> +		uint16_t ctag_vid:12,
> +			 ctag_dei:1,
> +			 ctag_pcp:3;
> +	} vlan;
> +
> +	struct {
> +		uint16_t protocol:8,
> +			 ttl:8;
> +		uint16_t tos:8,
> +			 ihl:4,
> +			 version:4;
> +	} ipv4;
> +
> +	struct {
> +		uint16_t hoplimit:8,
> +			 nexthdr:8;
> +		uint16_t flowhi4:4,
> +			 tc:8,
> +			 version:4;
> +	} ipv6;
> +
> +	struct {
> +		uint16_t flowlo16;
> +		uint16_t flowhi4:4,
> +			 tc:8,
> +			 version:4;
> +	} ipv6_flow;
> +
> +	struct {
> +		uint16_t fin:1,
> +			 syn:1,
> +			 rst:1,
> +			 psh:1,
> +			 ack:1,
> +			 urg:1,
> +			 ece:1,
> +			 cwr:1,
> +			 res1:4,
> +			 doff:4;
> +		uint16_t rsvd;
> +	} tcp;
> +
> +	uint32_t ip_ofs;
> +};
> +
> +/* Offset of mbuf dynamic field for flexible descriptor's extraction data */
> +extern int rte_net_iavf_dynfield_flex_desc_metadata_offs;
> +
> +/* Mask of mbuf dynamic flags for flexible descriptor's extraction type */
> +extern uint64_t rte_net_iavf_dynflag_flex_desc_vlan_mask;
> +extern uint64_t rte_net_iavf_dynflag_flex_desc_ipv4_mask;
> +extern uint64_t rte_net_iavf_dynflag_flex_desc_ipv6_mask;
> +extern uint64_t rte_net_iavf_dynflag_flex_desc_ipv6_flow_mask;
> +extern uint64_t rte_net_iavf_dynflag_flex_desc_tcp_mask;
> +extern uint64_t rte_net_iavf_dynflag_flex_desc_ovs_mask;
> +extern uint64_t rte_net_iavf_dynflag_flex_desc_ip_offset_mask;
> +
> +/**
> + * The mbuf dynamic field pointer for flexible descriptor's extraction metadata.
> + */
> +#define RTE_NET_IAVF_DYNF_FLEX_DESC_METADATA(m) \
> +	RTE_MBUF_DYNFIELD((m), \
> +			  rte_net_iavf_dynfield_flex_desc_metadata_offs, \
> +			  uint32_t *)
> +
> +/**
> + * The mbuf dynamic flag for VLAN protocol extraction metadata, it is valid
> + * when dev_args 'flex_desc' has 'vlan' specified.
> + */
> +#define RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_VLAN \
> +	(rte_net_iavf_dynflag_flex_desc_vlan_mask)
> +
> +/**
> + * The mbuf dynamic flag for IPv4 protocol extraction metadata, it is valid
> + * when dev_args 'flex_desc' has 'ipv4' specified.
> + */
> +#define RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_IPV4 \
> +	(rte_net_iavf_dynflag_flex_desc_ipv4_mask)
> +
> +/**
> + * The mbuf dynamic flag for IPv6 protocol extraction metadata, it is valid
> + * when dev_args 'flex_desc' has 'ipv6' specified.
> + */
> +#define RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_IPV6 \
> +	(rte_net_iavf_dynflag_flex_desc_ipv6_mask)
> +
> +/**
> + * The mbuf dynamic flag for IPv6 with flow protocol extraction metadata, it is
> + * valid when dev_args 'flex_desc' has 'ipv6_flow' specified.
> + */
> +#define RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_IPV6_FLOW \
> +	(rte_net_iavf_dynflag_flex_desc_ipv6_flow_mask)
> +
> +/**
> + * The mbuf dynamic flag for TCP protocol extraction metadata, it is valid
> + * when dev_args 'flex_desc' has 'tcp' specified.
> + */
> +#define RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_TCP \
> +	(rte_net_iavf_dynflag_flex_desc_tcp_mask)
> +
> +/**
> + * The mbuf dynamic flag for the extraction metadata of OVS flexible
> + * descriptor, it is valid when dev_args 'flex_desc' has 'ovs' specified.
> + */
> +#define RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_OVS \
> +	(rte_net_iavf_dynflag_flex_desc_ovs_mask)
> +
> +/**
> + * The mbuf dynamic flag for IP_OFFSET extraction metadata, it is valid
> + * when dev_args 'flex_desc' has 'ip_offset' specified.
> + */
> +#define RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_IP_OFFSET \
> +	(rte_net_iavf_dynflag_flex_desc_ip_offset_mask)
> +
> +/**
> + * Check if mbuf dynamic field for flexible descriptor's extraction metadata
> + * is registered.
> + *
> + * @return
> + *   True if registered, false otherwise.
> + */
> +__rte_experimental
> +static __rte_always_inline int
> +rte_net_iavf_dynf_flex_desc_metadata_avail(void)
> +{
> +	return rte_net_iavf_dynfield_flex_desc_metadata_offs != -1;
> +}
> +
> +/**
> + * Get the mbuf dynamic field for flexible descriptor's extraction metadata.
> + *
> + * @param m
> + *    The pointer to the mbuf.
> + * @return
> + *   The saved protocol extraction metadata.
> + */
> +__rte_experimental
> +static __rte_always_inline uint32_t
> +rte_net_iavf_dynf_flex_desc_metadata_get(struct rte_mbuf *m)
> +{
> +	return *RTE_NET_IAVF_DYNF_FLEX_DESC_METADATA(m);
> +}
> +
> +/**
> + * Dump the mbuf dynamic field for flexible descriptor's extraction metadata.
> + *
> + * @param m
> + *    The pointer to the mbuf.
> + */
> +__rte_experimental
> +static inline void
> +rte_net_iavf_dump_flex_desc_metadata(struct rte_mbuf *m)
> +{
> +	union rte_net_iavf_flex_desc_metadata data;
> +
> +	if (!rte_net_iavf_dynf_flex_desc_metadata_avail())
> +		return;
> +
> +	data.metadata = rte_net_iavf_dynf_flex_desc_metadata_get(m);
> +
> +	if (m->ol_flags & RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_VLAN)
> +		printf(" - Flexible descriptor's Metadata: [0x%04x:0x%04x],"
> +		       "vlan,stag=%u:%u:%u,ctag=%u:%u:%u",
> +		       data.raw.data0, data.raw.data1,
> +		       data.vlan.stag_pcp,
> +		       data.vlan.stag_dei,
> +		       data.vlan.stag_vid,
> +		       data.vlan.ctag_pcp,
> +		       data.vlan.ctag_dei,
> +		       data.vlan.ctag_vid);
> +	else if (m->ol_flags & RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_IPV4)
> +		printf(" - Flexible descriptor's Metadata: [0x%04x:0x%04x],"
> +		       "ipv4,ver=%u,hdrlen=%u,tos=%u,ttl=%u,proto=%u",
> +		       data.raw.data0, data.raw.data1,
> +		       data.ipv4.version,
> +		       data.ipv4.ihl,
> +		       data.ipv4.tos,
> +		       data.ipv4.ttl,
> +		       data.ipv4.protocol);
> +	else if (m->ol_flags & RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_IPV6)
> +		printf(" - Flexible descriptor's Metadata: [0x%04x:0x%04x],"
> +		       "ipv6,ver=%u,tc=%u,flow_hi4=0x%x,nexthdr=%u,hoplimit=%u",
> +		       data.raw.data0, data.raw.data1,
> +		       data.ipv6.version,
> +		       data.ipv6.tc,
> +		       data.ipv6.flowhi4,
> +		       data.ipv6.nexthdr,
> +		       data.ipv6.hoplimit);
> +	else if (m->ol_flags & RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_IPV6_FLOW)
> +		printf(" - Flexible descriptor's Metadata: [0x%04x:0x%04x],"
> +		       "ipv6_flow,ver=%u,tc=%u,flow=0x%x%04x",
> +		       data.raw.data0, data.raw.data1,
> +		       data.ipv6_flow.version,
> +		       data.ipv6_flow.tc,
> +		       data.ipv6_flow.flowhi4,
> +		       data.ipv6_flow.flowlo16);
> +	else if (m->ol_flags & RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_TCP)
> +		printf(" - Flexible descriptor's Metadata: [0x%04x:0x%04x],"
> +		       "tcp,doff=%u,flags=%s%s%s%s%s%s%s%s",
> +		       data.raw.data0, data.raw.data1,
> +		       data.tcp.doff,
> +		       data.tcp.cwr ? "C" : "",
> +		       data.tcp.ece ? "E" : "",
> +		       data.tcp.urg ? "U" : "",
> +		       data.tcp.ack ? "A" : "",
> +		       data.tcp.psh ? "P" : "",
> +		       data.tcp.rst ? "R" : "",
> +		       data.tcp.syn ? "S" : "",
> +		       data.tcp.fin ? "F" : "");
> +	else if (m->ol_flags & RTE_IAVF_PKT_RX_DYNF_FLEX_DESC_IP_OFFSET)
> +		printf(" - Flexible descriptor's Extraction: ip_offset=%u",
> +		       data.ip_ofs);
> +}
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_PMD_IAVF_H_ */

You need to export these global symbols into rte_pmd_iavf_version.map like:

EXPERIMENTAL {
        global:

        rte_net_iavf_dynfield_proto_xtr_metadata_offs;
        ...
};

> --
> 2.20.1



More information about the dev mailing list