From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <3chas3@gmail.com> Received: from mail-io0-f196.google.com (mail-io0-f196.google.com [209.85.223.196]) by dpdk.org (Postfix) with ESMTP id 11A432BB1 for ; Wed, 29 Aug 2018 01:59:06 +0200 (CEST) Received: by mail-io0-f196.google.com with SMTP id l7-v6so2969370iok.6 for ; Tue, 28 Aug 2018 16:59:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:sender:from:date:message-id :subject:to:cc; bh=UiMOV3jnp9wcYmdHuB4H/k40xCbgqvT4u9lmGtsKdnM=; b=abP9QePxpAEsofGV9SV+FvTESVoVd79/S5TPbIaI25+OtcZRwMhk8vabLD8jCN0kYN HGR68Vd3IXgAR/RCN7fs7uhf53r8SG6gW2yodjUKYdbfLFJzPGajBNn8U7xXZd4q6Wmj LdEAL/qsAcLki7eUhjHCQyXsQQo784IITsut1+wvrLA2opFLgM3gXd6CVOlhdaGgXUhf Q7SpJSBJXFH4e36rAOnSqPZbOJISVC2sbSm6Jf0A2LUnvUyr8kBLVnemPy38kGCYHt6Y t9j3TV/0UXcBhpwTm9C9mhGCzlM2ptr9brZR226FUhut1qjNvhC8O7EjqNPdGBGoTmUr FNQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:sender:from :date:message-id:subject:to:cc; bh=UiMOV3jnp9wcYmdHuB4H/k40xCbgqvT4u9lmGtsKdnM=; b=I5tt8JmC6WnbA0cm8UuRAzGLxN1VYcN6EoYMyXxlpxNqEbIhynOvT/uWDGp6nY5+Qr orKdDdAvTFzkIAZ60G1c7Us7Sq34lIG+Hdd4TShAT6dtwPzlTq+tlFkVof4yXmCyTkDk 2W1BWYm1Fspsl9Cfdg3fBXOt9+3LU4aT1bgIVD7fWwnl8zsxpeptQq8mmSvYdFwcNGJp +ymVg5rNELbOuSOLqbKWUoFqbO6pNAcY8vr8i8K08Gcv5zEx7NijB/TMixYwsZBCL84F zzkSkxW9n/jcPDRVdAg1OLSc6WmvDFvUgOwpNIjnABT00RBvnsybs/ayx3PIP3CVFDON y0+Q== X-Gm-Message-State: APzg51DYfHw7tdSrzpolSxuJXL2lRrEQnW+HxQPzLtzooX7zbI2TNtuC c9MCdAxp2/g4PYyy57B3YC3tHYBs0nwO2Mg0BTM= X-Google-Smtp-Source: ANB0VdbskZ0sHxNmDR1ynQdBYkynTMi3gICfT4PgKPIHH2aOuDfyJL8jbzqzQP22mgX5bjc5jyVjtuGNtsGgCbmvcdQ= X-Received: by 2002:a5e:c009:: with SMTP id u9-v6mr3507680iol.155.1535500745270; Tue, 28 Aug 2018 16:59:05 -0700 (PDT) MIME-Version: 1.0 References: <1535128501-31597-1-git-send-email-robertshearman@gmail.com> In-Reply-To: <1535128501-31597-1-git-send-email-robertshearman@gmail.com> Sender: chasmosaurus@gmail.com X-Google-Sender-Delegation: chasmosaurus@gmail.com From: Chas Williams <3chas3@gmail.com> Date: Tue, 28 Aug 2018 19:58:53 -0400 X-Google-Sender-Auth: d58-Kcm0JF623EM9U_zw1Z6GiOA Message-ID: To: robertshearman@gmail.com Cc: dev@dpdk.org, "Lu, Wenzhuo" , "Ananyev, Konstantin" , Robert Shearman Content-Type: text/plain; charset="UTF-8" X-Content-Filtered-By: Mailman/MimeDel 2.1.15 Subject: Re: [dpdk-dev] [PATCH] net/ixgbe: Strip SR-IOV transparent VLANs in VF X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 28 Aug 2018 23:59:06 -0000 On Fri, Aug 24, 2018 at 12:45 PM wrote: > From: Robert Shearman > > SR-IOV VFs support "transparent" VLANs. Traffic from/to a VM > associated with a VF has a VLAN tag inserted/stripped in a manner > intended to be totally transparent to the VM. On a Linux hypervisor > the vlan can be specified by "ip link set vf vlan ". > The VM VF driver is not configured to use any VLAN and the VM should > never see the transparent VLAN for that reason. However, in practice > these VLAN headers are being received by the VM which discards the > packets as that VLAN is unknown to it. The Linux kernel ixbge driver > explicitly removes the VLAN in this case (presumably due to the > hardware not being able to do this) but the DPDK driver does not. > > This patch mirrors the kernel driver behaviour by removing the VLAN on > the VF side. This is done by checking the VLAN in the VFTA, where the > hypervisor will have set the bit in the VFTA corresponding to the VLAN > if transparent VLANs were being used for the VF. If the VLAN is set in > the VFTA then it is known that it's a transparent VLAN case and so the > VLAN is stripped from the mbuf. To limit any potential performance > impact on the PF data path, the RX path is split into PF and VF > versions with the transparent VLAN stripping only done in the VF > path. Measurements with our application show ~2% performance hit for > the VF case and none for the PF case. > > Signed-off-by: Robert Shearman > Reviewed-by: Chas Williams > --- > drivers/net/ixgbe/ixgbe_ethdev.c | 18 +++---- > drivers/net/ixgbe/ixgbe_ethdev.h | 38 +++++++++++++++ > drivers/net/ixgbe/ixgbe_rxtx.c | 83 > +++++++++++++++++++++++++++++--- > drivers/net/ixgbe/ixgbe_rxtx.h | 31 +++++++++++- > drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c | 7 +++ > drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c | 84 > ++++++++++++++++++++++++++++++--- > 6 files changed, 238 insertions(+), 23 deletions(-) > > diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c > b/drivers/net/ixgbe/ixgbe_ethdev.c > index 26b1927..3f88a02 100644 > --- a/drivers/net/ixgbe/ixgbe_ethdev.c > +++ b/drivers/net/ixgbe/ixgbe_ethdev.c > @@ -604,7 +604,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = { > .vlan_filter_set = ixgbevf_vlan_filter_set, > .vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set, > .vlan_offload_set = ixgbevf_vlan_offload_set, > - .rx_queue_setup = ixgbe_dev_rx_queue_setup, > + .rx_queue_setup = ixgbevf_dev_rx_queue_setup, > .rx_queue_release = ixgbe_dev_rx_queue_release, > .rx_descriptor_done = ixgbe_dev_rx_descriptor_done, > .rx_descriptor_status = ixgbe_dev_rx_descriptor_status, > @@ -1094,7 +1094,7 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void > *init_params __rte_unused) > "Using default TX function."); > } > > - ixgbe_set_rx_function(eth_dev); > + ixgbe_set_rx_function(eth_dev, true); > > return 0; > } > @@ -1576,7 +1576,7 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev) > "No TX queues configured yet. Using > default TX function."); > } > > - ixgbe_set_rx_function(eth_dev); > + ixgbe_set_rx_function(eth_dev, true); > > return 0; > } > @@ -1839,8 +1839,8 @@ ixgbe_vlan_filter_set(struct rte_eth_dev *dev, > uint16_t vlan_id, int on) > uint32_t vid_idx; > uint32_t vid_bit; > > - vid_idx = (uint32_t) ((vlan_id >> 5) & 0x7F); > - vid_bit = (uint32_t) (1 << (vlan_id & 0x1F)); > + vid_idx = ixgbe_vfta_index(vlan_id); > + vid_bit = ixgbe_vfta_bit(vlan_id); > vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(vid_idx)); > if (on) > vfta |= vid_bit; > @@ -3807,7 +3807,9 @@ ixgbe_dev_supported_ptypes_get(struct rte_eth_dev > *dev) > > #if defined(RTE_ARCH_X86) > if (dev->rx_pkt_burst == ixgbe_recv_pkts_vec || > - dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec) > + dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec || > + dev->rx_pkt_burst == ixgbevf_recv_pkts_vec || > + dev->rx_pkt_burst == ixgbevf_recv_scattered_pkts_vec) > return ptypes; > #endif > return NULL; > @@ -5231,8 +5233,8 @@ ixgbevf_vlan_filter_set(struct rte_eth_dev *dev, > uint16_t vlan_id, int on) > PMD_INIT_LOG(ERR, "Unable to set VF vlan"); > return ret; > } > - vid_idx = (uint32_t) ((vlan_id >> 5) & 0x7F); > - vid_bit = (uint32_t) (1 << (vlan_id & 0x1F)); > + vid_idx = ixgbe_vfta_index(vlan_id); > + vid_bit = ixgbe_vfta_bit(vlan_id); > > /* Save what we set and retore it after device reset */ > if (on) > diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h > b/drivers/net/ixgbe/ixgbe_ethdev.h > index d0b9396..483d2cd 100644 > --- a/drivers/net/ixgbe/ixgbe_ethdev.h > +++ b/drivers/net/ixgbe/ixgbe_ethdev.h > @@ -568,6 +568,11 @@ int ixgbe_dev_rx_queue_setup(struct rte_eth_dev > *dev, uint16_t rx_queue_id, > const struct rte_eth_rxconf *rx_conf, > struct rte_mempool *mb_pool); > > +int ixgbevf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t > rx_queue_id, > + uint16_t nb_rx_desc, unsigned int > socket_id, > + const struct rte_eth_rxconf *rx_conf, > + struct rte_mempool *mb_pool); > + > int ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t > tx_queue_id, > uint16_t nb_tx_desc, unsigned int socket_id, > const struct rte_eth_txconf *tx_conf); > @@ -779,4 +784,37 @@ ixgbe_ethertype_filter_remove(struct > ixgbe_filter_info *filter_info, > return idx; > } > > +int ixgbe_fdir_ctrl_func(struct rte_eth_dev *dev, > + enum rte_filter_op filter_op, void *arg); > + > +/* > + * Calculate index in vfta array of the 32 bit value enclosing > + * a given vlan id > + */ > +static inline uint32_t > +ixgbe_vfta_index(uint16_t vlan) > +{ > + return (vlan >> 5) & 0x7f; > +} > + > +/* > + * Calculate vfta array entry bitmask for vlan id within the > + * enclosing 32 bit entry. > + */ > +static inline uint32_t > +ixgbe_vfta_bit(uint16_t vlan) > +{ > + return 1 << (vlan & 0x1f); > +} > + > +/* > + * Check in the vfta bit array if the bit corresponding to > + * the given vlan is set. > + */ > +static inline bool > +ixgbe_vfta_is_vlan_set(const struct ixgbe_vfta *vfta, uint16_t vlan) > +{ > + return (vfta->vfta[ixgbe_vfta_index(vlan)] & ixgbe_vfta_bit(vlan)) > != 0; > +} > + > #endif /* _IXGBE_ETHDEV_H_ */ > diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c > b/drivers/net/ixgbe/ixgbe_rxtx.c > index f82b74a..26a99cb 100644 > --- a/drivers/net/ixgbe/ixgbe_rxtx.c > +++ b/drivers/net/ixgbe/ixgbe_rxtx.c > @@ -1623,14 +1623,23 @@ ixgbe_rx_fill_from_stage(struct ixgbe_rx_queue > *rxq, struct rte_mbuf **rx_pkts, > uint16_t nb_pkts) > { > struct rte_mbuf **stage = &rxq->rx_stage[rxq->rx_next_avail]; > + const struct rte_eth_dev *dev; > + const struct ixgbe_vfta *vfta; > int i; > > + dev = &rte_eth_devices[rxq->port_id]; > + vfta = IXGBE_DEV_PRIVATE_TO_VFTA(dev->data->dev_private); > + > /* how many packets are ready to return? */ > nb_pkts = (uint16_t)RTE_MIN(nb_pkts, rxq->rx_nb_avail); > > /* copy mbuf pointers to the application's packet list */ > - for (i = 0; i < nb_pkts; ++i) > + for (i = 0; i < nb_pkts; ++i) { > rx_pkts[i] = stage[i]; > + if (rxq->vf) > + ixgbevf_trans_vlan_sw_filter_hdr(rx_pkts[i], > + vfta); > + } > > /* update internal queue state */ > rxq->rx_nb_avail = (uint16_t)(rxq->rx_nb_avail - nb_pkts); > @@ -1750,6 +1759,8 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf > **rx_pkts, > uint16_t nb_hold; > uint64_t pkt_flags; > uint64_t vlan_flags; > + const struct rte_eth_dev *dev; > + const struct ixgbe_vfta *vfta; > > nb_rx = 0; > nb_hold = 0; > @@ -1758,6 +1769,9 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf > **rx_pkts, > rx_ring = rxq->rx_ring; > sw_ring = rxq->sw_ring; > vlan_flags = rxq->vlan_flags; > + dev = &rte_eth_devices[rxq->port_id]; > + vfta = IXGBE_DEV_PRIVATE_TO_VFTA(dev->data->dev_private); > + > while (nb_rx < nb_pkts) { > /* > * The order of operations here is important as the DD > status > @@ -1876,6 +1890,10 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf > **rx_pkts, > ixgbe_rxd_pkt_info_to_pkt_type(pkt_info, > rxq->pkt_type_mask); > > + if (rxq->vf) > + ixgbevf_trans_vlan_sw_filter_hdr(rxm, > + vfta); > + > if (likely(pkt_flags & PKT_RX_RSS_HASH)) > rxm->hash.rss = rte_le_to_cpu_32( > rxd.wb.lower.hi_dword.rss); > @@ -2016,6 +2034,11 @@ ixgbe_recv_pkts_lro(void *rx_queue, struct rte_mbuf > **rx_pkts, uint16_t nb_pkts, > uint16_t nb_rx = 0; > uint16_t nb_hold = rxq->nb_rx_hold; > uint16_t prev_id = rxq->rx_tail; > + const struct rte_eth_dev *dev; > + const struct ixgbe_vfta *vfta; > + > + dev = &rte_eth_devices[rxq->port_id]; > + vfta = IXGBE_DEV_PRIVATE_TO_VFTA(dev->data->dev_private); > > while (nb_rx < nb_pkts) { > bool eop; > @@ -2230,6 +2253,10 @@ ixgbe_recv_pkts_lro(void *rx_queue, struct rte_mbuf > **rx_pkts, uint16_t nb_pkts, > rte_packet_prefetch((char *)first_seg->buf_addr + > first_seg->data_off); > > + if (rxq->vf) > + ixgbevf_trans_vlan_sw_filter_hdr(first_seg, > + vfta); > + > /* > * Store the mbuf address into the next entry of the array > * of returned packets. > @@ -3066,6 +3093,25 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev, > return 0; > } > > +int __attribute__((cold)) > +ixgbevf_dev_rx_queue_setup(struct rte_eth_dev *dev, > + uint16_t queue_idx, > + uint16_t nb_desc, > + unsigned int socket_id, > + const struct rte_eth_rxconf *rx_conf, > + struct rte_mempool *mp) > +{ > + struct ixgbe_rx_queue *rxq; > + > + ixgbe_dev_rx_queue_setup(dev, queue_idx, nb_desc, socket_id, > + rx_conf, mp); > + > + rxq = dev->data->rx_queues[queue_idx]; > + rxq->vf = true; > + > + return 0; > +} > + > uint32_t > ixgbe_dev_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id) > { > @@ -4561,7 +4607,7 @@ ixgbe_set_ivar(struct rte_eth_dev *dev, u8 entry, u8 > vector, s8 type) > } > > void __attribute__((cold)) > -ixgbe_set_rx_function(struct rte_eth_dev *dev) > +ixgbe_set_rx_function(struct rte_eth_dev *dev, bool vf) > { > uint16_t i, rx_using_sse; > struct ixgbe_adapter *adapter = > @@ -4608,7 +4654,9 @@ ixgbe_set_rx_function(struct rte_eth_dev *dev) > "callback (port=%d).", > dev->data->port_id); > > - dev->rx_pkt_burst = ixgbe_recv_scattered_pkts_vec; > + dev->rx_pkt_burst = vf ? > + ixgbevf_recv_scattered_pkts_vec : > + ixgbe_recv_scattered_pkts_vec; > } else if (adapter->rx_bulk_alloc_allowed) { > PMD_INIT_LOG(DEBUG, "Using a Scattered with bulk " > "allocation callback > (port=%d).", > @@ -4637,7 +4685,8 @@ ixgbe_set_rx_function(struct rte_eth_dev *dev) > RTE_IXGBE_DESCS_PER_LOOP, > dev->data->port_id); > > - dev->rx_pkt_burst = ixgbe_recv_pkts_vec; > + dev->rx_pkt_burst = vf ? ixgbevf_recv_pkts_vec : > + ixgbe_recv_pkts_vec; > } else if (adapter->rx_bulk_alloc_allowed) { > PMD_INIT_LOG(DEBUG, "Rx Burst Bulk Alloc Preconditions are > " > "satisfied. Rx Burst Bulk Alloc > function " > @@ -4658,7 +4707,9 @@ ixgbe_set_rx_function(struct rte_eth_dev *dev) > > rx_using_sse = > (dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec || > - dev->rx_pkt_burst == ixgbe_recv_pkts_vec); > + dev->rx_pkt_burst == ixgbe_recv_pkts_vec || > + dev->rx_pkt_burst == ixgbevf_recv_scattered_pkts_vec || > + dev->rx_pkt_burst == ixgbevf_recv_pkts_vec); > > for (i = 0; i < dev->data->nb_rx_queues; i++) { > struct ixgbe_rx_queue *rxq = dev->data->rx_queues[i]; > @@ -4977,7 +5028,7 @@ ixgbe_dev_rx_init(struct rte_eth_dev *dev) > if (rc) > return rc; > > - ixgbe_set_rx_function(dev); > + ixgbe_set_rx_function(dev, false); > > return 0; > } > @@ -5500,7 +5551,7 @@ ixgbevf_dev_rx_init(struct rte_eth_dev *dev) > IXGBE_PSRTYPE_RQPL_SHIFT; > IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype); > > - ixgbe_set_rx_function(dev); > + ixgbe_set_rx_function(dev, true); > > return 0; > } > @@ -5731,6 +5782,24 @@ ixgbe_recv_pkts_vec( > } > > uint16_t __attribute__((weak)) > +ixgbevf_recv_pkts_vec( > + void __rte_unused *rx_queue, > + struct rte_mbuf __rte_unused **rx_pkts, > + uint16_t __rte_unused nb_pkts) > +{ > + return 0; > +} > + > +uint16_t __attribute__((weak)) > +ixgbevf_recv_scattered_pkts_vec( > + void __rte_unused *rx_queue, > + struct rte_mbuf __rte_unused **rx_pkts, > + uint16_t __rte_unused nb_pkts) > +{ > + return 0; > +} > + > +uint16_t __attribute__((weak)) > ixgbe_recv_scattered_pkts_vec( > void __rte_unused *rx_queue, > struct rte_mbuf __rte_unused **rx_pkts, > diff --git a/drivers/net/ixgbe/ixgbe_rxtx.h > b/drivers/net/ixgbe/ixgbe_rxtx.h > index 39378f7..676557b 100644 > --- a/drivers/net/ixgbe/ixgbe_rxtx.h > +++ b/drivers/net/ixgbe/ixgbe_rxtx.h > @@ -111,6 +111,7 @@ struct ixgbe_rx_queue { > uint16_t rx_free_trigger; /**< triggers rx buffer allocation */ > uint8_t rx_using_sse; > /**< indicates that vector RX is in use */ > + uint8_t vf; /**< indicates that this is for a VF */ > #ifdef RTE_LIBRTE_SECURITY > uint8_t using_ipsec; > /**< indicates that IPsec RX feature is in use */ > @@ -254,6 +255,30 @@ struct ixgbe_txq_ops { > IXGBE_ADVTXD_DCMD_EOP) > > > + > +/* > + * Filter out unknown vlans resulting from use of transparent vlan. > + * > + * When a VF is configured to use transparent vlans then the VF can > + * see this VLAN being set in the packet, meaning that the transparent > + * property isn't preserved. Furthermore, when the VF is used in a > + * guest VM then there's no way of knowing for sure that transparent > + * VLAN is in use and what tag value has been configured. So work > + * around this by removing the VLAN flag if the VF isn't interested in > + * the VLAN tag. > + */ > +static inline void > +ixgbevf_trans_vlan_sw_filter_hdr(struct rte_mbuf *m, > + const struct ixgbe_vfta *vfta) > +{ > + if (m->ol_flags & PKT_RX_VLAN) { > + uint16_t vlan = m->vlan_tci & 0xFFF; > + > + if (!ixgbe_vfta_is_vlan_set(vfta, vlan)) > + m->ol_flags &= ~PKT_RX_VLAN; > + } > +} > + > /* Takes an ethdev and a queue and sets up the tx function to be used > based on > * the queue parameters. Used in tx_queue_setup by primary process and > then > * in dev_init by secondary process when attaching to an existing ethdev. > @@ -274,12 +299,16 @@ void ixgbe_set_tx_function(struct rte_eth_dev *dev, > struct ixgbe_tx_queue *txq); > * > * @dev rte_eth_dev handle > */ > -void ixgbe_set_rx_function(struct rte_eth_dev *dev); > +void ixgbe_set_rx_function(struct rte_eth_dev *dev, bool vf); > > uint16_t ixgbe_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, > uint16_t nb_pkts); > uint16_t ixgbe_recv_scattered_pkts_vec(void *rx_queue, > struct rte_mbuf **rx_pkts, uint16_t nb_pkts); > +uint16_t ixgbevf_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, > + uint16_t nb_pkts); > +uint16_t ixgbevf_recv_scattered_pkts_vec(void *rx_queue, > + struct rte_mbuf **rx_pkts, uint16_t nb_pkts); > int ixgbe_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev); > int ixgbe_rxq_vec_setup(struct ixgbe_rx_queue *rxq); > void ixgbe_rx_queue_release_mbufs_vec(struct ixgbe_rx_queue *rxq); > diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c > b/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c > index edb1383..d077918 100644 > --- a/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c > +++ b/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c > @@ -149,6 +149,9 @@ static inline uint16_t > _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, > uint16_t nb_pkts, uint8_t *split_packet) > { > + const struct rte_eth_dev *dev = &rte_eth_devices[rxq->port_id]; > + const struct ixgbe_vfta *vfta > + = IXGBE_DEV_PRIVATE_TO_VFTA(dev->data->dev_private); > volatile union ixgbe_adv_rx_desc *rxdp; > struct ixgbe_rx_entry *sw_ring; > uint16_t nb_pkts_recd; > @@ -272,8 +275,10 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct > rte_mbuf **rx_pkts, > /* D.3 copy final 3,4 data to rx_pkts */ > vst1q_u8((void *)&rx_pkts[pos + 3]->rx_descriptor_fields1, > pkt_mb4); > + ixgbe_unknown_vlan_sw_filter_hdr(rx_pkts[pos + 3], vfta, > rxq); > vst1q_u8((void *)&rx_pkts[pos + 2]->rx_descriptor_fields1, > pkt_mb3); > + ixgbe_unknown_vlan_sw_filter_hdr(rx_pkts[pos + 2], vfta, > rxq); > > /* D.2 pkt 1,2 set in_port/nb_seg and remove crc */ > tmp = vsubq_u16(vreinterpretq_u16_u8(pkt_mb2), crc_adjust); > @@ -294,8 +299,10 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct > rte_mbuf **rx_pkts, > /* D.3 copy final 1,2 data to rx_pkts */ > vst1q_u8((uint8_t *)&rx_pkts[pos + > 1]->rx_descriptor_fields1, > pkt_mb2); > + ixgbe_unknown_vlan_sw_filter_hdr(rx_pkts[pos + 1], vfta, > rxq); > vst1q_u8((uint8_t *)&rx_pkts[pos]->rx_descriptor_fields1, > pkt_mb1); > + ixgbe_unknown_vlan_sw_filter_hdr(rx_pkts[pos], vfta, rxq); > > stat &= IXGBE_VPMD_DESC_DD_MASK; > > diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c > b/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c > index c9ba482..04a3307 100644 > --- a/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c > +++ b/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c > @@ -313,9 +313,10 @@ desc_to_ptype_v(__m128i descs[4], uint16_t > pkt_type_mask, > */ > static inline uint16_t > _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, > - uint16_t nb_pkts, uint8_t *split_packet) > + uint16_t nb_pkts, bool vf, uint8_t *split_packet) > { > volatile union ixgbe_adv_rx_desc *rxdp; > + const struct ixgbe_vfta *vfta = NULL; > struct ixgbe_rx_entry *sw_ring; > uint16_t nb_pkts_recd; > #ifdef RTE_LIBRTE_SECURITY > @@ -344,6 +345,13 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct > rte_mbuf **rx_pkts, > __m128i mbuf_init; > uint8_t vlan_flags; > > + if (vf) { > + const struct rte_eth_dev *dev = > + &rte_eth_devices[rxq->port_id]; > + > + vfta = IXGBE_DEV_PRIVATE_TO_VFTA(dev->data->dev_private); > + } > + > /* nb_pkts shall be less equal than RTE_IXGBE_MAX_RX_BURST */ > nb_pkts = RTE_MIN(nb_pkts, RTE_IXGBE_MAX_RX_BURST); > > @@ -500,8 +508,15 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct > rte_mbuf **rx_pkts, > /* D.3 copy final 3,4 data to rx_pkts */ > _mm_storeu_si128((void > *)&rx_pkts[pos+3]->rx_descriptor_fields1, > pkt_mb4); > + if (vf) > + ixgbevf_trans_vlan_sw_filter_hdr(rx_pkts[pos + 3], > + vfta); > + > _mm_storeu_si128((void > *)&rx_pkts[pos+2]->rx_descriptor_fields1, > pkt_mb3); > + if (vf) > + ixgbevf_trans_vlan_sw_filter_hdr(rx_pkts[pos + 2], > + vfta); > > /* D.2 pkt 1,2 set in_port/nb_seg and remove crc */ > pkt_mb2 = _mm_add_epi16(pkt_mb2, crc_adjust); > @@ -536,8 +551,15 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct > rte_mbuf **rx_pkts, > /* D.3 copy final 1,2 data to rx_pkts */ > _mm_storeu_si128((void > *)&rx_pkts[pos+1]->rx_descriptor_fields1, > pkt_mb2); > + if (vf) > + ixgbevf_trans_vlan_sw_filter_hdr(rx_pkts[pos + 1], > + vfta); > + > _mm_storeu_si128((void > *)&rx_pkts[pos]->rx_descriptor_fields1, > pkt_mb1); > + if (vf) > + ixgbevf_trans_vlan_sw_filter_hdr(rx_pkts[pos], > + vfta); > > desc_to_ptype_v(descs, rxq->pkt_type_mask, &rx_pkts[pos]); > > @@ -569,11 +591,11 @@ uint16_t > ixgbe_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, > uint16_t nb_pkts) > { > - return _recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, NULL); > + return _recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, false, NULL); > } > > /* > - * vPMD receive routine that reassembles scattered packets > + * vPMD raw receive routine that reassembles scattered packets > * > * Notice: > * - nb_pkts < RTE_IXGBE_DESCS_PER_LOOP, just return no packet > @@ -581,16 +603,16 @@ ixgbe_recv_pkts_vec(void *rx_queue, struct rte_mbuf > **rx_pkts, > * numbers of DD bit > * - floor align nb_pkts to a RTE_IXGBE_DESC_PER_LOOP power-of-two > */ > -uint16_t > -ixgbe_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, > - uint16_t nb_pkts) > +static inline uint16_t > +_recv_raw_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, > + uint16_t nb_pkts, bool vf) > { > struct ixgbe_rx_queue *rxq = rx_queue; > uint8_t split_flags[RTE_IXGBE_MAX_RX_BURST] = {0}; > > /* get some new buffers */ > uint16_t nb_bufs = _recv_raw_pkts_vec(rxq, rx_pkts, nb_pkts, > - split_flags); > + vf, split_flags); > if (nb_bufs == 0) > return 0; > > @@ -614,6 +636,54 @@ ixgbe_recv_scattered_pkts_vec(void *rx_queue, struct > rte_mbuf **rx_pkts, > &split_flags[i]); > } > > +/* > + * vPMD receive routine that reassembles scattered packets > + * > + * Notice: > + * - nb_pkts < RTE_IXGBE_DESCS_PER_LOOP, just return no packet > + * - nb_pkts > RTE_IXGBE_MAX_RX_BURST, only scan RTE_IXGBE_MAX_RX_BURST > + * numbers of DD bit > + * - floor align nb_pkts to a RTE_IXGBE_DESC_PER_LOOP power-of-two > + */ > +uint16_t > +ixgbe_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, > + uint16_t nb_pkts) > +{ > + return _recv_raw_scattered_pkts_vec(rx_queue, rx_pkts, nb_pkts, > false); > +} > + > +/* > + * vPMD VF receive routine, only accept(nb_pkts >= > RTE_IXGBE_DESCS_PER_LOOP) > + * > + * Notice: > + * - nb_pkts < RTE_IXGBE_DESCS_PER_LOOP, just return no packet > + * - nb_pkts > RTE_IXGBE_MAX_RX_BURST, only scan RTE_IXGBE_MAX_RX_BURST > + * numbers of DD bit > + * - floor align nb_pkts to a RTE_IXGBE_DESC_PER_LOOP power-of-two > + */ > +uint16_t > +ixgbevf_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, > + uint16_t nb_pkts) > +{ > + return _recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, true, NULL); > +} > + > +/* > + * vPMD VF receive routine that reassembles scattered packets > + * > + * Notice: > + * - nb_pkts < RTE_IXGBE_DESCS_PER_LOOP, just return no packet > + * - nb_pkts > RTE_IXGBE_MAX_RX_BURST, only scan RTE_IXGBE_MAX_RX_BURST > + * numbers of DD bit > + * - floor align nb_pkts to a RTE_IXGBE_DESC_PER_LOOP power-of-two > + */ > +uint16_t > +ixgbevf_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, > + uint16_t nb_pkts) > +{ > + return _recv_raw_scattered_pkts_vec(rx_queue, rx_pkts, nb_pkts, > true); > +} > + > static inline void > vtx1(volatile union ixgbe_adv_tx_desc *txdp, > struct rte_mbuf *pkt, uint64_t flags) > -- > 2.7.4 > >