[dpdk-stable] patch 'net/virtio: fix Rx scatter offload' has been queued to stable release 20.11.3

luca.boccassi at gmail.com luca.boccassi at gmail.com
Mon Jul 26 15:52:48 CEST 2021


Hi,

FYI, your patch has been queued to stable release 20.11.3

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 07/28/21. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/bluca/dpdk-stable

This queued commit can be viewed at:
https://github.com/bluca/dpdk-stable/commit/a961df1650da104147df36cdf0c1f3bc567792e2

Thanks.

Luca Boccassi

---
>From a961df1650da104147df36cdf0c1f3bc567792e2 Mon Sep 17 00:00:00 2001
From: Ivan Ilchenko <ivan.ilchenko at oktetlabs.ru>
Date: Tue, 20 Jul 2021 10:54:45 +0300
Subject: [PATCH] net/virtio: fix Rx scatter offload

[ upstream commit 4e8169eb0d2d34067f56b368633f816ce927650a ]

Report Rx scatter offload capability depending on VIRTIO_NET_F_MRG_RXBUF.

If Rx scatter is not requested, ensure that provided Rx buffers on
each Rx queue are big enough to fit Rx packets up to configured MTU.

Fixes: ce17eddefc20 ("ethdev: introduce Rx queue offloads API")

Signed-off-by: Ivan Ilchenko <ivan.ilchenko at oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybchenko at oktetlabs.ru>
Reviewed-by: Maxime Coquelin <maxime.coquelin at redhat.com>
---
 drivers/net/virtio/virtio_ethdev.c | 65 ++++++++++++++++++++++++++++++
 drivers/net/virtio/virtio_ethdev.h |  5 +++
 drivers/net/virtio/virtio_pci.h    |  2 +
 drivers/net/virtio/virtio_rxtx.c   | 10 +++++
 4 files changed, 82 insertions(+)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 6c233b75ba..25810cc8db 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -867,6 +867,56 @@ virtio_dev_allmulticast_disable(struct rte_eth_dev *dev)
 	return 0;
 }
 
+uint16_t
+virtio_rx_mem_pool_buf_size(struct rte_mempool *mp)
+{
+	return rte_pktmbuf_data_room_size(mp) - RTE_PKTMBUF_HEADROOM;
+}
+
+bool
+virtio_rx_check_scatter(uint16_t max_rx_pkt_len, uint16_t rx_buf_size,
+			bool rx_scatter_enabled, const char **error)
+{
+	if (!rx_scatter_enabled && max_rx_pkt_len > rx_buf_size) {
+		*error = "Rx scatter is disabled and RxQ mbuf pool object size is too small";
+		return false;
+	}
+
+	return true;
+}
+
+static bool
+virtio_check_scatter_on_all_rx_queues(struct rte_eth_dev *dev,
+				      uint16_t frame_size)
+{
+	struct virtio_hw *hw = dev->data->dev_private;
+	struct virtnet_rx *rxvq;
+	struct virtqueue *vq;
+	unsigned int qidx;
+	uint16_t buf_size;
+	const char *error;
+
+	if (hw->vqs == NULL)
+		return true;
+
+	for (qidx = 0; (vq = hw->vqs[2 * qidx + VTNET_SQ_RQ_QUEUE_IDX]) != NULL;
+	     qidx++) {
+		rxvq = &vq->rxq;
+		if (rxvq->mpool == NULL)
+			continue;
+		buf_size = virtio_rx_mem_pool_buf_size(rxvq->mpool);
+
+		if (!virtio_rx_check_scatter(frame_size, buf_size,
+					     hw->rx_ol_scatter, &error)) {
+			PMD_INIT_LOG(ERR, "MTU check for RxQ %u failed: %s",
+				     qidx, error);
+			return false;
+		}
+	}
+
+	return true;
+}
+
 #define VLAN_TAG_LEN           4    /* 802.3ac tag (not DMA'd) */
 static int
 virtio_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
@@ -884,6 +934,15 @@ virtio_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 			RTE_ETHER_MIN_MTU, max_frame_size - ether_hdr_len);
 		return -EINVAL;
 	}
+
+	if (!virtio_check_scatter_on_all_rx_queues(dev, frame_size)) {
+		PMD_INIT_LOG(ERR, "MTU vs Rx scatter and Rx buffers check failed");
+		return -EINVAL;
+	}
+
+	hw->max_rx_pkt_len = frame_size;
+	dev->data->dev_conf.rxmode.max_rx_pkt_len = hw->max_rx_pkt_len;
+
 	return 0;
 }
 
