All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/4] virtio-net: avoid XDP and _F_GUEST_CSUM
@ 2023-06-19 10:57 Heng Qi
  2023-06-19 10:57 ` [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum Heng Qi
                   ` (3 more replies)
  0 siblings, 4 replies; 22+ messages in thread
From: Heng Qi @ 2023-06-19 10:57 UTC (permalink / raw)
  To: netdev, bpf
  Cc: Michael S. Tsirkin, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

virtio-net needs to clear the VIRTIO_NET_F_GUEST_CSUM feature when
loading XDP. The main reason for doing this is because
VIRTIO_NET_F_GUEST_CSUM allows to receive packets marked as
VIRTIO_NET_HDR_F_NEEDS_CSUM. Such packets are not compatible with
XDP programs, because we cannot guarantee that the csum_{start, offset}
fields are correct after XDP modifies the packets.

There is also an existing problem, in the same host vm-vm (eg
[vm]<->[ovs vhost-user]<->[vm]) scenario, loading XDP will cause packet loss.

To solve the above problems, we have discussed in the [1] proposal, and
now try to solve it through the method of reprobing fields suggested
by Jason.

[1] https://lists.oasis-open.org/archives/virtio-dev/202305/msg00318.html

Heng Qi (4):
  virtio-net: a helper for probing the pseudo-header checksum
  virtio-net: reprobe csum related fields for skb passed by XDP
  virtio-net: virtio-net: support coexistence of XDP and _F_GUEST_CSUM
  virtio-net: remove F_GUEST_CSUM check for XDP loading

 drivers/net/virtio_net.c | 173 +++++++++++++++++++++++++++++++++++----
 1 file changed, 158 insertions(+), 15 deletions(-)

-- 
2.19.1.6.gb485710b


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum
  2023-06-19 10:57 [PATCH net-next 0/4] virtio-net: avoid XDP and _F_GUEST_CSUM Heng Qi
@ 2023-06-19 10:57 ` Heng Qi
  2023-06-19 12:30   ` kernel test robot
  2023-06-19 12:30   ` kernel test robot
  2023-06-19 10:57 ` [PATCH net-next 2/4] virtio-net: reprobe csum related fields for skb passed by XDP Heng Qi
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 22+ messages in thread
From: Heng Qi @ 2023-06-19 10:57 UTC (permalink / raw)
  To: netdev, bpf
  Cc: Michael S. Tsirkin, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

This helper parses UDP/TCP and calculates the pseudo-header checksum
for virtio-net.

virtio-net currently does not support insertion/deletion of VLANs nor
SCTP checksum offloading.

Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 95 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 5a7f7a76b920..36cae78f6311 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1568,6 +1568,101 @@ static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash,
 	skb_set_hash(skb, __le32_to_cpu(hdr_hash->hash_value), rss_hash_type);
 }
 
+static int virtnet_flow_dissect_udp_tcp(struct virtnet_info *vi, struct sk_buff *skb)
+{
+	struct net_device *dev = vi->dev;
+	struct flow_keys_basic keys;
+	struct udphdr *uh;
+	struct tcphdr *th;
+	int len, offset;
+
+	/* The flow dissector needs this information. */
+	skb->dev = dev;
+	skb_reset_mac_header(skb);
+	skb->protocol = dev_parse_header_protocol(skb);
+	/* virtio-net does not need to resolve VLAN. */
+	skb_set_network_header(skb, ETH_HLEN);
+	if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
+					      NULL, 0, 0, 0, 0))
+		return -EINVAL;
+
+	/* 1. Pseudo-header checksum calculation requires:
+	 *    (1) saddr/daddr (2) IP_PROTO (3) length of transport payload
+	 * 2. We don't parse SCTP because virtio-net currently doesn't
+	 *    support CRC offloading for SCTP.
+	 */
+	if (keys.basic.n_proto == htons(ETH_P_IP)) {
+		struct iphdr *iph;
+
+		/* Flow dissector has verified that there is an IP header. */
+		iph = ip_hdr(skb);
+		if (iph->version != 4 || !pskb_may_pull(skb, iph->ihl * 4))
+			return -EINVAL;
+
+		skb->transport_header = skb->mac_header + keys.control.thoff;
+		offset = skb_transport_offset(skb);
+		len = skb->len - offset;
+		if (keys.basic.ip_proto == IPPROTO_UDP) {
+			if (!pskb_may_pull(skb, offset + sizeof(struct udphdr)))
+				return -EINVAL;
+
+			uh = udp_hdr(skb);
+			skb->csum_offset = offsetof(struct udphdr, check);
+			/* Although uh->len is already the 3rd parameter for the calculation
+			 * of the pseudo-header checksum, we have already calculated the
+			 * length of the transport layer, so use 'len' here directly.
+			 */
+			uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, len,
+					IPPROTO_UDP, 0);
+		} else if (keys.basic.ip_proto == IPPROTO_TCP) {
+			if (!pskb_may_pull(skb, offset + sizeof(struct tcphdr)))
+				return -EINVAL;
+
+			th = tcp_hdr(skb);
+			skb->csum_offset = offsetof(struct tcphdr, check);
+			th->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, len,
+					IPPROTO_TCP, 0);
+		} /* virtio-net doesn't support checksums for SCTP hw offloading.*/
+	} else if (keys.basic.n_proto == htons(ETH_P_IPV6)) {
+		struct ipv6hdr *ip6h;
+
+		ip6h = ipv6_hdr(skb);
+		if (ip6h->version != 6)
+			return -EINVAL;
+
+		/* We have skipped the possible extension headers for IPv6.
+		 * If there is a Routing Header, the tx's check value is calculated by
+		 * final_dst, and that value is the rx's daddr.
+		 */
+		skb->transport_header = skb->mac_header + keys.control.thoff;
+		offset = skb_transport_offset(skb);
+		len = skb->len - offset;
+		if (keys.basic.ip_proto == IPPROTO_UDP) {
+			if (!pskb_may_pull(skb, offset + sizeof(struct udphdr)))
+				return -EINVAL;
+
+			uh = udp_hdr(skb);
+			skb->csum_offset = offsetof(struct udphdr, check);
+			uh->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr,
+					(const struct in6_addr *)&ip6h->daddr,
+					len, IPPROTO_UDP, 0);
+		} else if (keys.basic.ip_proto == IPPROTO_TCP) {
+			if (!pskb_may_pull(skb, offset + sizeof(struct tcphdr)))
+				return -EINVAL;
+
+			th = tcp_hdr(skb);
+			skb->csum_offset = offsetof(struct tcphdr, check);
+			th->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr,
+					(const struct in6_addr *)&ip6h->daddr,
+					len, IPPROTO_TCP, 0);
+		}
+	}
+
+	skb->csum_start = skb->transport_header;
+
+	return 0;
+}
+
 static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
 			void *buf, unsigned int len, void **ctx,
 			unsigned int *xdp_xmit,
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 2/4] virtio-net: reprobe csum related fields for skb passed by XDP
  2023-06-19 10:57 [PATCH net-next 0/4] virtio-net: avoid XDP and _F_GUEST_CSUM Heng Qi
  2023-06-19 10:57 ` [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum Heng Qi
@ 2023-06-19 10:57 ` Heng Qi
  2023-06-19 11:27   ` Michael S. Tsirkin
  2023-06-19 13:32   ` kernel test robot
  2023-06-19 10:57 ` [PATCH net-next 3/4] virtio-net: support coexistence of XDP and _F_GUEST_CSUM Heng Qi
  2023-06-19 10:57 ` [PATCH net-next 4/4] virtio-net: remove F_GUEST_CSUM check for XDP loading Heng Qi
  3 siblings, 2 replies; 22+ messages in thread
From: Heng Qi @ 2023-06-19 10:57 UTC (permalink / raw)
  To: netdev, bpf
  Cc: Michael S. Tsirkin, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

Currently, the VIRTIO_NET_F_GUEST_CSUM (corresponds to NETIF_F_RXCSUM
for netdev) feature of the virtio-net driver conflicts with the loading
of XDP, which is caused by the problem described in [1][2], that is,
XDP may cause errors in partial csumed-related fields which can lead
to packet dropping.

In addition, when communicating between vm and vm on the same host, the
receiving side vm will receive packets marked as
VIRTIO_NET_HDR_F_NEEDS_CSUM, but after these packets are processed by
XDP, the VIRTIO_NET_HDR_F_NEEDS_CSUM and skb CHECKSUM_PARTIAL flags will
be cleared, causing the packet dropping.

This patch introduces a helper function, which will try to solve the
above problems in the subsequent patch.

[1] commit 18ba58e1c234 ("virtio-net: fail XDP set if guest csum is negotiated")
[2] commit e59ff2c49ae1 ("virtio-net: disable guest csum during XDP set")

Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 36cae78f6311..07b4801d689c 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1663,6 +1663,44 @@ static int virtnet_flow_dissect_udp_tcp(struct virtnet_info *vi, struct sk_buff
 	return 0;
 }
 
+static int virtnet_set_csum_after_xdp(struct virtnet_info *vi,
+				      struct sk_buff *skb,
+				      __u8 flags)
+{
+	int err;
+
+	/* When XDP program is loaded, for example, the vm-vm scenario
+	 * on the same host, packets marked as VIRTIO_NET_HDR_F_NEEDS_CSUM
+	 * will travel. Although these packets are safe from the point of
+	 * view of the vm, to avoid modification by XDP and successful
+	 * forwarding in the upper layer, we re-probe the necessary checksum
+	 * related information: skb->csum_{start, offset}, pseudo-header csum.
+	 *
+	 * This benefits us:
+	 * 1. XDP can be loaded when there's _F_GUEST_CSUM.
+	 * 2. The device verifies the checksum of packets , especially
+	 *    benefiting for large packets.
+	 * 3. In the same-host vm-vm scenario, packets marked as
+	 *    VIRTIO_NET_HDR_F_NEEDS_CSUM are no longer dropped after being
+	 *    processed by XDP.
+	 */
+	if (flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+		err = virtnet_flow_dissect_udp_tcp(vi, skb);
+		if (err < 0)
+			return -EINVAL;
+
+		skb->ip_summed = CHECKSUM_PARTIAL;
+	} else if (flags && VIRTIO_NET_HDR_F_DATA_VALID) {
+		/* We want to benefit from this: XDP guarantees that packets marked
+		 * as VIRTIO_NET_HDR_F_DATA_VALID still have correct csum after they
+		 * are processed.
+		 */
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	}
+
+	return 0;
+}
+
 static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
 			void *buf, unsigned int len, void **ctx,
 			unsigned int *xdp_xmit,
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 3/4] virtio-net: support coexistence of XDP and _F_GUEST_CSUM
  2023-06-19 10:57 [PATCH net-next 0/4] virtio-net: avoid XDP and _F_GUEST_CSUM Heng Qi
  2023-06-19 10:57 ` [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum Heng Qi
  2023-06-19 10:57 ` [PATCH net-next 2/4] virtio-net: reprobe csum related fields for skb passed by XDP Heng Qi
