[dpdk-dev] [PATCH] mbuf: new flag when Vlan is stripped

Ananyev, Konstantin konstantin.ananyev at intel.com
Mon May 23 11:20:36 CEST 2016



> -----Original Message-----
> From: Olivier Matz [mailto:olivier.matz at 6wind.com]
> Sent: Monday, May 23, 2016 9:47 AM
> To: dev at dpdk.org
> Cc: johndale at cisco.com; Ananyev, Konstantin; Zhang, Helin; adrien.mazarguil at 6wind.com; rahul.lakkireddy at chelsio.com;
> alejandro.lucero at netronome.com; sony.chacko at qlogic.com
> Subject: [PATCH] mbuf: new flag when Vlan is stripped
> 
> The behavior of PKT_RX_VLAN_PKT was not very well defined, resulting in
> PMDs not advertising the same flags in similar conditions.
> 
> Following discussion in [1], introduce 2 new flags PKT_RX_VLAN_STRIPPED
> and PKT_RX_QINQ_STRIPPED that are better defined:
> 
>   PKT_RX_VLAN_STRIPPED: a vlan has been stripped by the hardware and its
>   tci is saved in mbuf->vlan_tci. This can only happen if vlan stripping
>   is enabled in the RX configuration of the PMD.
> 
> For now, the old flag PKT_RX_VLAN_PKT is kept but marked as deprecated.
> It should be removed from applications and PMDs in a future revision.
> 
> This patch also updates the drivers. For PKT_RX_VLAN_PKT:
> 
> - e1000, enic, i40e, mlx5, nfp, vmxnet3: done, PKT_RX_VLAN_PKT already
>   had the same meaning than PKT_RX_VLAN_STRIPPED, minor update is
>   required.
> - fm10k: done, PKT_RX_VLAN_PKT already had the same meaning than
>   PKT_RX_VLAN_STRIPPED, and vlan stripping is always enabled on fm10k.
> - ixgbe: modification done for standard mode (vector does not support
>   vlan stripping)
> - the other drivers do not support vlan stripping.
> 
> For PKT_RX_QINQ_PKT, it was only supported on i40e, and the meaning was
> already correct, so we can reuse the same value for PKT_RX_QINQ_STRIPPED.
> 
> [1] http://dpdk.org/ml/archives/dev/2016-April/037837.html,
> 
> Signed-off-by: Olivier Matz <olivier.matz at 6wind.com>
> ---
> 
> RFC -> v1:
> - fix checkpatch and check-git-log.sh issues
> - add a deprecation notice for the old vlan flags
> - rebase on head
> 
> 
>  app/test-pmd/rxonly.c                |  4 +--
>  doc/guides/rel_notes/deprecation.rst |  5 ++++
>  drivers/net/e1000/em_rxtx.c          |  3 ++-
>  drivers/net/e1000/igb_rxtx.c         |  3 ++-
>  drivers/net/enic/enic_rx.c           |  2 +-
>  drivers/net/i40e/i40e_rxtx.c         |  2 +-
>  drivers/net/ixgbe/ixgbe_ethdev.c     |  7 +++++
>  drivers/net/ixgbe/ixgbe_rxtx.c       | 21 +++++++++++----
>  drivers/net/ixgbe/ixgbe_rxtx.h       |  1 +
>  drivers/net/mlx5/mlx5_rxtx.c         |  6 +++--
>  drivers/net/nfp/nfp_net.c            |  2 +-
>  drivers/net/vmxnet3/vmxnet3_rxtx.c   |  2 +-
>  lib/librte_mbuf/rte_mbuf.c           |  2 ++
>  lib/librte_mbuf/rte_mbuf.h           | 50 ++++++++++++++++++++++++++++++++----
>  14 files changed, 90 insertions(+), 20 deletions(-)
> 
> diff --git a/app/test-pmd/rxonly.c b/app/test-pmd/rxonly.c
> index 14555ab..c69b344 100644
> --- a/app/test-pmd/rxonly.c
> +++ b/app/test-pmd/rxonly.c
> @@ -156,9 +156,9 @@ pkt_burst_receive(struct fwd_stream *fs)
>  				printf("hash=0x%x ID=0x%x ",
>  				       mb->hash.fdir.hash, mb->hash.fdir.id);
>  		}
> -		if (ol_flags & PKT_RX_VLAN_PKT)
> +		if (ol_flags & PKT_RX_VLAN_STRIPPED)
>  			printf(" - VLAN tci=0x%x", mb->vlan_tci);
> -		if (ol_flags & PKT_RX_QINQ_PKT)
> +		if (ol_flags & PKT_RX_QINQ_STRIPPED)
>  			printf(" - QinQ VLAN tci=0x%x, VLAN tci outer=0x%x",
>  					mb->vlan_tci, mb->vlan_tci_outer);
>  		if (mb->packet_type) {
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index ad05eba..2233a90 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -57,3 +57,8 @@ Deprecation Notices
>    a handle, like the way kernel exposes an fd to user for locating a
>    specific file, and to keep all major structures internally, so that
>    we are likely to be free from ABI violations in future.
> +
> +* The mbuf flags PKT_RX_VLAN_PKT and PKT_RX_QINQ_PKT are deprecated and
> +  are respectively replaced by PKT_RX_VLAN_STRIPPED and
> +  PKT_RX_QINQ_STRIPPED, that are better described. The old flags and
> +  their behavior will be kept in 16.07 and will be removed in 16.11.
> diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c
> index 3d36f21..6d8750a 100644
> --- a/drivers/net/e1000/em_rxtx.c
> +++ b/drivers/net/e1000/em_rxtx.c
> @@ -629,7 +629,8 @@ rx_desc_status_to_pkt_flags(uint32_t rx_status)
>  	uint64_t pkt_flags;
> 
>  	/* Check if VLAN present */
> -	pkt_flags = ((rx_status & E1000_RXD_STAT_VP) ?  PKT_RX_VLAN_PKT : 0);
> +	pkt_flags = ((rx_status & E1000_RXD_STAT_VP) ?
> +		PKT_RX_VLAN_PKT | PKT_RX_VLAN_STRIPPED : 0);
> 
>  	return pkt_flags;
>  }
> diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
> index 18aeead..9d80a0b 100644
> --- a/drivers/net/e1000/igb_rxtx.c
> +++ b/drivers/net/e1000/igb_rxtx.c
> @@ -729,7 +729,8 @@ rx_desc_status_to_pkt_flags(uint32_t rx_status)
>  	uint64_t pkt_flags;
> 
>  	/* Check if VLAN present */
> -	pkt_flags = (rx_status & E1000_RXD_STAT_VP) ?  PKT_RX_VLAN_PKT : 0;
> +	pkt_flags = ((rx_status & E1000_RXD_STAT_VP) ?
> +		PKT_RX_VLAN_PKT | PKT_RX_VLAN_STRIPPED : 0);
> 
>  #if defined(RTE_LIBRTE_IEEE1588)
>  	if (rx_status & E1000_RXD_STAT_TMST)
> diff --git a/drivers/net/enic/enic_rx.c b/drivers/net/enic/enic_rx.c
> index f92f6bc..6459e97 100644
> --- a/drivers/net/enic/enic_rx.c
> +++ b/drivers/net/enic/enic_rx.c
> @@ -197,7 +197,7 @@ enic_cq_rx_to_pkt_flags(struct cq_desc *cqd, struct rte_mbuf *mbuf)
> 
>  	/* VLAN stripping */
>  	if (bwflags & CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED) {
> -		pkt_flags |= PKT_RX_VLAN_PKT;
> +		pkt_flags |= PKT_RX_VLAN_PKT | PKT_RX_VLAN_STRIPPED;
>  		mbuf->vlan_tci = enic_cq_rx_desc_vlan(cqrd);
>  	} else {
>  		mbuf->vlan_tci = 0;
> diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
> index c833aa3..aa161a9 100644
> --- a/drivers/net/i40e/i40e_rxtx.c
> +++ b/drivers/net/i40e/i40e_rxtx.c
> @@ -99,7 +99,7 @@ i40e_rxd_to_vlan_tci(struct rte_mbuf *mb, volatile union i40e_rx_desc *rxdp)
>  #ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC
>  	if (rte_le_to_cpu_16(rxdp->wb.qword2.ext_status) &
>  		(1 << I40E_RX_DESC_EXT_STATUS_L2TAG2P_SHIFT)) {
> -		mb->ol_flags |= PKT_RX_QINQ_PKT;
> +		mb->ol_flags |= PKT_RX_QINQ_STRIPPED;
>  		mb->vlan_tci_outer = mb->vlan_tci;
>  		mb->vlan_tci = rte_le_to_cpu_16(rxdp->wb.qword2.l2tag2_2);
>  		PMD_RX_LOG(DEBUG, "Descriptor l2tag2_1: %u, l2tag2_2: %u",
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> index a2b170b..e7717e3 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -1636,6 +1636,7 @@ ixgbe_vlan_hw_strip_bitmap_set(struct rte_eth_dev *dev, uint16_t queue, bool on)
>  {
>  	struct ixgbe_hwstrip *hwstrip =
>  		IXGBE_DEV_PRIVATE_TO_HWSTRIP_BITMAP(dev->data->dev_private);
> +	struct ixgbe_rx_queue *rxq;
> 
>  	if (queue >= IXGBE_MAX_RX_QUEUE_NUM)
>  		return;
> @@ -1644,6 +1645,12 @@ ixgbe_vlan_hw_strip_bitmap_set(struct rte_eth_dev *dev, uint16_t queue, bool on)
>  		IXGBE_SET_HWSTRIP(hwstrip, queue);
>  	else
>  		IXGBE_CLEAR_HWSTRIP(hwstrip, queue);
> +
> +	if (queue >= dev->data->nb_rx_queues)
> +		return;
> +
> +	rxq = dev->data->rx_queues[queue];
> +	rxq->vlan_strip = on;
>  }
> 
>  static void
> diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
> index 9c6eaf2..3d740df 100644
> --- a/drivers/net/ixgbe/ixgbe_rxtx.c
> +++ b/drivers/net/ixgbe/ixgbe_rxtx.c
> @@ -1221,16 +1221,23 @@ ixgbe_rxd_pkt_info_to_pkt_flags(uint16_t pkt_info)
>  }
> 
>  static inline uint64_t
> -rx_desc_status_to_pkt_flags(uint32_t rx_status)
> +rx_desc_status_to_pkt_flags(uint32_t rx_status, uint8_t vlan_strip)
>  {
>  	uint64_t pkt_flags;
> +	uint64_t vlan_flags;
> +
> +	/* if vlan is stripped, set the proper flag */
> +	if (vlan_strip)
> +		vlan_flags = PKT_RX_VLAN_PKT | PKT_RX_VLAN_STRIPPED;
> +	else
> +		vlan_flags = PKT_RX_VLAN_PKT;
> 
>  	/*
>  	 * Check if VLAN present only.
>  	 * Do not check whether L3/L4 rx checksum done by NIC or not,
>  	 * That can be found from rte_eth_rxmode.hw_ip_checksum flag
>  	 */
> -	pkt_flags = (rx_status & IXGBE_RXD_STAT_VP) ?  PKT_RX_VLAN_PKT : 0;
> +	pkt_flags = (rx_status & IXGBE_RXD_STAT_VP) ?  vlan_flags : 0;


Instead of storing in rxq (and passing as a parameter) a bool value for vlan_strip (=on/off),
you probably can store in rxq and pass as a parameter here uint64_t vlan_flags;
Then it will be:
 
rx_desc_status_to_pkt_flags(uint32_t rx_status, uint64_t vlan_flags)
{
   ...
   pkt_flags = (rx_status & IXGBE_RXD_STAT_VP) ?  vlan_flags : 0;
   ...
}

...
pkt_flags = rx_desc_status_to_pkt_flags(s[j], rxq->vlan_flags);

Might help to save few cycles here.
Konstantin

> 
>  #ifdef RTE_LIBRTE_IEEE1588
>  	if (rx_status & IXGBE_RXD_STAT_TMST)
> @@ -1287,6 +1294,7 @@ ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
>  	uint32_t pkt_info[LOOK_AHEAD];
>  	int i, j, nb_rx = 0;
>  	uint32_t status;
> +	uint8_t vlan_strip = rxq->vlan_strip;
> 
>  	/* get references to current descriptor and S/W ring entry */
>  	rxdp = &rxq->rx_ring[rxq->rx_tail];
> @@ -1328,7 +1336,8 @@ ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
>  			mb->vlan_tci = rte_le_to_cpu_16(rxdp[j].wb.upper.vlan);
> 
>  			/* convert descriptor fields to rte mbuf flags */
> -			pkt_flags = rx_desc_status_to_pkt_flags(s[j]);
> +			pkt_flags = rx_desc_status_to_pkt_flags(s[j],
> +				vlan_strip);
>  			pkt_flags |= rx_desc_error_to_pkt_flags(s[j]);
>  			pkt_flags |= ixgbe_rxd_pkt_info_to_pkt_flags
>  					((uint16_t)pkt_info[j]);
> @@ -1544,6 +1553,7 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
>  	uint16_t nb_rx;
>  	uint16_t nb_hold;
>  	uint64_t pkt_flags;
> +	uint8_t vlan_strip;
> 
>  	nb_rx = 0;
>  	nb_hold = 0;
> @@ -1551,6 +1561,7 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
>  	rx_id = rxq->rx_tail;
>  	rx_ring = rxq->rx_ring;
>  	sw_ring = rxq->sw_ring;
> +	vlan_strip = rxq->vlan_strip;
>  	while (nb_rx < nb_pkts) {
>  		/*
>  		 * The order of operations here is important as the DD status
> @@ -1660,7 +1671,7 @@ ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
>  		/* Only valid if PKT_RX_VLAN_PKT set in pkt_flags */
>  		rxm->vlan_tci = rte_le_to_cpu_16(rxd.wb.upper.vlan);
> 
> -		pkt_flags = rx_desc_status_to_pkt_flags(staterr);
> +		pkt_flags = rx_desc_status_to_pkt_flags(staterr, vlan_strip);
>  		pkt_flags = pkt_flags | rx_desc_error_to_pkt_flags(staterr);
>  		pkt_flags = pkt_flags |
>  			ixgbe_rxd_pkt_info_to_pkt_flags((uint16_t)pkt_info);
> @@ -1753,7 +1764,7 @@ ixgbe_fill_cluster_head_buf(
>  	 */
>  	head->vlan_tci = rte_le_to_cpu_16(desc->wb.upper.vlan);
>  	pkt_info = rte_le_to_cpu_32(desc->wb.lower.lo_dword.data);
> -	pkt_flags = rx_desc_status_to_pkt_flags(staterr);
> +	pkt_flags = rx_desc_status_to_pkt_flags(staterr, rxq->vlan_strip);
>  	pkt_flags |= rx_desc_error_to_pkt_flags(staterr);
>  	pkt_flags |= ixgbe_rxd_pkt_info_to_pkt_flags((uint16_t)pkt_info);
>  	head->ol_flags = pkt_flags;
> diff --git a/drivers/net/ixgbe/ixgbe_rxtx.h b/drivers/net/ixgbe/ixgbe_rxtx.h
> index 3691a19..9ca0e8b 100644
> --- a/drivers/net/ixgbe/ixgbe_rxtx.h
> +++ b/drivers/net/ixgbe/ixgbe_rxtx.h
> @@ -146,6 +146,7 @@ struct ixgbe_rx_queue {
>  	uint8_t             crc_len;  /**< 0 if CRC stripped, 4 otherwise. */
>  	uint8_t             drop_en;  /**< If not 0, set SRRCTL.Drop_En. */
>  	uint8_t             rx_deferred_start; /**< not in global dev start. */
> +	uint8_t             vlan_strip; /**< 1 if vlan stripping enabled. */
>  	/** need to alloc dummy mbuf, for wraparound when scanning hw ring */
>  	struct rte_mbuf fake_mbuf;
>  	/** hold packets to return to application */


More information about the dev mailing list