@@ -2242,6 +2301,8 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 	if (rxmode->max_rx_pkt_len > hw->max_mtu + ether_hdr_len)
 		req_features &= ~(1ULL << VIRTIO_NET_F_MTU);
 
+	hw->max_rx_pkt_len = rxmode->max_rx_pkt_len;
+
 	if (rx_offloads & (DEV_RX_OFFLOAD_UDP_CKSUM |
 			   DEV_RX_OFFLOAD_TCP_CKSUM))
 		req_features |= (1ULL << VIRTIO_NET_F_GUEST_CSUM);
@@ -2290,6 +2351,8 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 	if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
 		hw->vlan_strip = 1;
 
+	hw->rx_ol_scatter = (rx_offloads & DEV_RX_OFFLOAD_SCATTER);
+
 	if ((rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
 	    && !vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VLAN)) {
 		PMD_DRV_LOG(ERR,
@@ -2635,6 +2698,8 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	host_features = VTPCI_OPS(hw)->get_features(hw);
 	dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP;
 	dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_JUMBO_FRAME;
+	if (host_features & (1ULL << VIRTIO_NET_F_MRG_RXBUF))
+		dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_SCATTER;
 	if (host_features & (1ULL << VIRTIO_NET_F_GUEST_CSUM)) {
 		dev_info->rx_offload_capa |=
 			DEV_RX_OFFLOAD_TCP_CKSUM |
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index b7d52d497f..916ff11f7a 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -120,4 +120,9 @@ void virtio_dev_resume(struct rte_eth_dev *dev);
 int virtio_inject_pkts(struct rte_eth_dev *dev, struct rte_mbuf **tx_pkts,
 		int nb_pkts);
 
+bool virtio_rx_check_scatter(uint16_t max_rx_pkt_len, uint16_t rx_buf_size,
+			bool rx_scatter_enabled, const char **error);
+
+uint16_t virtio_rx_mem_pool_buf_size(struct rte_mempool *mp);
+
 #endif /* _VIRTIO_ETHDEV_H_ */
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index ab61e911b8..f56d3e8bb7 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -259,6 +259,7 @@ struct virtio_hw {
 	uint8_t     use_inorder_rx;
 	uint8_t     use_inorder_tx;
 	uint8_t     weak_barriers;
+	bool        rx_ol_scatter;
 	bool        has_tx_offload;
 	bool        has_rx_offload;
 	uint16_t    port_id;
@@ -268,6 +269,7 @@ struct virtio_hw {
 	uint8_t     duplex;
 	uint8_t     *isr;
 	uint16_t    *notify_base;
+	size_t      max_rx_pkt_len;
 	struct virtio_pci_common_cfg *common_cfg;
 	struct virtio_net_config *dev_cfg;
 	void	    *virtio_user_dev;
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 393d4e9f84..6cfdfc63c2 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -671,6 +671,8 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
 	struct virtnet_rx *rxvq;
 	uint16_t rx_free_thresh;
+	uint16_t buf_size;
+	const char *error;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -679,6 +681,14 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
+	buf_size = virtio_rx_mem_pool_buf_size(mp);
+	if (!virtio_rx_check_scatter(hw->max_rx_pkt_len, buf_size,
+				     hw->rx_ol_scatter, &error)) {
+		PMD_INIT_LOG(ERR, "RxQ %u Rx scatter check failed: %s",
+			     queue_idx, error);
+		return -EINVAL;
+	}
+
 	rx_free_thresh = rx_conf->rx_free_thresh;
 	if (rx_free_thresh == 0)
 		rx_free_thresh =
-- 
2.30.2

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2021-07-26 13:53:17.140231475 +0100
+++ 0025-net-virtio-fix-Rx-scatter-offload.patch	2021-07-26 13:53:15.853292706 +0100
@@ -1 +1 @@
-From 4e8169eb0d2d34067f56b368633f816ce927650a Mon Sep 17 00:00:00 2001
+From a961df1650da104147df36cdf0c1f3bc567792e2 Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit 4e8169eb0d2d34067f56b368633f816ce927650a ]
+
@@ -12 +13,0 @@
-Cc: stable at dpdk.org
@@ -18 +18,0 @@
- drivers/net/virtio/virtio.h        |  2 +
@@ -20,0 +21 @@
+ drivers/net/virtio/virtio_pci.h    |  2 +
@@ -24,20 +24,0 @@
-diff --git a/drivers/net/virtio/virtio.h b/drivers/net/virtio/virtio.h
-index 2c987d19ab..525e2dad4c 100644
---- a/drivers/net/virtio/virtio.h
-+++ b/drivers/net/virtio/virtio.h
-@@ -167,6 +167,7 @@ struct virtio_hw {
- 	uint8_t started;
- 	uint8_t weak_barriers;
- 	uint8_t vlan_strip;
-+	bool rx_ol_scatter;
- 	uint8_t has_tx_offload;
- 	uint8_t has_rx_offload;
- 	uint8_t use_vec_rx;
-@@ -180,6 +181,7 @@ struct virtio_hw {
- 	uint8_t duplex;
- 	uint8_t intr_lsc;
- 	uint16_t max_mtu;
-+	size_t max_rx_pkt_len;
- 	/*
- 	 * App management thread and virtio interrupt handler thread
- 	 * both can change device state, this lock is meant to avoid
@@ -45 +26 @@
-index 0568305667..72d3dda71f 100644
+index 6c233b75ba..25810cc8db 100644
@@ -48 +29 @@
-@@ -841,6 +841,56 @@ virtio_dev_allmulticast_disable(struct rte_eth_dev *dev)
+@@ -867,6 +867,56 @@ virtio_dev_allmulticast_disable(struct rte_eth_dev *dev)
@@ -105 +86 @@
-@@ -858,6 +908,15 @@ virtio_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
+@@ -884,6 +934,15 @@ virtio_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
@@ -121 +102 @@
-@@ -2042,6 +2101,8 @@ virtio_dev_configure(struct rte_eth_dev *dev)
+@@ -2242,6 +2301,8 @@ virtio_dev_configure(struct rte_eth_dev *dev)
@@ -130 +111 @@
-@@ -2090,6 +2151,8 @@ virtio_dev_configure(struct rte_eth_dev *dev)
+@@ -2290,6 +2351,8 @@ virtio_dev_configure(struct rte_eth_dev *dev)
@@ -136,2 +117,2 @@
- 	if ((rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER) &&
- 			!virtio_with_feature(hw, VIRTIO_NET_F_CTRL_VLAN)) {
+ 	if ((rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
+ 	    && !vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VLAN)) {
@@ -139,2 +120,2 @@
-@@ -2445,6 +2508,8 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
- 	host_features = VIRTIO_OPS(hw)->get_features(hw);
+@@ -2635,6 +2698,8 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
+ 	host_features = VTPCI_OPS(hw)->get_features(hw);
@@ -149 +130 @@
-index 5a501e7890..2f63ef2b2d 100644
+index b7d52d497f..916ff11f7a 100644
@@ -152 +133 @@
-@@ -120,4 +120,9 @@ int virtio_dev_close(struct rte_eth_dev *dev);
+@@ -120,4 +120,9 @@ void virtio_dev_resume(struct rte_eth_dev *dev);
@@ -161,0 +143,20 @@
+diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
+index ab61e911b8..f56d3e8bb7 100644
+--- a/drivers/net/virtio/virtio_pci.h
++++ b/drivers/net/virtio/virtio_pci.h
+@@ -259,6 +259,7 @@ struct virtio_hw {
+ 	uint8_t     use_inorder_rx;
+ 	uint8_t     use_inorder_tx;
+ 	uint8_t     weak_barriers;
++	bool        rx_ol_scatter;
+ 	bool        has_tx_offload;
+ 	bool        has_rx_offload;
+ 	uint16_t    port_id;
+@@ -268,6 +269,7 @@ struct virtio_hw {
+ 	uint8_t     duplex;
+ 	uint8_t     *isr;
+ 	uint16_t    *notify_base;
++	size_t      max_rx_pkt_len;
+ 	struct virtio_pci_common_cfg *common_cfg;
+ 	struct virtio_net_config *dev_cfg;
+ 	void	    *virtio_user_dev;
@@ -163 +164 @@
-index f70644b0b7..d0365ce4bf 100644
+index 393d4e9f84..6cfdfc63c2 100644
@@ -166,2 +167,2 @@
-@@ -666,6 +666,8 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
- 	struct virtqueue *vq = hw->vqs[vq_idx];
+@@ -671,6 +671,8 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
+ 	struct virtqueue *vq = hw->vqs[vtpci_queue_idx];
@@ -175 +176 @@
-@@ -674,6 +676,14 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
+@@ -679,6 +681,14 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,


More information about the stable mailing list