@ 2023-06-19 10:57 ` Heng Qi
  2023-06-19 11:26   ` Michael S. Tsirkin
  2023-06-19 10:57 ` [PATCH net-next 4/4] virtio-net: remove F_GUEST_CSUM check for XDP loading Heng Qi
  3 siblings, 1 reply; 22+ messages in thread
From: Heng Qi @ 2023-06-19 10:57 UTC (permalink / raw)
  To: netdev, bpf
  Cc: Michael S. Tsirkin, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

We are now re-probing the csum related fields and  trying
to have XDP and RX hw checksum capabilities coexist on the
XDP path. For the benefit of:
1. RX hw checksum capability can be used if XDP is loaded.
2. Avoid packet loss when loading XDP in the vm-vm scenario.

Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 07b4801d689c..25b486ab74db 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1709,6 +1709,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
 	struct net_device *dev = vi->dev;
 	struct sk_buff *skb;
 	struct virtio_net_hdr_mrg_rxbuf *hdr;
+	__u8 flags;
 
 	if (unlikely(len < vi->hdr_len + ETH_HLEN)) {
 		pr_debug("%s: short packet %i\n", dev->name, len);
@@ -1717,6 +1718,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
 		return;
 	}
 
+	flags = ((struct virtio_net_hdr_mrg_rxbuf *)buf)->hdr.flags;
+
 	if (vi->mergeable_rx_bufs)
 		skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
 					stats);
@@ -1728,19 +1731,28 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
 	if (unlikely(!skb))
 		return;
 
-	hdr = skb_vnet_hdr(skb);
-	if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report)
-		virtio_skb_set_hash((const struct virtio_net_hdr_v1_hash *)hdr, skb);
-
-	if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID)
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	if (unlikely(vi->xdp_enabled)) {
+		if (virtnet_set_csum_after_xdp(vi, skb, flags) < 0) {
+			pr_debug("%s: errors occurred in flow dissector setting csum",
+				 dev->name);
+			goto frame_err;
+		}
 
-	if (virtio_net_hdr_to_skb(skb, &hdr->hdr,
-				  virtio_is_little_endian(vi->vdev))) {
-		net_warn_ratelimited("%s: bad gso: type: %u, size: %u\n",
-				     dev->name, hdr->hdr.gso_type,
-				     hdr->hdr.gso_size);
-		goto frame_err;
+	} else {
+		hdr = skb_vnet_hdr(skb);
+		if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report)
+			virtio_skb_set_hash((const struct virtio_net_hdr_v1_hash *)hdr, skb);
+
+		if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID)
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+		if (virtio_net_hdr_to_skb(skb, &hdr->hdr,
+					  virtio_is_little_endian(vi->vdev))) {
+			net_warn_ratelimited("%s: bad gso: type: %u, size: %u\n",
+					     dev->name, hdr->hdr.gso_type,
+					     hdr->hdr.gso_size);
+			goto frame_err;
+		}
 	}
 
 	skb_record_rx_queue(skb, vq2rxq(rq->vq));
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 4/4] virtio-net: remove F_GUEST_CSUM check for XDP loading
  2023-06-19 10:57 [PATCH net-next 0/4] virtio-net: avoid XDP and _F_GUEST_CSUM Heng Qi
                   ` (2 preceding siblings ...)
  2023-06-19 10:57 ` [PATCH net-next 3/4] virtio-net: support coexistence of XDP and _F_GUEST_CSUM Heng Qi
@ 2023-06-19 10:57 ` Heng Qi
  2023-06-19 11:16   ` Michael S. Tsirkin
  3 siblings, 1 reply; 22+ messages in thread
From: Heng Qi @ 2023-06-19 10:57 UTC (permalink / raw)
  To: netdev, bpf
  Cc: Michael S. Tsirkin, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

Lay the foundation for the subsequent patch to complete the coexistence
of XDP and virtio-net guest csum.

Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 25b486ab74db..79471de64b56 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -60,7 +60,6 @@ static const unsigned long guest_offloads[] = {
 	VIRTIO_NET_F_GUEST_TSO6,
 	VIRTIO_NET_F_GUEST_ECN,
 	VIRTIO_NET_F_GUEST_UFO,
-	VIRTIO_NET_F_GUEST_CSUM,
 	VIRTIO_NET_F_GUEST_USO4,
 	VIRTIO_NET_F_GUEST_USO6,
 	VIRTIO_NET_F_GUEST_HDRLEN
@@ -3522,10 +3521,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
 	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) ||
 	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||
 		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) ||
-		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM) ||
 		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO4) ||
 		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO6))) {
-		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first");
+		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW, disable GRO_HW first");
 		return -EOPNOTSUPP;
 	}
 
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 4/4] virtio-net: remove F_GUEST_CSUM check for XDP loading
  2023-06-19 10:57 ` [PATCH net-next 4/4] virtio-net: remove F_GUEST_CSUM check for XDP loading Heng Qi
@ 2023-06-19 11:16   ` Michael S. Tsirkin
  2023-06-19 12:41     ` Heng Qi
  0 siblings, 1 reply; 22+ messages in thread
From: Michael S. Tsirkin @ 2023-06-19 11:16 UTC (permalink / raw)
  To: Heng Qi
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Mon, Jun 19, 2023 at 06:57:38PM +0800, Heng Qi wrote:
> Lay the foundation for the subsequent patch

which subsequent patch? this is the last one in series.

> to complete the coexistence
> of XDP and virtio-net guest csum.
> 
> Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> ---
>  drivers/net/virtio_net.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 25b486ab74db..79471de64b56 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -60,7 +60,6 @@ static const unsigned long guest_offloads[] = {
>  	VIRTIO_NET_F_GUEST_TSO6,
>  	VIRTIO_NET_F_GUEST_ECN,
>  	VIRTIO_NET_F_GUEST_UFO,
> -	VIRTIO_NET_F_GUEST_CSUM,
>  	VIRTIO_NET_F_GUEST_USO4,
>  	VIRTIO_NET_F_GUEST_USO6,
>  	VIRTIO_NET_F_GUEST_HDRLEN

What is this doing? Drop support for VIRTIO_NET_F_GUEST_CSUM? Why?
This will disable all of guest offloads I think ..


> @@ -3522,10 +3521,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
>  	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) ||
>  	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||
>  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) ||
> -		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM) ||
>  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO4) ||
>  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO6))) {
> -		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first");
> +		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW, disable GRO_HW first");
>  		return -EOPNOTSUPP;
>  	}
>  
> -- 
> 2.19.1.6.gb485710b


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 3/4] virtio-net: support coexistence of XDP and _F_GUEST_CSUM
  2023-06-19 10:57 ` [PATCH net-next 3/4] virtio-net: support coexistence of XDP and _F_GUEST_CSUM Heng Qi
@ 2023-06-19 11:26   ` Michael S. Tsirkin
  2023-06-19 12:31     ` Heng Qi
  2023-06-20  3:24     ` Heng Qi
  0 siblings, 2 replies; 22+ messages in thread
From: Michael S. Tsirkin @ 2023-06-19 11:26 UTC (permalink / raw)
  To: Heng Qi
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Mon, Jun 19, 2023 at 06:57:37PM +0800, Heng Qi wrote:
> We are now re-probing the csum related fields and  trying
> to have XDP and RX hw checksum capabilities coexist on the
> XDP path. For the benefit of:
> 1. RX hw checksum capability can be used if XDP is loaded.
> 2. Avoid packet loss when loading XDP in the vm-vm scenario.
> 
> Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> ---
>  drivers/net/virtio_net.c | 36 ++++++++++++++++++++++++------------
>  1 file changed, 24 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 07b4801d689c..25b486ab74db 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1709,6 +1709,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
>  	struct net_device *dev = vi->dev;
>  	struct sk_buff *skb;
>  	struct virtio_net_hdr_mrg_rxbuf *hdr;
> +	__u8 flags;
>  
>  	if (unlikely(len < vi->hdr_len + ETH_HLEN)) {
>  		pr_debug("%s: short packet %i\n", dev->name, len);
> @@ -1717,6 +1718,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
>  		return;
>  	}
>  
> +	flags = ((struct virtio_net_hdr_mrg_rxbuf *)buf)->hdr.flags;
> +
>  	if (vi->mergeable_rx_bufs)
>  		skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
>  					stats);

what's going on here?

> @@ -1728,19 +1731,28 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
>  	if (unlikely(!skb))
>  		return;
>  
> -	hdr = skb_vnet_hdr(skb);
> -	if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report)
> -		virtio_skb_set_hash((const struct virtio_net_hdr_v1_hash *)hdr, skb);
> -
> -	if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID)
> -		skb->ip_summed = CHECKSUM_UNNECESSARY;
> +	if (unlikely(vi->xdp_enabled)) {
> +		if (virtnet_set_csum_after_xdp(vi, skb, flags) < 0) {
> +			pr_debug("%s: errors occurred in flow dissector setting csum",
> +				 dev->name);
> +			goto frame_err;
> +		}
>  
> -	if (virtio_net_hdr_to_skb(skb, &hdr->hdr,
> -				  virtio_is_little_endian(vi->vdev))) {
> -		net_warn_ratelimited("%s: bad gso: type: %u, size: %u\n",
> -				     dev->name, hdr->hdr.gso_type,
> -				     hdr->hdr.gso_size);
> -		goto frame_err;
> +	} else {
> +		hdr = skb_vnet_hdr(skb);
> +		if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report)
> +			virtio_skb_set_hash((const struct virtio_net_hdr_v1_hash *)hdr, skb);
> +
> +		if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID)
> +			skb->ip_summed = CHECKSUM_UNNECESSARY;
> +
> +		if (virtio_net_hdr_to_skb(skb, &hdr->hdr,
> +					  virtio_is_little_endian(vi->vdev))) {
> +			net_warn_ratelimited("%s: bad gso: type: %u, size: %u\n",
> +					     dev->name, hdr->hdr.gso_type,
> +					     hdr->hdr.gso_size);
> +			goto frame_err;
> +		}
>  	}
>  
>  	skb_record_rx_queue(skb, vq2rxq(rq->vq));
> -- 
> 2.19.1.6.gb485710b


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 2/4] virtio-net: reprobe csum related fields for skb passed by XDP
  2023-06-19 10:57 ` [PATCH net-next 2/4] virtio-net: reprobe csum related fields for skb passed by XDP Heng Qi
@ 2023-06-19 11:27   ` Michael S. Tsirkin
  2023-06-19 12:29     ` Heng Qi
  2023-06-19 13:32   ` kernel test robot
  1 sibling, 1 reply; 22+ messages in thread
From: Michael S. Tsirkin @ 2023-06-19 11:27 UTC (permalink / raw)
  To: Heng Qi
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Mon, Jun 19, 2023 at 06:57:36PM +0800, Heng Qi wrote:
> Currently, the VIRTIO_NET_F_GUEST_CSUM (corresponds to NETIF_F_RXCSUM
> for netdev) feature of the virtio-net driver conflicts with the loading
> of XDP, which is caused by the problem described in [1][2], that is,
> XDP may cause errors in partial csumed-related fields which can lead
> to packet dropping.
> 
> In addition, when communicating between vm and vm on the same host, the
> receiving side vm will receive packets marked as
> VIRTIO_NET_HDR_F_NEEDS_CSUM, but after these packets are processed by
> XDP, the VIRTIO_NET_HDR_F_NEEDS_CSUM and skb CHECKSUM_PARTIAL flags will
> be cleared, causing the packet dropping.
> 
> This patch introduces a helper function, which will try to solve the
> above problems in the subsequent patch.
> 
> [1] commit 18ba58e1c234 ("virtio-net: fail XDP set if guest csum is negotiated")
> [2] commit e59ff2c49ae1 ("virtio-net: disable guest csum during XDP set")
> 
> Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>


