Hi Jeff, > -----Original Message----- > From: dev <dev-boun...@dpdk.org> On Behalf Of Jeff Guo > Sent: Wednesday, September 9, 2020 10:54 > To: Wu, Jingjing <jingjing...@intel.com>; Zhang, Qi Z <qi.z.zh...@intel.com>; > Xing, Beilei > <beilei.x...@intel.com> > Cc: dev@dpdk.org; Guo, Jia <jia....@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....@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