All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: weimin xiong <15927021679@163.com>
Cc: jasowang@redhat.com, virtualization@vger.kernel.org,
	netdev@vger.kernel.org, xiongweimin <xiongweimin@kylinos.cn>
Subject: Re: [PATCH] vhost/net: Fill virtio_net_hdr GSO/csum metadata on RX
Date: Mon, 13 Jul 2026 03:03:39 -0400	[thread overview]
Message-ID: <20260713025549-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <20260713010442.331109-1-15927021679@163.com>

On Mon, Jul 13, 2026 at 09:04:42AM +0800, weimin xiong wrote:
> From: xiongweimin <xiongweimin@kylinos.cn>
> 
> When VHOST_NET_F_VIRTIO_NET_HDR is set, vhost supplies virtio_net_hdr to
> the guest but previously always wrote a zeroed header (GSO_NONE). Guests
> that rely on GUEST_TSO*/GUEST_CSUM therefore never saw offload metadata.

Right. Question is why are you using VHOST_NET_F_VIRTIO_NET_HDR?

> 
> Peek the socket skb before recvmsg and populate the header with
> virtio_net_hdr_from_skb(). Also advertise the corresponding guest offload
> feature bits from VHOST_GET_FEATURES.
> 
> TX TSO toward backends without IFF_VNET_HDR is intentionally left for a
> follow-up series.
> 
> Signed-off-by: xiongweimin <xiongweimin@kylinos.cn>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Cc: Jason Wang <jasowang@redhat.com>
> Cc: virtualization@vger.kernel.org
> Cc: netdev@vger.kernel.org
> ---
> 
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -73,6 +73,10 @@
>  	VHOST_FEATURES,
>  	VHOST_NET_F_VIRTIO_NET_HDR,
>  	VIRTIO_NET_F_MRG_RXBUF,
> +	VIRTIO_NET_F_GUEST_CSUM,
> +	VIRTIO_NET_F_GUEST_TSO4,
> +	VIRTIO_NET_F_GUEST_TSO6,
> +	VIRTIO_NET_F_GUEST_ECN,
>  	VIRTIO_F_ACCESS_PLATFORM,
>  	VIRTIO_F_RING_RESET,
>  	VIRTIO_F_IN_ORDER,
> @@ -644,7 +648,7 @@
>  static size_t init_iov_iter(struct vhost_virtqueue *vq, struct iov_iter *iter,
>  			    size_t hdr_size, int out)
>  {
> -	/* Skip header. TODO: support TSO. */
> +	/* Skip guest virtio_net_hdr; TX TSO handled in a follow-up. */
>  	size_t len = iov_length(vq->iov, out);
>  
>  	iov_iter_init(iter, ITER_SOURCE, vq->iov, out, len);
> @@ -1025,6 +1029,35 @@
>  	return len;
>  }
>  
> +/*
> + * When VHOST_NET_F_VIRTIO_NET_HDR is set, vhost supplies virtio_net_hdr.
> + * Populate GSO/checksum metadata from the socket skb so guests that
> + * negotiated GUEST_TSO*/GUEST_CSUM receive correct offload information.
> + */

this is a wrong type of multiline comment. this file follows net
convention:

/* AAA
 * BBB
 */

> +static int vhost_net_hdr_from_sock(struct vhost_virtqueue *vq, struct sock *sk,
> +				   struct virtio_net_hdr *hdr)
> +{
> +	struct sk_buff *skb;
> +	unsigned long flags;
> +	int vlan_hlen = 0;
> +	int ret;
> +
> +	spin_lock_irqsave(&sk->sk_receive_queue.lock, flags);
> +	skb = skb_peek(&sk->sk_receive_queue);
> +	if (!skb) {
> +		spin_unlock_irqrestore(&sk->sk_receive_queue.lock, flags);
> +		memset(hdr, 0, sizeof(*hdr));
> +		hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
> +		return 0;
> +	}
> +	if (skb_vlan_tag_present(skb))
> +		vlan_hlen = VLAN_HLEN;
> +	ret = virtio_net_hdr_from_skb(skb, hdr, vhost_is_little_endian(vq),
> +				      true, vlan_hlen);
> +	spin_unlock_irqrestore(&sk->sk_receive_queue.lock, flags);
> +	return ret;
> +}


This means the header will be wrong if something consumes
the skb after we drop the lock, no?

That's why in the end we put the header filling logic
in tun, it can avoid races there.


> +
>  static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk,
>  				      bool *busyloop_intr, unsigned int *count)
>  {
> @@ -1239,10 +1272,18 @@
>  		/* We don't need to be notified again. */
>  		iov_iter_init(&msg.msg_iter, ITER_DEST, vq->iov, in, vhost_len);
>  		fixup = msg.msg_iter;
> -		if (unlikely((vhost_hlen))) {
> -			/* We will supply the header ourselves
> -			 * TODO: support TSO.
> +		if (unlikely(vhost_hlen)) {
> +			/*
> +			 * Build virtio_net_hdr from the socket skb before
> +			 * recvmsg consumes it. Skip for ptr_ring backends
> +			 * where the skb is not on sk_receive_queue.
>  			 */
> +			if (!nvq->rx_ring &&
> +			    vhost_net_hdr_from_sock(vq, sock->sk, &hdr)) {
> +				vq_err(vq, "Failed to build vnet_hdr from skb\n");
> +				vhost_discard_vq_desc(vq, headcount, ndesc);
> +				continue;
> +			}
>  			iov_iter_advance(&msg.msg_iter, vhost_hlen);
>  		}
>  		err = sock->ops->recvmsg(sock, &msg,
> @@ -1270,7 +1311,6 @@
>  			 */
>  			iov_iter_advance(&fixup, sizeof(hdr));
>  		}
> -		/* TODO: Should check and handle checksum. */
>  
>  		num_buffers = cpu_to_vhost16(vq, headcount);
>  		if (likely(set_num_buffers) &&


  reply	other threads:[~2026-07-13  7:03 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-13  1:04 [PATCH] vhost/net: Fill virtio_net_hdr GSO/csum metadata on RX weimin xiong
2026-07-13  7:03 ` Michael S. Tsirkin [this message]
2026-07-13  8:04   ` Xiong Weimin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260713025549-mutt-send-email-mst@kernel.org \
    --to=mst@redhat.com \
    --cc=15927021679@163.com \
    --cc=jasowang@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=virtualization@vger.kernel.org \
    --cc=xiongweimin@kylinos.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.