squash this and patch 1 into where the helpers are used.

in particular so we don't get warnings with bisect.

> ---
>  drivers/net/virtio_net.c | 38 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 36cae78f6311..07b4801d689c 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1663,6 +1663,44 @@ static int virtnet_flow_dissect_udp_tcp(struct virtnet_info *vi, struct sk_buff
>  	return 0;
>  }
>  
> +static int virtnet_set_csum_after_xdp(struct virtnet_info *vi,
> +				      struct sk_buff *skb,
> +				      __u8 flags)
> +{
> +	int err;
> +
> +	/* When XDP program is loaded, for example, the vm-vm scenario
> +	 * on the same host, packets marked as VIRTIO_NET_HDR_F_NEEDS_CSUM
> +	 * will travel. Although these packets are safe from the point of
> +	 * view of the vm, to avoid modification by XDP and successful
> +	 * forwarding in the upper layer, we re-probe the necessary checksum
> +	 * related information: skb->csum_{start, offset}, pseudo-header csum.
> +	 *
> +	 * This benefits us:
> +	 * 1. XDP can be loaded when there's _F_GUEST_CSUM.
> +	 * 2. The device verifies the checksum of packets , especially
> +	 *    benefiting for large packets.
> +	 * 3. In the same-host vm-vm scenario, packets marked as
> +	 *    VIRTIO_NET_HDR_F_NEEDS_CSUM are no longer dropped after being
> +	 *    processed by XDP.
> +	 */
> +	if (flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
> +		err = virtnet_flow_dissect_udp_tcp(vi, skb);
> +		if (err < 0)
> +			return -EINVAL;
> +
> +		skb->ip_summed = CHECKSUM_PARTIAL;
> +	} else if (flags && VIRTIO_NET_HDR_F_DATA_VALID) {
> +		/* We want to benefit from this: XDP guarantees that packets marked
> +		 * as VIRTIO_NET_HDR_F_DATA_VALID still have correct csum after they
> +		 * are processed.
> +		 */
> +		skb->ip_summed = CHECKSUM_UNNECESSARY;
> +	}
> +
> +	return 0;
> +}
> +
>  static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
>  			void *buf, unsigned int len, void **ctx,
>  			unsigned int *xdp_xmit,
> -- 
> 2.19.1.6.gb485710b


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 2/4] virtio-net: reprobe csum related fields for skb passed by XDP
  2023-06-19 11:27   ` Michael S. Tsirkin
@ 2023-06-19 12:29     ` Heng Qi
  0 siblings, 0 replies; 22+ messages in thread
From: Heng Qi @ 2023-06-19 12:29 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Mon, Jun 19, 2023 at 07:27:26AM -0400, Michael S. Tsirkin wrote:
> On Mon, Jun 19, 2023 at 06:57:36PM +0800, Heng Qi wrote:
> > Currently, the VIRTIO_NET_F_GUEST_CSUM (corresponds to NETIF_F_RXCSUM
> > for netdev) feature of the virtio-net driver conflicts with the loading
> > of XDP, which is caused by the problem described in [1][2], that is,
> > XDP may cause errors in partial csumed-related fields which can lead
> > to packet dropping.
> > 
> > In addition, when communicating between vm and vm on the same host, the
> > receiving side vm will receive packets marked as
> > VIRTIO_NET_HDR_F_NEEDS_CSUM, but after these packets are processed by
> > XDP, the VIRTIO_NET_HDR_F_NEEDS_CSUM and skb CHECKSUM_PARTIAL flags will
> > be cleared, causing the packet dropping.
> > 
> > This patch introduces a helper function, which will try to solve the
> > above problems in the subsequent patch.
> > 
> > [1] commit 18ba58e1c234 ("virtio-net: fail XDP set if guest csum is negotiated")
> > [2] commit e59ff2c49ae1 ("virtio-net: disable guest csum during XDP set")
> > 
> > Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> > Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> 
> 
> squash this and patch 1 into where the helpers are used.
> 
> in particular so we don't get warnings with bisect.

Ok. Will modify.

Thanks.

> 
> > ---
> >  drivers/net/virtio_net.c | 38 ++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> > 
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index 36cae78f6311..07b4801d689c 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -1663,6 +1663,44 @@ static int virtnet_flow_dissect_udp_tcp(struct virtnet_info *vi, struct sk_buff
> >  	return 0;
> >  }
> >  
> > +static int virtnet_set_csum_after_xdp(struct virtnet_info *vi,
> > +				      struct sk_buff *skb,
> > +				      __u8 flags)
> > +{
> > +	int err;
> > +
> > +	/* When XDP program is loaded, for example, the vm-vm scenario
> > +	 * on the same host, packets marked as VIRTIO_NET_HDR_F_NEEDS_CSUM
> > +	 * will travel. Although these packets are safe from the point of
> > +	 * view of the vm, to avoid modification by XDP and successful
> > +	 * forwarding in the upper layer, we re-probe the necessary checksum
> > +	 * related information: skb->csum_{start, offset}, pseudo-header csum.
> > +	 *
> > +	 * This benefits us:
> > +	 * 1. XDP can be loaded when there's _F_GUEST_CSUM.
> > +	 * 2. The device verifies the checksum of packets , especially
> > +	 *    benefiting for large packets.
> > +	 * 3. In the same-host vm-vm scenario, packets marked as
> > +	 *    VIRTIO_NET_HDR_F_NEEDS_CSUM are no longer dropped after being
> > +	 *    processed by XDP.
> > +	 */
> > +	if (flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
> > +		err = virtnet_flow_dissect_udp_tcp(vi, skb);
> > +		if (err < 0)
> > +			return -EINVAL;
> > +
> > +		skb->ip_summed = CHECKSUM_PARTIAL;
> > +	} else if (flags && VIRTIO_NET_HDR_F_DATA_VALID) {
> > +		/* We want to benefit from this: XDP guarantees that packets marked
> > +		 * as VIRTIO_NET_HDR_F_DATA_VALID still have correct csum after they
> > +		 * are processed.
> > +		 */
> > +		skb->ip_summed = CHECKSUM_UNNECESSARY;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> >  			void *buf, unsigned int len, void **ctx,
> >  			unsigned int *xdp_xmit,
> > -- 
> > 2.19.1.6.gb485710b

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum
  2023-06-19 10:57 ` [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum Heng Qi
@ 2023-06-19 12:30   ` kernel test robot
  2023-06-19 12:30   ` kernel test robot
  1 sibling, 0 replies; 22+ messages in thread
From: kernel test robot @ 2023-06-19 12:30 UTC (permalink / raw)
  To: Heng Qi, netdev, bpf
  Cc: llvm, oe-kbuild-all, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

Hi Heng,

kernel test robot noticed the following build errors:

[auto build test ERROR on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Heng-Qi/virtio-net-a-helper-for-probing-the-pseudo-header-checksum/20230619-190212
base:   net-next/main
patch link:    https://lore.kernel.org/r/20230619105738.117733-2-hengqi%40linux.alibaba.com
patch subject: [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum
config: x86_64-randconfig-r014-20230619 (https://download.01.org/0day-ci/archive/20230619/202306192049.8y7DR5F1-lkp@intel.com/config)
compiler: clang version 15.0.7 (https://github.com/llvm/llvm-project.git 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a)
reproduce: (https://download.01.org/0day-ci/archive/20230619/202306192049.8y7DR5F1-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202306192049.8y7DR5F1-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/net/virtio_net.c:1648:17: error: call to undeclared function 'csum_ipv6_magic'; ISO C99 and later do not support implicit function declarations [-Werror,-Wimplicit-function-declaration]
                           uh->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr,
                                        ^
   drivers/net/virtio_net.c:1648:17: note: did you mean 'csum_tcpudp_magic'?
   include/asm-generic/checksum.h:52:1: note: 'csum_tcpudp_magic' declared here
   csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
   ^
   drivers/net/virtio_net.c:1657:17: error: call to undeclared function 'csum_ipv6_magic'; ISO C99 and later do not support implicit function declarations [-Werror,-Wimplicit-function-declaration]
                           th->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr,
                                        ^
   2 errors generated.


vim +/csum_ipv6_magic +1648 drivers/net/virtio_net.c

  1572	
  1573	static int virtnet_flow_dissect_udp_tcp(struct virtnet_info *vi, struct sk_buff *skb)
  1574	{
  1575		struct net_device *dev = vi->dev;
  1576		struct flow_keys_basic keys;
  1577		struct udphdr *uh;
  1578		struct tcphdr *th;
  1579		int len, offset;
  1580	
  1581		/* The flow dissector needs this information. */
  1582		skb->dev = dev;
  1583		skb_reset_mac_header(skb);
  1584		skb->protocol = dev_parse_header_protocol(skb);
  1585		/* virtio-net does not need to resolve VLAN. */
  1586		skb_set_network_header(skb, ETH_HLEN);
  1587		if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
  1588						      NULL, 0, 0, 0, 0))
  1589			return -EINVAL;
  1590	
  1591		/* 1. Pseudo-header checksum calculation requires:
  1592		 *    (1) saddr/daddr (2) IP_PROTO (3) length of transport payload
  1593		 * 2. We don't parse SCTP because virtio-net currently doesn't
  1594		 *    support CRC offloading for SCTP.
  1595		 */
  1596		if (keys.basic.n_proto == htons(ETH_P_IP)) {
  1597			struct iphdr *iph;
  1598	
  1599			/* Flow dissector has verified that there is an IP header. */
  1600			iph = ip_hdr(skb);
  1601			if (iph->version != 4 || !pskb_may_pull(skb, iph->ihl * 4))
  1602				return -EINVAL;
  1603	
  1604			skb->transport_header = skb->mac_header + keys.control.thoff;
  1605			offset = skb_transport_offset(skb);
  1606			len = skb->len - offset;
  1607			if (keys.basic.ip_proto == IPPROTO_UDP) {
  1608				if (!pskb_may_pull(skb, offset + sizeof(struct udphdr)))
  1609					return -EINVAL;
  1610	
  1611				uh = udp_hdr(skb);
  1612				skb->csum_offset = offsetof(struct udphdr, check);
  1613				/* Although uh->len is already the 3rd parameter for the calculation
  1614				 * of the pseudo-header checksum, we have already calculated the
  1615				 * length of the transport layer, so use 'len' here directly.
  1616				 */
  1617				uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, len,
  1618						IPPROTO_UDP, 0);
  1619			} else if (keys.basic.ip_proto == IPPROTO_TCP) {
  1620				if (!pskb_may_pull(skb, offset + sizeof(struct tcphdr)))
  1621					return -EINVAL;
  1622	
  1623				th = tcp_hdr(skb);
  1624				skb->csum_offset = offsetof(struct tcphdr, check);
  1625				th->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, len,
  1626						IPPROTO_TCP, 0);
  1627			} /* virtio-net doesn't support checksums for SCTP hw offloading.*/
  1628		} else if (keys.basic.n_proto == htons(ETH_P_IPV6)) {
  1629			struct ipv6hdr *ip6h;
  1630	
  1631			ip6h = ipv6_hdr(skb);
  1632			if (ip6h->version != 6)
  1633				return -EINVAL;
  1634	
  1635			/* We have skipped the possible extension headers for IPv6.
  1636			 * If there is a Routing Header, the tx's check value is calculated by
  1637			 * final_dst, and that value is the rx's daddr.
  1638			 */
  1639			skb->transport_header = skb->mac_header + keys.control.thoff;
  1640			offset = skb_transport_offset(skb);
  1641			len = skb->len - offset;
  1642			if (keys.basic.ip_proto == IPPROTO_UDP) {
  1643				if (!pskb_may_pull(skb, offset + sizeof(struct udphdr)))
  1644					return -EINVAL;
  1645	
  1646				uh = udp_hdr(skb);
  1647				skb->csum_offset = offsetof(struct udphdr, check);
> 1648				uh->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr,
  1649						(const struct in6_addr *)&ip6h->daddr,
  1650						len, IPPROTO_UDP, 0);
  1651			} else if (keys.basic.ip_proto == IPPROTO_TCP) {
  1652				if (!pskb_may_pull(skb, offset + sizeof(struct tcphdr)))
  1653					return -EINVAL;
  1654	
  1655				th = tcp_hdr(skb);
  1656				skb->csum_offset = offsetof(struct tcphdr, check);
  1657				th->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr,
  1658						(const struct in6_addr *)&ip6h->daddr,
  1659						len, IPPROTO_TCP, 0);
  1660			}
  1661		}
  1662	
  1663		skb->csum_start = skb->transport_header;
  1664	
  1665		return 0;
  1666	}
  1667	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum
  2023-06-19 10:57 ` [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum Heng Qi
  2023-06-19 12:30   ` kernel test robot
@ 2023-06-19 12:30   ` kernel test robot
  1 sibling, 0 replies; 22+ messages in thread
From: kernel test robot @ 2023-06-19 12:30 UTC (permalink / raw)
  To: Heng Qi, netdev, bpf
  Cc: oe-kbuild-all, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

Hi Heng,

kernel test robot noticed the following build errors:

[auto build test ERROR on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Heng-Qi/virtio-net-a-helper-for-probing-the-pseudo-header-checksum/20230619-190212
base:   net-next/main
patch link:    https://lore.kernel.org/r/20230619105738.117733-2-hengqi%40linux.alibaba.com
patch subject: [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum
config: m68k-randconfig-r021-20230619 (https://download.01.org/0day-ci/archive/20230619/202306192049.l2eaZ7od-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230619/202306192049.l2eaZ7od-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202306192049.l2eaZ7od-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/net/virtio_net.c: In function 'virtnet_flow_dissect_udp_tcp':
>> drivers/net/virtio_net.c:1648:38: error: implicit declaration of function 'csum_ipv6_magic'; did you mean 'csum_tcpudp_magic'? [-Werror=implicit-function-declaration]
    1648 |                         uh->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr,
         |                                      ^~~~~~~~~~~~~~~
         |                                      csum_tcpudp_magic
   drivers/net/virtio_net.c: At top level:
   drivers/net/virtio_net.c:1573:12: warning: 'virtnet_flow_dissect_udp_tcp' defined but not used [-Wunused-function]
    1573 | static int virtnet_flow_dissect_udp_tcp(struct virtnet_info *vi, struct sk_buff *skb)
         |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +1648 drivers/net/virtio_net.c

  1572	
  1573	static int virtnet_flow_dissect_udp_tcp(struct virtnet_info *vi, struct sk_buff *skb)
  1574	{
  1575		struct net_device *dev = vi->dev;
  1576		struct flow_keys_basic keys;
  1577		struct udphdr *uh;
  1578		struct tcphdr *th;
  1579		int len, offset;
  1580	
  1581		/* The flow dissector needs this information. */
  1582		skb->dev = dev;
  1583		skb_reset_mac_header(skb);
  1584		skb->protocol = dev_parse_header_protocol(skb);
  1585		/* virtio-net does not need to resolve VLAN. */
  1586		skb_set_network_header(skb, ETH_HLEN);
  1587		if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
  1588						      NULL, 0, 0, 0, 0))
  1589			return -EINVAL;
  1590	
  1591		/* 1. Pseudo-header checksum calculation requires:
  1592		 *    (1) saddr/daddr (2) IP_PROTO (3) length of transport payload
  1593		 * 2. We don't parse SCTP because virtio-net currently doesn't
  1594		 *    support CRC offloading for SCTP.
  1595		 */
  1596		if (keys.basic.n_proto == htons(ETH_P_IP)) {
  1597			struct iphdr *iph;
  1598	
  1599			/* Flow dissector has verified that there is an IP header. */
  1600			iph = ip_hdr(skb);
  1601			if (iph->version != 4 || !pskb_may_pull(skb, iph->ihl * 4))
  1602				return -EINVAL;
  1603	
  1604			skb->transport_header = skb->mac_header + keys.control.thoff;
  1605			offset = skb_transport_offset(skb);
  1606			len = skb->len - offset;
  1607			if (keys.basic.ip_proto == IPPROTO_UDP) {
  1608				if (!pskb_may_pull(skb, offset + sizeof(struct udphdr)))
  1609					return -EINVAL;
  1610	
  1611				uh = udp_hdr(skb);
  1612				skb->csum_offset = offsetof(struct udphdr, check);
  1613				/* Although uh->len is already the 3rd parameter for the calculation
  1614				 * of the pseudo-header checksum, we have already calculated the
  1615				 * length of the transport layer, so use 'len' here directly.
  1616				 */
  1617				uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, len,
  1618						IPPROTO_UDP, 0);
  1619			} else if (keys.basic.ip_proto == IPPROTO_TCP) {
  1620				if (!pskb_may_pull(skb, offset + sizeof(struct tcphdr)))
  1621					return -EINVAL;
  1622	
  1623				th = tcp_hdr(skb);
  1624				skb->csum_offset = offsetof(struct tcphdr, check);
  1625				th->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, len,
  1626						IPPROTO_TCP, 0);
  1627			} /* virtio-net doesn't support checksums for SCTP hw offloading.*/
  1628		} else if (keys.basic.n_proto == htons(ETH_P_IPV6)) {
  1629			struct ipv6hdr *ip6h;
  1630	
  1631			ip6h = ipv6_hdr(skb);
  1632			if (ip6h->version != 6)
  1633				return -EINVAL;
  1634	
  1635			/* We have skipped the possible extension headers for IPv6.
  1636			 * If there is a Routing Header, the tx's check value is calculated by
  1637			 * final_dst, and that value is the rx's daddr.
  1638			 */
  1639			skb->transport_header = skb->mac_header + keys.control.thoff;
  1640			offset = skb_transport_offset(skb);
  1641			len = skb->len - offset;
  1642			if (keys.basic.ip_proto == IPPROTO_UDP) {
  1643				if (!pskb_may_pull(skb, offset + sizeof(struct udphdr)))
  1644					return -EINVAL;
  1645	
  1646				uh = udp_hdr(skb);
  1647				skb->csum_offset = offsetof(struct udphdr, check);
> 1648				uh->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr,
  1649						(const struct in6_addr *)&ip6h->daddr,
  1650						len, IPPROTO_UDP, 0);
  1651			} else if (keys.basic.ip_proto == IPPROTO_TCP) {
  1652				if (!pskb_may_pull(skb, offset + sizeof(struct tcphdr)))
  1653					return -EINVAL;
  1654	
  1655				th = tcp_hdr(skb);
  1656				skb->csum_offset = offsetof(struct tcphdr, check);
  1657				th->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr,
  1658						(const struct in6_addr *)&ip6h->daddr,
  1659						len, IPPROTO_TCP, 0);
  1660			}
  1661		}
  1662	
  1663		skb->csum_start = skb->transport_header;
  1664	
  1665		return 0;
  1666	}
  1667	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 3/4] virtio-net: support coexistence of XDP and _F_GUEST_CSUM
  2023-06-19 11:26   ` Michael S. Tsirkin
@ 2023-06-19 12:31     ` Heng Qi
  2023-06-20  3:24     ` Heng Qi
  1 sibling, 0 replies; 22+ messages in thread
From: Heng Qi @ 2023-06-19 12:31 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Mon, Jun 19, 2023 at 07:26:44AM -0400, Michael S. Tsirkin wrote:
> On Mon, Jun 19, 2023 at 06:57:37PM +0800, Heng Qi wrote:
> > We are now re-probing the csum related fields and  trying
> > to have XDP and RX hw checksum capabilities coexist on the
> > XDP path. For the benefit of:
> > 1. RX hw checksum capability can be used if XDP is loaded.
> > 2. Avoid packet loss when loading XDP in the vm-vm scenario.
> > 
> > Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> > Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > ---
> >  drivers/net/virtio_net.c | 36 ++++++++++++++++++++++++------------
> >  1 file changed, 24 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index 07b4801d689c..25b486ab74db 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -1709,6 +1709,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> >  	struct net_device *dev = vi->dev;
> >  	struct sk_buff *skb;
> >  	struct virtio_net_hdr_mrg_rxbuf *hdr;
> > +	__u8 flags;
> >  
> >  	if (unlikely(len < vi->hdr_len + ETH_HLEN)) {
> >  		pr_debug("%s: short packet %i\n", dev->name, len);
> > @@ -1717,6 +1718,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> >  		return;
> >  	}
> >  
> > +	flags = ((struct virtio_net_hdr_mrg_rxbuf *)buf)->hdr.flags;
> > +
> >  	if (vi->mergeable_rx_bufs)
> >  		skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
> >  					stats);
> 
> what's going on here?

Thanks for pointing this out. Will insert into mergeable and small modes
respectively.

> 
> > @@ -1728,19 +1731,28 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> >  	if (unlikely(!skb))
> >  		return;
> >  
> > -	hdr = skb_vnet_hdr(skb);
> > -	if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report)
> > -		virtio_skb_set_hash((const struct virtio_net_hdr_v1_hash *)hdr, skb);
> > -
> > -	if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID)
> > -		skb->ip_summed = CHECKSUM_UNNECESSARY;
> > +	if (unlikely(vi->xdp_enabled)) {
> > +		if (virtnet_set_csum_after_xdp(vi, skb, flags) < 0) {
> > +			pr_debug("%s: errors occurred in flow dissector setting csum",
> > +				 dev->name);
> > +			goto frame_err;
> > +		}
> >  
> > -	if (virtio_net_hdr_to_skb(skb, &hdr->hdr,
> > -				  virtio_is_little_endian(vi->vdev))) {
> > -		net_warn_ratelimited("%s: bad gso: type: %u, size: %u\n",
> > -				     dev->name, hdr->hdr.gso_type,
> > -				     hdr->hdr.gso_size);
> > -		goto frame_err;
> > +	} else {
> > +		hdr = skb_vnet_hdr(skb);
> > +		if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report)
> > +			virtio_skb_set_hash((const struct virtio_net_hdr_v1_hash *)hdr, skb);
> > +
> > +		if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID)
> > +			skb->ip_summed = CHECKSUM_UNNECESSARY;
> > +
> > +		if (virtio_net_hdr_to_skb(skb, &hdr->hdr,
> > +					  virtio_is_little_endian(vi->vdev))) {
> > +			net_warn_ratelimited("%s: bad gso: type: %u, size: %u\n",
> > +					     dev->name, hdr->hdr.gso_type,
> > +					     hdr->hdr.gso_size);
> > +			goto frame_err;
> > +		}
> >  	}
> >  
> >  	skb_record_rx_queue(skb, vq2rxq(rq->vq));
> > -- 
> > 2.19.1.6.gb485710b

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 4/4] virtio-net: remove F_GUEST_CSUM check for XDP loading
  2023-06-19 11:16   ` Michael S. Tsirkin
@ 2023-06-19 12:41     ` Heng Qi
  2023-06-19 14:33       ` Michael S. Tsirkin
  0 siblings, 1 reply; 22+ messages in thread
From: Heng Qi @ 2023-06-19 12:41 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Mon, Jun 19, 2023 at 07:16:20AM -0400, Michael S. Tsirkin wrote:
> On Mon, Jun 19, 2023 at 06:57:38PM +0800, Heng Qi wrote:
> > Lay the foundation for the subsequent patch
> 
> which subsequent patch? this is the last one in series.
> 
> > to complete the coexistence
> > of XDP and virtio-net guest csum.
> > 
> > Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> > Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > ---
> >  drivers/net/virtio_net.c | 4 +---
> >  1 file changed, 1 insertion(+), 3 deletions(-)
> > 
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index 25b486ab74db..79471de64b56 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -60,7 +60,6 @@ static const unsigned long guest_offloads[] = {
> >  	VIRTIO_NET_F_GUEST_TSO6,
> >  	VIRTIO_NET_F_GUEST_ECN,
> >  	VIRTIO_NET_F_GUEST_UFO,
> > -	VIRTIO_NET_F_GUEST_CSUM,
> >  	VIRTIO_NET_F_GUEST_USO4,
> >  	VIRTIO_NET_F_GUEST_USO6,
> >  	VIRTIO_NET_F_GUEST_HDRLEN
> 
> What is this doing? Drop support for VIRTIO_NET_F_GUEST_CSUM? Why?

guest_offloads[] is used by the VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET
command to switch features when XDP is loaded/unloaded.

If the VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature is negotiated:
1. When XDP is loaded, virtnet_xdp_set() uses virtnet_clear_guest_offloads()
to automatically turn off the features in guest_offloads[].

2. when XDP is unloaded, virtnet_xdp_set() uses virtnet_restore_guest_offloads()
to automatically restore the features in guest_offloads[].

Now, this work no longer makes XDP and _F_GUEST_CSUM mutually
exclusive, so this patch removed the _F_GUEST_CSUM from guest_offloads[].

> This will disable all of guest offloads I think ..

No. This doesn't change the dependencies of other features on
_F_GUEST_CSUM. Removing _F_GUEST_CSUM here does not mean that other
features that depend on it will be turned off at the same time, such as
_F_GUEST_TSO{4,6}, F_GUEST_USO{4,6}, etc.

Thanks.

> 
> 
> > @@ -3522,10 +3521,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
> >  	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) ||
> >  	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||
> >  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) ||
> > -		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM) ||
> >  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO4) ||
> >  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO6))) {
> > -		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first");
> > +		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW, disable GRO_HW first");
> >  		return -EOPNOTSUPP;
> >  	}
> >  
> > -- 
> > 2.19.1.6.gb485710b

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 2/4] virtio-net: reprobe csum related fields for skb passed by XDP
  2023-06-19 10:57 ` [PATCH net-next 2/4] virtio-net: reprobe csum related fields for skb passed by XDP Heng Qi
  2023-06-19 11:27   ` Michael S. Tsirkin
@ 2023-06-19 13:32   ` kernel test robot
  1 sibling, 0 replies; 22+ messages in thread
From: kernel test robot @ 2023-06-19 13:32 UTC (permalink / raw)
  To: Heng Qi, netdev, bpf
  Cc: llvm, oe-kbuild-all, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

Hi Heng,

kernel test robot noticed the following build warnings:

[auto build test WARNING on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Heng-Qi/virtio-net-a-helper-for-probing-the-pseudo-header-checksum/20230619-190212
base:   net-next/main
patch link:    https://lore.kernel.org/r/20230619105738.117733-3-hengqi%40linux.alibaba.com
patch subject: [PATCH net-next 2/4] virtio-net: reprobe csum related fields for skb passed by XDP
config: x86_64-randconfig-r014-20230619 (https://download.01.org/0day-ci/archive/20230619/202306192151.YMz3NiKw-lkp@intel.com/config)
compiler: clang version 15.0.7 (https://github.com/llvm/llvm-project.git 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a)
reproduce: (https://download.01.org/0day-ci/archive/20230619/202306192151.YMz3NiKw-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202306192151.YMz3NiKw-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/net/virtio_net.c:1648:17: error: call to undeclared function 'csum_ipv6_magic'; ISO C99 and later do not support implicit function declarations [-Werror,-Wimplicit-function-declaration]
                           uh->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr,
                                        ^
   drivers/net/virtio_net.c:1648:17: note: did you mean 'csum_tcpudp_magic'?
   include/asm-generic/checksum.h:52:1: note: 'csum_tcpudp_magic' declared here
   csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
   ^
   drivers/net/virtio_net.c:1657:17: error: call to undeclared function 'csum_ipv6_magic'; ISO C99 and later do not support implicit function declarations [-Werror,-Wimplicit-function-declaration]
                           th->check = ~csum_ipv6_magic((const struct in6_addr *)&ip6h->saddr,
                                        ^
>> drivers/net/virtio_net.c:1695:19: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]
           } else if (flags && VIRTIO_NET_HDR_F_DATA_VALID) {
                            ^  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/virtio_net.c:1695:19: note: use '&' for a bitwise operation
           } else if (flags && VIRTIO_NET_HDR_F_DATA_VALID) {
                            ^~
                            &
   drivers/net/virtio_net.c:1695:19: note: remove constant to silence this warning
           } else if (flags && VIRTIO_NET_HDR_F_DATA_VALID) {
                           ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 warning and 2 errors generated.


vim +1695 drivers/net/virtio_net.c

  1667	
  1668	static int virtnet_set_csum_after_xdp(struct virtnet_info *vi,
  1669					      struct sk_buff *skb,
  1670					      __u8 flags)
  1671	{
  1672		int err;
  1673	
  1674		/* When XDP program is loaded, for example, the vm-vm scenario
  1675		 * on the same host, packets marked as VIRTIO_NET_HDR_F_NEEDS_CSUM
  1676		 * will travel. Although these packets are safe from the point of
  1677		 * view of the vm, to avoid modification by XDP and successful
  1678		 * forwarding in the upper layer, we re-probe the necessary checksum
  1679		 * related information: skb->csum_{start, offset}, pseudo-header csum.
  1680		 *
  1681		 * This benefits us:
  1682		 * 1. XDP can be loaded when there's _F_GUEST_CSUM.
  1683		 * 2. The device verifies the checksum of packets , especially
  1684		 *    benefiting for large packets.
  1685		 * 3. In the same-host vm-vm scenario, packets marked as
  1686		 *    VIRTIO_NET_HDR_F_NEEDS_CSUM are no longer dropped after being
  1687		 *    processed by XDP.
  1688		 */
  1689		if (flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
  1690			err = virtnet_flow_dissect_udp_tcp(vi, skb);
  1691			if (err < 0)
  1692				return -EINVAL;
  1693	
  1694			skb->ip_summed = CHECKSUM_PARTIAL;
> 1695		} else if (flags && VIRTIO_NET_HDR_F_DATA_VALID) {
  1696			/* We want to benefit from this: XDP guarantees that packets marked
  1697			 * as VIRTIO_NET_HDR_F_DATA_VALID still have correct csum after they
  1698			 * are processed.
  1699			 */
  1700			skb->ip_summed = CHECKSUM_UNNECESSARY;
  1701		}
  1702	
  1703		return 0;
  1704	}
  1705	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 4/4] virtio-net: remove F_GUEST_CSUM check for XDP loading
  2023-06-19 12:41     ` Heng Qi
@ 2023-06-19 14:33       ` Michael S. Tsirkin
  2023-06-19 15:43         ` Heng Qi
  0 siblings, 1 reply; 22+ messages in thread
From: Michael S. Tsirkin @ 2023-06-19 14:33 UTC (permalink / raw)
  To: Heng Qi
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Mon, Jun 19, 2023 at 08:41:54PM +0800, Heng Qi wrote:
> On Mon, Jun 19, 2023 at 07:16:20AM -0400, Michael S. Tsirkin wrote:
> > On Mon, Jun 19, 2023 at 06:57:38PM +0800, Heng Qi wrote:
> > > Lay the foundation for the subsequent patch
> > 
> > which subsequent patch? this is the last one in series.
> > 
> > > to complete the coexistence
> > > of XDP and virtio-net guest csum.
> > > 
> > > Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> > > Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > > ---
> > >  drivers/net/virtio_net.c | 4 +---
> > >  1 file changed, 1 insertion(+), 3 deletions(-)
> > > 
> > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > index 25b486ab74db..79471de64b56 100644
> > > --- a/drivers/net/virtio_net.c
> > > +++ b/drivers/net/virtio_net.c
> > > @@ -60,7 +60,6 @@ static const unsigned long guest_offloads[] = {
> > >  	VIRTIO_NET_F_GUEST_TSO6,
> > >  	VIRTIO_NET_F_GUEST_ECN,
> > >  	VIRTIO_NET_F_GUEST_UFO,
> > > -	VIRTIO_NET_F_GUEST_CSUM,
> > >  	VIRTIO_NET_F_GUEST_USO4,
> > >  	VIRTIO_NET_F_GUEST_USO6,
> > >  	VIRTIO_NET_F_GUEST_HDRLEN
> > 
> > What is this doing? Drop support for VIRTIO_NET_F_GUEST_CSUM? Why?
> 
> guest_offloads[] is used by the VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET
> command to switch features when XDP is loaded/unloaded.
> 
> If the VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature is negotiated:
> 1. When XDP is loaded, virtnet_xdp_set() uses virtnet_clear_guest_offloads()
> to automatically turn off the features in guest_offloads[].
> 
> 2. when XDP is unloaded, virtnet_xdp_set() uses virtnet_restore_guest_offloads()
> to automatically restore the features in guest_offloads[].
> 
> Now, this work no longer makes XDP and _F_GUEST_CSUM mutually
> exclusive, so this patch removed the _F_GUEST_CSUM from guest_offloads[].
> 
> > This will disable all of guest offloads I think ..
> 
> No. This doesn't change the dependencies of other features on
> _F_GUEST_CSUM. Removing _F_GUEST_CSUM here does not mean that other
> features that depend on it will be turned off at the same time, such as
> _F_GUEST_TSO{4,6}, F_GUEST_USO{4,6}, etc.
> 
> Thanks.

Hmm I don't get it.

static int virtnet_restore_guest_offloads(struct virtnet_info *vi)
{               
        u64 offloads = vi->guest_offloads;
                        
        if (!vi->guest_offloads)
                return 0;
        
        return virtnet_set_guest_offloads(vi, offloads); 
}               
                        
is the bit _F_GUEST_CSUM set in vi->guest_offloads?

Because if it isn't then we'll try to set _F_GUEST_TSO
without setting _F_GUEST_CSUM and that's a spec
violation I think.


> > 
> > 
> > > @@ -3522,10 +3521,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
> > >  	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) ||
> > >  	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||
> > >  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) ||
> > > -		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM) ||
> > >  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO4) ||
> > >  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO6))) {
> > > -		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first");
> > > +		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW, disable GRO_HW first");
> > >  		return -EOPNOTSUPP;
> > >  	}
> > >  
> > > -- 
> > > 2.19.1.6.gb485710b


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 4/4] virtio-net: remove F_GUEST_CSUM check for XDP loading
  2023-06-19 14:33       ` Michael S. Tsirkin
@ 2023-06-19 15:43         ` Heng Qi
  2023-06-19 18:36           ` Michael S. Tsirkin
  0 siblings, 1 reply; 22+ messages in thread
From: Heng Qi @ 2023-06-19 15:43 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Mon, Jun 19, 2023 at 10:33:44AM -0400, Michael S. Tsirkin wrote:
> On Mon, Jun 19, 2023 at 08:41:54PM +0800, Heng Qi wrote:
> > On Mon, Jun 19, 2023 at 07:16:20AM -0400, Michael S. Tsirkin wrote:
> > > On Mon, Jun 19, 2023 at 06:57:38PM +0800, Heng Qi wrote:
> > > > Lay the foundation for the subsequent patch
> > > 
> > > which subsequent patch? this is the last one in series.
> > > 
> > > > to complete the coexistence
> > > > of XDP and virtio-net guest csum.
> > > > 
> > > > Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> > > > Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > > > ---
> > > >  drivers/net/virtio_net.c | 4 +---
> > > >  1 file changed, 1 insertion(+), 3 deletions(-)
> > > > 
> > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > > index 25b486ab74db..79471de64b56 100644
> > > > --- a/drivers/net/virtio_net.c
> > > > +++ b/drivers/net/virtio_net.c
> > > > @@ -60,7 +60,6 @@ static const unsigned long guest_offloads[] = {
> > > >  	VIRTIO_NET_F_GUEST_TSO6,
> > > >  	VIRTIO_NET_F_GUEST_ECN,
> > > >  	VIRTIO_NET_F_GUEST_UFO,
> > > > -	VIRTIO_NET_F_GUEST_CSUM,
> > > >  	VIRTIO_NET_F_GUEST_USO4,
> > > >  	VIRTIO_NET_F_GUEST_USO6,
> > > >  	VIRTIO_NET_F_GUEST_HDRLEN
> > > 
> > > What is this doing? Drop support for VIRTIO_NET_F_GUEST_CSUM? Why?
> > 
> > guest_offloads[] is used by the VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET
> > command to switch features when XDP is loaded/unloaded.
> > 
> > If the VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature is negotiated:
> > 1. When XDP is loaded, virtnet_xdp_set() uses virtnet_clear_guest_offloads()
> > to automatically turn off the features in guest_offloads[].
> > 
> > 2. when XDP is unloaded, virtnet_xdp_set() uses virtnet_restore_guest_offloads()
> > to automatically restore the features in guest_offloads[].
> > 
> > Now, this work no longer makes XDP and _F_GUEST_CSUM mutually
> > exclusive, so this patch removed the _F_GUEST_CSUM from guest_offloads[].
> > 
> > > This will disable all of guest offloads I think ..
> > 
> > No. This doesn't change the dependencies of other features on
> > _F_GUEST_CSUM. Removing _F_GUEST_CSUM here does not mean that other
> > features that depend on it will be turned off at the same time, such as
> > _F_GUEST_TSO{4,6}, F_GUEST_USO{4,6}, etc.
> > 
> > Thanks.
> 
> Hmm I don't get it.
> 
> static int virtnet_restore_guest_offloads(struct virtnet_info *vi)
> {               
>         u64 offloads = vi->guest_offloads;
>                         
>         if (!vi->guest_offloads)
>                 return 0;
>         
>         return virtnet_set_guest_offloads(vi, offloads); 
> }               
>                         
> is the bit _F_GUEST_CSUM set in vi->guest_offloads?

No, but first we doesn't clear _F_GUEST_CSUM in virtnet_clear_guest_offloads().

If VIRTIO_NET_F_CTRL_GUEST_OFFLOADS is negotiated, features that can
be dynamically controlled by the VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET
command must also be negotiated. Therefore, if GRO_HW_MASK features such
as _F_GUEST_TSO exist, then _F_GUEST_CSUM must exist (according to the
dependencies defined by the spec).

Now, we only dynamically turn off/on the features contained in
guest_offloads[] through XDP loading/unloading (with this patch,
_F_GUEST_CSUM will not be controlled), and _F_GUEST_CSUM is always on.

Another point is that the virtio-net NETIF_F_RXCSUM corresponding to
_F_GUEST_CSUM is only included in dev->features, not in dev->hw_features,
which means that users cannot manually control the switch of
_F_GUEST_CSUM.

> 
> Because if it isn't then we'll try to set _F_GUEST_TSO
> without setting _F_GUEST_CSUM and that's a spec
> violation I think.

As explained above, we did not cause a specification violation.

Thanks.

> 
> 
> > > 
> > > 
> > > > @@ -3522,10 +3521,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
> > > >  	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) ||
> > > >  	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||
> > > >  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) ||
> > > > -		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM) ||
> > > >  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO4) ||
> > > >  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO6))) {
> > > > -		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first");
> > > > +		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW, disable GRO_HW first");
> > > >  		return -EOPNOTSUPP;
> > > >  	}
> > > >  
> > > > -- 
> > > > 2.19.1.6.gb485710b

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 4/4] virtio-net: remove F_GUEST_CSUM check for XDP loading
  2023-06-19 15:43         ` Heng Qi
@ 2023-06-19 18:36           ` Michael S. Tsirkin
  0 siblings, 0 replies; 22+ messages in thread
From: Michael S. Tsirkin @ 2023-06-19 18:36 UTC (permalink / raw)
  To: Heng Qi
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Mon, Jun 19, 2023 at 11:43:29PM +0800, Heng Qi wrote:
> On Mon, Jun 19, 2023 at 10:33:44AM -0400, Michael S. Tsirkin wrote:
> > On Mon, Jun 19, 2023 at 08:41:54PM +0800, Heng Qi wrote:
> > > On Mon, Jun 19, 2023 at 07:16:20AM -0400, Michael S. Tsirkin wrote:
> > > > On Mon, Jun 19, 2023 at 06:57:38PM +0800, Heng Qi wrote:
> > > > > Lay the foundation for the subsequent patch
> > > > 
> > > > which subsequent patch? this is the last one in series.
> > > > 
> > > > > to complete the coexistence
> > > > > of XDP and virtio-net guest csum.
> > > > > 
> > > > > Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> > > > > Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > > > > ---
> > > > >  drivers/net/virtio_net.c | 4 +---
> > > > >  1 file changed, 1 insertion(+), 3 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > > > index 25b486ab74db..79471de64b56 100644
> > > > > --- a/drivers/net/virtio_net.c
> > > > > +++ b/drivers/net/virtio_net.c
> > > > > @@ -60,7 +60,6 @@ static const unsigned long guest_offloads[] = {
> > > > >  	VIRTIO_NET_F_GUEST_TSO6,
> > > > >  	VIRTIO_NET_F_GUEST_ECN,
> > > > >  	VIRTIO_NET_F_GUEST_UFO,
> > > > > -	VIRTIO_NET_F_GUEST_CSUM,
> > > > >  	VIRTIO_NET_F_GUEST_USO4,
> > > > >  	VIRTIO_NET_F_GUEST_USO6,
> > > > >  	VIRTIO_NET_F_GUEST_HDRLEN
> > > > 
> > > > What is this doing? Drop support for VIRTIO_NET_F_GUEST_CSUM? Why?
> > > 
> > > guest_offloads[] is used by the VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET
> > > command to switch features when XDP is loaded/unloaded.
> > > 
> > > If the VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature is negotiated:
> > > 1. When XDP is loaded, virtnet_xdp_set() uses virtnet_clear_guest_offloads()
> > > to automatically turn off the features in guest_offloads[].
> > > 
> > > 2. when XDP is unloaded, virtnet_xdp_set() uses virtnet_restore_guest_offloads()
> > > to automatically restore the features in guest_offloads[].
> > > 
> > > Now, this work no longer makes XDP and _F_GUEST_CSUM mutually
> > > exclusive, so this patch removed the _F_GUEST_CSUM from guest_offloads[].
> > > 
> > > > This will disable all of guest offloads I think ..
> > > 
> > > No. This doesn't change the dependencies of other features on
> > > _F_GUEST_CSUM. Removing _F_GUEST_CSUM here does not mean that other
> > > features that depend on it will be turned off at the same time, such as
> > > _F_GUEST_TSO{4,6}, F_GUEST_USO{4,6}, etc.
> > > 
> > > Thanks.
> > 
> > Hmm I don't get it.
> > 
> > static int virtnet_restore_guest_offloads(struct virtnet_info *vi)
> > {               
> >         u64 offloads = vi->guest_offloads;
> >                         
> >         if (!vi->guest_offloads)
> >                 return 0;
> >         
> >         return virtnet_set_guest_offloads(vi, offloads); 
> > }               
> >                         
> > is the bit _F_GUEST_CSUM set in vi->guest_offloads?
> 
> No, but first we doesn't clear _F_GUEST_CSUM in virtnet_clear_guest_offloads().
> 
> If VIRTIO_NET_F_CTRL_GUEST_OFFLOADS is negotiated, features that can
> be dynamically controlled by the VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET
> command must also be negotiated. Therefore, if GRO_HW_MASK features such
> as _F_GUEST_TSO exist, then _F_GUEST_CSUM must exist (according to the
> dependencies defined by the spec).
> 
> Now, we only dynamically turn off/on the features contained in
> guest_offloads[] through XDP loading/unloading (with this patch,
> _F_GUEST_CSUM will not be controlled), and _F_GUEST_CSUM is always on.
> 
> Another point is that the virtio-net NETIF_F_RXCSUM corresponding to
> _F_GUEST_CSUM is only included in dev->features, not in dev->hw_features,
> which means that users cannot manually control the switch of
> _F_GUEST_CSUM.

I think I get it now.

> > 
> > Because if it isn't then we'll try to set _F_GUEST_TSO
> > without setting _F_GUEST_CSUM and that's a spec
> > violation I think.
> 
> As explained above, we did not cause a specification violation.
> 
> Thanks.

Right.

> > 
> > 
> > > > 
> > > > 
> > > > > @@ -3522,10 +3521,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
> > > > >  	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) ||
> > > > >  	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||
> > > > >  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) ||
> > > > > -		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM) ||
> > > > >  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO4) ||
> > > > >  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO6))) {
> > > > > -		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first");
> > > > > +		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW, disable GRO_HW first");
> > > > >  		return -EOPNOTSUPP;
> > > > >  	}
> > > > >  
> > > > > -- 
> > > > > 2.19.1.6.gb485710b


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 3/4] virtio-net: support coexistence of XDP and _F_GUEST_CSUM
  2023-06-19 11:26   ` Michael S. Tsirkin
  2023-06-19 12:31     ` Heng Qi
@ 2023-06-20  3:24     ` Heng Qi
  2023-06-20 10:50       ` Michael S. Tsirkin
  1 sibling, 1 reply; 22+ messages in thread
From: Heng Qi @ 2023-06-20  3:24 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Mon, Jun 19, 2023 at 07:26:44AM -0400, Michael S. Tsirkin wrote:
> On Mon, Jun 19, 2023 at 06:57:37PM +0800, Heng Qi wrote:
> > We are now re-probing the csum related fields and  trying
> > to have XDP and RX hw checksum capabilities coexist on the
> > XDP path. For the benefit of:
> > 1. RX hw checksum capability can be used if XDP is loaded.
> > 2. Avoid packet loss when loading XDP in the vm-vm scenario.
> > 
> > Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> > Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > ---
> >  drivers/net/virtio_net.c | 36 ++++++++++++++++++++++++------------
> >  1 file changed, 24 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index 07b4801d689c..25b486ab74db 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -1709,6 +1709,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> >  	struct net_device *dev = vi->dev;
> >  	struct sk_buff *skb;
> >  	struct virtio_net_hdr_mrg_rxbuf *hdr;
> > +	__u8 flags;
> >  
> >  	if (unlikely(len < vi->hdr_len + ETH_HLEN)) {
> >  		pr_debug("%s: short packet %i\n", dev->name, len);
> > @@ -1717,6 +1718,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> >  		return;
> >  	}
> >  
> > +	flags = ((struct virtio_net_hdr_mrg_rxbuf *)buf)->hdr.flags;
> > +
> >  	if (vi->mergeable_rx_bufs)
> >  		skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
> >  					stats);
> 
> what's going on here?

Hi, Michael.

Is your question about the function of this code?
1. If yes,
this sentence saves the flags value in virtio-net-hdr in advance
before entering the XDP processing logic, so that it can be used to
judge further logic after XDP processing.

If _NEEDS_CSUM is included in flags before XDP processing, then after
XDP processing we need to re-probe the csum fields and calculate the
pseudo-header checksum.

2. If not,
do you mean that mergeable and small modes should be distinguished for
save actions?
The answer is that we don't need it. The information in virtio-net-hdr in
the current small mode is also forcibly converted into the
virtio_net_hdr_mrg_rxbuf structure, which is consistent with the
virtio_net_hdr structure in terms of code layout, and the results are
consistent.

If you think this is semantically wrong, then we need a bugfix patch.
The simplest example is in receive_small_xdp():
"
unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
...
struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset; "


Thanks.

> 
> > @@ -1728,19 +1731,28 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> >  	if (unlikely(!skb))
> >  		return;
> >  
> > -	hdr = skb_vnet_hdr(skb);
> > -	if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report)
> > -		virtio_skb_set_hash((const struct virtio_net_hdr_v1_hash *)hdr, skb);
> > -
> > -	if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID)
> > -		skb->ip_summed = CHECKSUM_UNNECESSARY;
> > +	if (unlikely(vi->xdp_enabled)) {
> > +		if (virtnet_set_csum_after_xdp(vi, skb, flags) < 0) {
> > +			pr_debug("%s: errors occurred in flow dissector setting csum",
> > +				 dev->name);
> > +			goto frame_err;
> > +		}
> >  
> > -	if (virtio_net_hdr_to_skb(skb, &hdr->hdr,
> > -				  virtio_is_little_endian(vi->vdev))) {
> > -		net_warn_ratelimited("%s: bad gso: type: %u, size: %u\n",
> > -				     dev->name, hdr->hdr.gso_type,
> > -				     hdr->hdr.gso_size);
> > -		goto frame_err;
> > +	} else {
> > +		hdr = skb_vnet_hdr(skb);
> > +		if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report)
> > +			virtio_skb_set_hash((const struct virtio_net_hdr_v1_hash *)hdr, skb);
> > +
> > +		if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID)
> > +			skb->ip_summed = CHECKSUM_UNNECESSARY;
> > +
> > +		if (virtio_net_hdr_to_skb(skb, &hdr->hdr,
> > +					  virtio_is_little_endian(vi->vdev))) {
> > +			net_warn_ratelimited("%s: bad gso: type: %u, size: %u\n",
> > +					     dev->name, hdr->hdr.gso_type,
> > +					     hdr->hdr.gso_size);
> > +			goto frame_err;
> > +		}
> >  	}
> >  
> >  	skb_record_rx_queue(skb, vq2rxq(rq->vq));
> > -- 
> > 2.19.1.6.gb485710b

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 3/4] virtio-net: support coexistence of XDP and _F_GUEST_CSUM
  2023-06-20  3:24     ` Heng Qi
@ 2023-06-20 10:50       ` Michael S. Tsirkin
  2023-06-20 11:01         ` Heng Qi
  0 siblings, 1 reply; 22+ messages in thread
From: Michael S. Tsirkin @ 2023-06-20 10:50 UTC (permalink / raw)
  To: Heng Qi
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Tue, Jun 20, 2023 at 11:24:30AM +0800, Heng Qi wrote:
> On Mon, Jun 19, 2023 at 07:26:44AM -0400, Michael S. Tsirkin wrote:
> > On Mon, Jun 19, 2023 at 06:57:37PM +0800, Heng Qi wrote:
> > > We are now re-probing the csum related fields and  trying
> > > to have XDP and RX hw checksum capabilities coexist on the
> > > XDP path. For the benefit of:
> > > 1. RX hw checksum capability can be used if XDP is loaded.
> > > 2. Avoid packet loss when loading XDP in the vm-vm scenario.
> > > 
> > > Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> > > Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > > ---
> > >  drivers/net/virtio_net.c | 36 ++++++++++++++++++++++++------------
> > >  1 file changed, 24 insertions(+), 12 deletions(-)
> > > 
> > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > index 07b4801d689c..25b486ab74db 100644
> > > --- a/drivers/net/virtio_net.c
> > > +++ b/drivers/net/virtio_net.c
> > > @@ -1709,6 +1709,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> > >  	struct net_device *dev = vi->dev;
> > >  	struct sk_buff *skb;
> > >  	struct virtio_net_hdr_mrg_rxbuf *hdr;
> > > +	__u8 flags;
> > >  
> > >  	if (unlikely(len < vi->hdr_len + ETH_HLEN)) {
> > >  		pr_debug("%s: short packet %i\n", dev->name, len);
> > > @@ -1717,6 +1718,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> > >  		return;
> > >  	}
> > >  
> > > +	flags = ((struct virtio_net_hdr_mrg_rxbuf *)buf)->hdr.flags;
> > > +
> > >  	if (vi->mergeable_rx_bufs)
> > >  		skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
> > >  					stats);
> > 
> > what's going on here?
> 
> Hi, Michael.
> 
> Is your question about the function of this code?
> 1. If yes,
> this sentence saves the flags value in virtio-net-hdr in advance
> before entering the XDP processing logic, so that it can be used to
> judge further logic after XDP processing.
> 
> If _NEEDS_CSUM is included in flags before XDP processing, then after
> XDP processing we need to re-probe the csum fields and calculate the
> pseudo-header checksum.

Yes but we previously used this:
-       hdr = skb_vnet_hdr(skb);
which pokes at the copy in skb cb.

Is anything wrong with this?

It seems preferable not to poke at the header an extra time.

-- 
MST


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 3/4] virtio-net: support coexistence of XDP and _F_GUEST_CSUM
  2023-06-20 10:50       ` Michael S. Tsirkin
@ 2023-06-20 11:01         ` Heng Qi
  2023-06-20 12:10           ` Michael S. Tsirkin
  0 siblings, 1 reply; 22+ messages in thread
From: Heng Qi @ 2023-06-20 11:01 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Tue, Jun 20, 2023 at 06:50:34AM -0400, Michael S. Tsirkin wrote:
> On Tue, Jun 20, 2023 at 11:24:30AM +0800, Heng Qi wrote:
> > On Mon, Jun 19, 2023 at 07:26:44AM -0400, Michael S. Tsirkin wrote:
> > > On Mon, Jun 19, 2023 at 06:57:37PM +0800, Heng Qi wrote:
> > > > We are now re-probing the csum related fields and  trying
> > > > to have XDP and RX hw checksum capabilities coexist on the
> > > > XDP path. For the benefit of:
> > > > 1. RX hw checksum capability can be used if XDP is loaded.
> > > > 2. Avoid packet loss when loading XDP in the vm-vm scenario.
> > > > 
> > > > Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> > > > Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > > > ---
> > > >  drivers/net/virtio_net.c | 36 ++++++++++++++++++++++++------------
> > > >  1 file changed, 24 insertions(+), 12 deletions(-)
> > > > 
> > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > > index 07b4801d689c..25b486ab74db 100644
> > > > --- a/drivers/net/virtio_net.c
> > > > +++ b/drivers/net/virtio_net.c
> > > > @@ -1709,6 +1709,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> > > >  	struct net_device *dev = vi->dev;
> > > >  	struct sk_buff *skb;
> > > >  	struct virtio_net_hdr_mrg_rxbuf *hdr;
> > > > +	__u8 flags;
> > > >  
> > > >  	if (unlikely(len < vi->hdr_len + ETH_HLEN)) {
> > > >  		pr_debug("%s: short packet %i\n", dev->name, len);
> > > > @@ -1717,6 +1718,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> > > >  		return;
> > > >  	}
> > > >  
> > > > +	flags = ((struct virtio_net_hdr_mrg_rxbuf *)buf)->hdr.flags;
> > > > +
> > > >  	if (vi->mergeable_rx_bufs)
> > > >  		skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
> > > >  					stats);
> > > 
> > > what's going on here?
> > 
> > Hi, Michael.
> > 
> > Is your question about the function of this code?
> > 1. If yes,
> > this sentence saves the flags value in virtio-net-hdr in advance
> > before entering the XDP processing logic, so that it can be used to
> > judge further logic after XDP processing.
> > 
> > If _NEEDS_CSUM is included in flags before XDP processing, then after
> > XDP processing we need to re-probe the csum fields and calculate the
> > pseudo-header checksum.
> 
> Yes but we previously used this:
> -       hdr = skb_vnet_hdr(skb);
> which pokes at the copy in skb cb.
> 
> Is anything wrong with this?
> 

This is where we save the hdr when there is no XDP loaded (note that
this is the complete hdr, including flags, and also including GSO and
other information). When XDP is loaded, because hdr is invalid, we will
not save it into skb->cb.

But the above situation is not what we want. Now our purpose is to save
the hdr information before XDP processing, that is, when the driver has
just received the packet and has not built the skb (in fact, we only
need flags). Therefore, only flags are saved here.

Thanks.

> It seems preferable not to poke at the header an extra time.
> 
> -- 
> MST

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 3/4] virtio-net: support coexistence of XDP and _F_GUEST_CSUM
  2023-06-20 11:01         ` Heng Qi
@ 2023-06-20 12:10           ` Michael S. Tsirkin
  2023-06-20 14:15             ` Heng Qi
  0 siblings, 1 reply; 22+ messages in thread
From: Michael S. Tsirkin @ 2023-06-20 12:10 UTC (permalink / raw)
  To: Heng Qi
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Tue, Jun 20, 2023 at 07:01:48PM +0800, Heng Qi wrote:
> On Tue, Jun 20, 2023 at 06:50:34AM -0400, Michael S. Tsirkin wrote:
> > On Tue, Jun 20, 2023 at 11:24:30AM +0800, Heng Qi wrote:
> > > On Mon, Jun 19, 2023 at 07:26:44AM -0400, Michael S. Tsirkin wrote:
> > > > On Mon, Jun 19, 2023 at 06:57:37PM +0800, Heng Qi wrote:
> > > > > We are now re-probing the csum related fields and  trying
> > > > > to have XDP and RX hw checksum capabilities coexist on the
> > > > > XDP path. For the benefit of:
> > > > > 1. RX hw checksum capability can be used if XDP is loaded.
> > > > > 2. Avoid packet loss when loading XDP in the vm-vm scenario.
> > > > > 
> > > > > Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> > > > > Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > > > > ---
> > > > >  drivers/net/virtio_net.c | 36 ++++++++++++++++++++++++------------
> > > > >  1 file changed, 24 insertions(+), 12 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > > > index 07b4801d689c..25b486ab74db 100644
> > > > > --- a/drivers/net/virtio_net.c
> > > > > +++ b/drivers/net/virtio_net.c
> > > > > @@ -1709,6 +1709,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> > > > >  	struct net_device *dev = vi->dev;
> > > > >  	struct sk_buff *skb;
> > > > >  	struct virtio_net_hdr_mrg_rxbuf *hdr;
> > > > > +	__u8 flags;
> > > > >  
> > > > >  	if (unlikely(len < vi->hdr_len + ETH_HLEN)) {
> > > > >  		pr_debug("%s: short packet %i\n", dev->name, len);
> > > > > @@ -1717,6 +1718,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> > > > >  		return;
> > > > >  	}
> > > > >  
> > > > > +	flags = ((struct virtio_net_hdr_mrg_rxbuf *)buf)->hdr.flags;
> > > > > +
> > > > >  	if (vi->mergeable_rx_bufs)
> > > > >  		skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
> > > > >  					stats);
> > > > 
> > > > what's going on here?
> > > 
> > > Hi, Michael.
> > > 
> > > Is your question about the function of this code?
> > > 1. If yes,
> > > this sentence saves the flags value in virtio-net-hdr in advance
> > > before entering the XDP processing logic, so that it can be used to
> > > judge further logic after XDP processing.
> > > 
> > > If _NEEDS_CSUM is included in flags before XDP processing, then after
> > > XDP processing we need to re-probe the csum fields and calculate the
> > > pseudo-header checksum.
> > 
> > Yes but we previously used this:
> > -       hdr = skb_vnet_hdr(skb);
> > which pokes at the copy in skb cb.
> > 
> > Is anything wrong with this?
> > 
> 
> This is where we save the hdr when there is no XDP loaded (note that
> this is the complete hdr, including flags, and also including GSO and
> other information). When XDP is loaded, because hdr is invalid, we will
> not save it into skb->cb.
> 
> But the above situation is not what we want. Now our purpose is to save
> the hdr information before XDP processing, that is, when the driver has
> just received the packet and has not built the skb (in fact, we only
> need flags). Therefore, only flags are saved here.
> 
> Thanks.

I don't get it. this seems to be the only use of flags:


+       if (unlikely(vi->xdp_enabled)) {
+               if (virtnet_set_csum_after_xdp(vi, skb, flags) < 0) {
+                       pr_debug("%s: errors occurred in flow dissector setting csum",
+                                dev->name);
+                       goto frame_err;
+               }

looks like skb has already been created here.

is there another use of flags that I missed?



> > It seems preferable not to poke at the header an extra time.
> > 
> > -- 
> > MST


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 3/4] virtio-net: support coexistence of XDP and _F_GUEST_CSUM
  2023-06-20 12:10           ` Michael S. Tsirkin
@ 2023-06-20 14:15             ` Heng Qi
  0 siblings, 0 replies; 22+ messages in thread
From: Heng Qi @ 2023-06-20 14:15 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: netdev, bpf, Jason Wang, Xuan Zhuo, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend

On Tue, Jun 20, 2023 at 08:10:38AM -0400, Michael S. Tsirkin wrote:
> On Tue, Jun 20, 2023 at 07:01:48PM +0800, Heng Qi wrote:
> > On Tue, Jun 20, 2023 at 06:50:34AM -0400, Michael S. Tsirkin wrote:
> > > On Tue, Jun 20, 2023 at 11:24:30AM +0800, Heng Qi wrote:
> > > > On Mon, Jun 19, 2023 at 07:26:44AM -0400, Michael S. Tsirkin wrote:
> > > > > On Mon, Jun 19, 2023 at 06:57:37PM +0800, Heng Qi wrote:
> > > > > > We are now re-probing the csum related fields and  trying
> > > > > > to have XDP and RX hw checksum capabilities coexist on the
> > > > > > XDP path. For the benefit of:
> > > > > > 1. RX hw checksum capability can be used if XDP is loaded.
> > > > > > 2. Avoid packet loss when loading XDP in the vm-vm scenario.
> > > > > > 
> > > > > > Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
> > > > > > Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > > > > > ---
> > > > > >  drivers/net/virtio_net.c | 36 ++++++++++++++++++++++++------------
> > > > > >  1 file changed, 24 insertions(+), 12 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > > > > index 07b4801d689c..25b486ab74db 100644
> > > > > > --- a/drivers/net/virtio_net.c
> > > > > > +++ b/drivers/net/virtio_net.c
> > > > > > @@ -1709,6 +1709,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> > > > > >  	struct net_device *dev = vi->dev;
> > > > > >  	struct sk_buff *skb;
> > > > > >  	struct virtio_net_hdr_mrg_rxbuf *hdr;
> > > > > > +	__u8 flags;
> > > > > >  
> > > > > >  	if (unlikely(len < vi->hdr_len + ETH_HLEN)) {
> > > > > >  		pr_debug("%s: short packet %i\n", dev->name, len);
> > > > > > @@ -1717,6 +1718,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> > > > > >  		return;
> > > > > >  	}
> > > > > >  
> > > > > > +	flags = ((struct virtio_net_hdr_mrg_rxbuf *)buf)->hdr.flags;
> > > > > > +
> > > > > >  	if (vi->mergeable_rx_bufs)
> > > > > >  		skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
> > > > > >  					stats);
> > > > > 
> > > > > what's going on here?
> > > > 
> > > > Hi, Michael.
> > > > 
> > > > Is your question about the function of this code?
> > > > 1. If yes,
> > > > this sentence saves the flags value in virtio-net-hdr in advance
> > > > before entering the XDP processing logic, so that it can be used to
> > > > judge further logic after XDP processing.
> > > > 
> > > > If _NEEDS_CSUM is included in flags before XDP processing, then after
> > > > XDP processing we need to re-probe the csum fields and calculate the
> > > > pseudo-header checksum.
> > > 
> > > Yes but we previously used this:
> > > -       hdr = skb_vnet_hdr(skb);
> > > which pokes at the copy in skb cb.
> > > 
> > > Is anything wrong with this?
> > > 
> > 
> > This is where we save the hdr when there is no XDP loaded (note that
> > this is the complete hdr, including flags, and also including GSO and
> > other information). When XDP is loaded, because hdr is invalid, we will
> > not save it into skb->cb.
> > 
> > But the above situation is not what we want. Now our purpose is to save
> > the hdr information before XDP processing, that is, when the driver has
> > just received the packet and has not built the skb (in fact, we only
> > need flags). Therefore, only flags are saved here.
> > 
> > Thanks.
> 
> I don't get it. this seems to be the only use of flags:
> 
> 
> +       if (unlikely(vi->xdp_enabled)) {
> +               if (virtnet_set_csum_after_xdp(vi, skb, flags) < 0) {
> +                       pr_debug("%s: errors occurred in flow dissector setting csum",
> +                                dev->name);
> +                       goto frame_err;
> +               }
> 
> looks like skb has already been created here.

I explain more:

First, this patchset only focuses on XDP loaded scenes.

Then in the same-host vm-vm scenario, when the receiver loads XDP, this
is the packet receiving process:
1. The driver receives a packet, represented by *buf.

2. The XDP program builds xdp_buff based on *buf.
   virtio_net_hdr_mrg_rxbuf is located in the headroom of xdp_buff.

3. The XDP program returns XDP_PASS and modifies the headroom, that is,
the information in virtio_net_hdr_mrg_rxbuf becomes invalid (including
flags). So information like csum_{start, offset} is no longer correct.
Therefore, the skb converted from xdp_buff does not save information in
skb cb. And, skb->ip_summed = CHECKSUM_NONE, there is a high probability of
packet loss at this time because the incorrect check value.

So, in order to solve this problem (not only), we save the flags in
virtio_net_hdr_mrg_rxbuf before the #2 step above, which is the
original information, just to know whether the packet is _NEEDS_CSUM or
_DATA_VALID.

If the saved flags contains _NEEDS_CSUM, then we use
virtnet_set_csum_after_xdp() to recalculate csum_{start, offset},
pseudo-header checksum for the skb converted from xdp_buff. That is, the
saved flags are only used to identify whether we want to re-probe for
the packet to avoiding the packet dropping.

Thanks.

> 
> is there another use of flags that I missed?
> 
> 
> 
> > > It seems preferable not to poke at the header an extra time.
> > > 
> > > -- 
> > > MST

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2023-06-20 14:15 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-19 10:57 [PATCH net-next 0/4] virtio-net: avoid XDP and _F_GUEST_CSUM Heng Qi
2023-06-19 10:57 ` [PATCH net-next 1/4] virtio-net: a helper for probing the pseudo-header checksum Heng Qi
2023-06-19 12:30   ` kernel test robot
2023-06-19 12:30   ` kernel test robot
2023-06-19 10:57 ` [PATCH net-next 2/4] virtio-net: reprobe csum related fields for skb passed by XDP Heng Qi
2023-06-19 11:27   ` Michael S. Tsirkin
2023-06-19 12:29     ` Heng Qi
2023-06-19 13:32   ` kernel test robot
2023-06-19 10:57 ` [PATCH net-next 3/4] virtio-net: support coexistence of XDP and _F_GUEST_CSUM Heng Qi
2023-06-19 11:26   ` Michael S. Tsirkin
2023-06-19 12:31     ` Heng Qi
2023-06-20  3:24     ` Heng Qi
2023-06-20 10:50       ` Michael S. Tsirkin
2023-06-20 11:01         ` Heng Qi
2023-06-20 12:10           ` Michael S. Tsirkin
2023-06-20 14:15             ` Heng Qi
2023-06-19 10:57 ` [PATCH net-next 4/4] virtio-net: remove F_GUEST_CSUM check for XDP loading Heng Qi
2023-06-19 11:16   ` Michael S. Tsirkin
2023-06-19 12:41     ` Heng Qi
2023-06-19 14:33       ` Michael S. Tsirkin
2023-06-19 15:43         ` Heng Qi
2023-06-19 18:36           ` Michael S. Tsirkin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.