netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net V2] virtio_net: fix alignment for virtio_net_hdr_v1_hash
@ 2025-10-31  6:05 Jason Wang
  2025-11-04 17:21 ` Lei Yang
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Jason Wang @ 2025-10-31  6:05 UTC (permalink / raw)
  To: mst, jasowang, xuanzhuo, eperezma, andrew+netdev, davem, edumazet,
	kuba, pabeni
  Cc: virtualization, netdev, linux-kernel, stable

From: "Michael S. Tsirkin" <mst@redhat.com>

Changing alignment of header would mean it's no longer safe to cast a
2 byte aligned pointer between formats. Use two 16 bit fields to make
it 2 byte aligned as previously.

This fixes the performance regression since
commit ("virtio_net: enable gso over UDP tunnel support.") as it uses
virtio_net_hdr_v1_hash_tunnel which embeds
virtio_net_hdr_v1_hash. Pktgen in guest + XDP_DROP on TAP + vhost_net
shows the TX PPS is recovered from 2.4Mpps to 4.45Mpps.

Fixes: 56a06bd40fab ("virtio_net: enable gso over UDP tunnel support.")
Cc: stable@vger.kernel.org
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
Changes since V1:
- Fix build issues of virtio_net_hdr_tnl_from_skb()
---
 drivers/net/virtio_net.c        | 15 +++++++++++++--
 include/linux/virtio_net.h      |  3 ++-
 include/uapi/linux/virtio_net.h |  3 ++-
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 8e8a179aaa49..e6e650bc3bc3 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2539,6 +2539,13 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	return NULL;
 }
 
+static inline u32
+virtio_net_hash_value(const struct virtio_net_hdr_v1_hash *hdr_hash)
+{
+	return __le16_to_cpu(hdr_hash->hash_value_lo) |
+		(__le16_to_cpu(hdr_hash->hash_value_hi) << 16);
+}
+
 static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash,
 				struct sk_buff *skb)
 {
@@ -2565,7 +2572,7 @@ static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash,
 	default:
 		rss_hash_type = PKT_HASH_TYPE_NONE;
 	}
-	skb_set_hash(skb, __le32_to_cpu(hdr_hash->hash_value), rss_hash_type);
+	skb_set_hash(skb, virtio_net_hash_value(hdr_hash), rss_hash_type);
 }
 
 static void virtnet_receive_done(struct virtnet_info *vi, struct receive_queue *rq,
@@ -3311,6 +3318,10 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb, bool orphan)
 
 	pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest);
 
+	/* Make sure it's safe to cast between formats */
+	BUILD_BUG_ON(__alignof__(*hdr) != __alignof__(hdr->hash_hdr));
+	BUILD_BUG_ON(__alignof__(*hdr) != __alignof__(hdr->hash_hdr.hdr));
+
 	can_push = vi->any_header_sg &&
 		!((unsigned long)skb->data & (__alignof__(*hdr) - 1)) &&
 		!skb_header_cloned(skb) && skb_headroom(skb) >= hdr_len;
@@ -6750,7 +6761,7 @@ static int virtnet_xdp_rx_hash(const struct xdp_md *_ctx, u32 *hash,
 		hash_report = VIRTIO_NET_HASH_REPORT_NONE;
 
 	*rss_type = virtnet_xdp_rss_type[hash_report];
-	*hash = __le32_to_cpu(hdr_hash->hash_value);
+	*hash = virtio_net_hash_value(hdr_hash);
 	return 0;
 }
 
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index 4d1780848d0e..b673c31569f3 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -401,7 +401,8 @@ virtio_net_hdr_tnl_from_skb(const struct sk_buff *skb,
 	if (!tnl_hdr_negotiated)
 		return -EINVAL;
 
-        vhdr->hash_hdr.hash_value = 0;
+	vhdr->hash_hdr.hash_value_lo = 0;
+	vhdr->hash_hdr.hash_value_hi = 0;
         vhdr->hash_hdr.hash_report = 0;
         vhdr->hash_hdr.padding = 0;
 
diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
index 8bf27ab8bcb4..1db45b01532b 100644
--- a/include/uapi/linux/virtio_net.h
+++ b/include/uapi/linux/virtio_net.h
@@ -193,7 +193,8 @@ struct virtio_net_hdr_v1 {
 
 struct virtio_net_hdr_v1_hash {
 	struct virtio_net_hdr_v1 hdr;
-	__le32 hash_value;
+	__le16 hash_value_lo;
+	__le16 hash_value_hi;
 #define VIRTIO_NET_HASH_REPORT_NONE            0
 #define VIRTIO_NET_HASH_REPORT_IPv4            1
 #define VIRTIO_NET_HASH_REPORT_TCPv4           2
-- 
2.31.1


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

* Re: [PATCH net V2] virtio_net: fix alignment for virtio_net_hdr_v1_hash
  2025-10-31  6:05 [PATCH net V2] virtio_net: fix alignment for virtio_net_hdr_v1_hash Jason Wang
@ 2025-11-04 17:21 ` Lei Yang
  2025-11-05  1:30 ` patchwork-bot+netdevbpf
  2025-11-05  7:17 ` Michael S. Tsirkin
  2 siblings, 0 replies; 4+ messages in thread
From: Lei Yang @ 2025-11-04 17:21 UTC (permalink / raw)
  To: Jason Wang
  Cc: mst, xuanzhuo, eperezma, andrew+netdev, davem, edumazet, kuba,
	pabeni, virtualization, netdev, linux-kernel, stable

Tested this patch with virtio-net regression tests, everything works fine.

Tested-by: Lei Yang <leiyang@redhat.com>

On Fri, Oct 31, 2025 at 2:06 PM Jason Wang <jasowang@redhat.com> wrote:
>
> From: "Michael S. Tsirkin" <mst@redhat.com>
>
> Changing alignment of header would mean it's no longer safe to cast a
> 2 byte aligned pointer between formats. Use two 16 bit fields to make
> it 2 byte aligned as previously.
>
> This fixes the performance regression since
> commit ("virtio_net: enable gso over UDP tunnel support.") as it uses
> virtio_net_hdr_v1_hash_tunnel which embeds
> virtio_net_hdr_v1_hash. Pktgen in guest + XDP_DROP on TAP + vhost_net
> shows the TX PPS is recovered from 2.4Mpps to 4.45Mpps.
>
> Fixes: 56a06bd40fab ("virtio_net: enable gso over UDP tunnel support.")
> Cc: stable@vger.kernel.org
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> Changes since V1:
> - Fix build issues of virtio_net_hdr_tnl_from_skb()
> ---
>  drivers/net/virtio_net.c        | 15 +++++++++++++--
>  include/linux/virtio_net.h      |  3 ++-
>  include/uapi/linux/virtio_net.h |  3 ++-
>  3 files changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 8e8a179aaa49..e6e650bc3bc3 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -2539,6 +2539,13 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
>         return NULL;
>  }
>
> +static inline u32
> +virtio_net_hash_value(const struct virtio_net_hdr_v1_hash *hdr_hash)
> +{
> +       return __le16_to_cpu(hdr_hash->hash_value_lo) |
> +               (__le16_to_cpu(hdr_hash->hash_value_hi) << 16);
> +}
> +
>  static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash,
>                                 struct sk_buff *skb)
>  {
> @@ -2565,7 +2572,7 @@ static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash,
>         default:
>                 rss_hash_type = PKT_HASH_TYPE_NONE;
>         }
> -       skb_set_hash(skb, __le32_to_cpu(hdr_hash->hash_value), rss_hash_type);
> +       skb_set_hash(skb, virtio_net_hash_value(hdr_hash), rss_hash_type);
>  }
>
>  static void virtnet_receive_done(struct virtnet_info *vi, struct receive_queue *rq,
> @@ -3311,6 +3318,10 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb, bool orphan)
>
>         pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest);
>
> +       /* Make sure it's safe to cast between formats */
> +       BUILD_BUG_ON(__alignof__(*hdr) != __alignof__(hdr->hash_hdr));
> +       BUILD_BUG_ON(__alignof__(*hdr) != __alignof__(hdr->hash_hdr.hdr));
> +
>         can_push = vi->any_header_sg &&
>                 !((unsigned long)skb->data & (__alignof__(*hdr) - 1)) &&
>                 !skb_header_cloned(skb) && skb_headroom(skb) >= hdr_len;
> @@ -6750,7 +6761,7 @@ static int virtnet_xdp_rx_hash(const struct xdp_md *_ctx, u32 *hash,
>                 hash_report = VIRTIO_NET_HASH_REPORT_NONE;
>
>         *rss_type = virtnet_xdp_rss_type[hash_report];
> -       *hash = __le32_to_cpu(hdr_hash->hash_value);
> +       *hash = virtio_net_hash_value(hdr_hash);
>         return 0;
>  }
>
> diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
> index 4d1780848d0e..b673c31569f3 100644
> --- a/include/linux/virtio_net.h
> +++ b/include/linux/virtio_net.h
> @@ -401,7 +401,8 @@ virtio_net_hdr_tnl_from_skb(const struct sk_buff *skb,
>         if (!tnl_hdr_negotiated)
>                 return -EINVAL;
>
> -        vhdr->hash_hdr.hash_value = 0;
> +       vhdr->hash_hdr.hash_value_lo = 0;
> +       vhdr->hash_hdr.hash_value_hi = 0;
>          vhdr->hash_hdr.hash_report = 0;
>          vhdr->hash_hdr.padding = 0;
>
> diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
> index 8bf27ab8bcb4..1db45b01532b 100644
> --- a/include/uapi/linux/virtio_net.h
> +++ b/include/uapi/linux/virtio_net.h
> @@ -193,7 +193,8 @@ struct virtio_net_hdr_v1 {
>
>  struct virtio_net_hdr_v1_hash {
>         struct virtio_net_hdr_v1 hdr;
> -       __le32 hash_value;
> +       __le16 hash_value_lo;
> +       __le16 hash_value_hi;
>  #define VIRTIO_NET_HASH_REPORT_NONE            0
>  #define VIRTIO_NET_HASH_REPORT_IPv4            1
>  #define VIRTIO_NET_HASH_REPORT_TCPv4           2
> --
> 2.31.1
>
>


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

* Re: [PATCH net V2] virtio_net: fix alignment for virtio_net_hdr_v1_hash
  2025-10-31  6:05 [PATCH net V2] virtio_net: fix alignment for virtio_net_hdr_v1_hash Jason Wang
  2025-11-04 17:21 ` Lei Yang
@ 2025-11-05  1:30 ` patchwork-bot+netdevbpf
  2025-11-05  7:17 ` Michael S. Tsirkin
  2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-11-05  1:30 UTC (permalink / raw)
  To: Jason Wang
  Cc: mst, xuanzhuo, eperezma, andrew+netdev, davem, edumazet, kuba,
	pabeni, virtualization, netdev, linux-kernel, stable

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Fri, 31 Oct 2025 14:05:51 +0800 you wrote:
> From: "Michael S. Tsirkin" <mst@redhat.com>
> 
> Changing alignment of header would mean it's no longer safe to cast a
> 2 byte aligned pointer between formats. Use two 16 bit fields to make
> it 2 byte aligned as previously.
> 
> This fixes the performance regression since
> commit ("virtio_net: enable gso over UDP tunnel support.") as it uses
> virtio_net_hdr_v1_hash_tunnel which embeds
> virtio_net_hdr_v1_hash. Pktgen in guest + XDP_DROP on TAP + vhost_net
> shows the TX PPS is recovered from 2.4Mpps to 4.45Mpps.
> 
> [...]

Here is the summary with links:
  - [net,V2] virtio_net: fix alignment for virtio_net_hdr_v1_hash
    https://git.kernel.org/netdev/net/c/c3838262b824

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

* Re: [PATCH net V2] virtio_net: fix alignment for virtio_net_hdr_v1_hash
  2025-10-31  6:05 [PATCH net V2] virtio_net: fix alignment for virtio_net_hdr_v1_hash Jason Wang
  2025-11-04 17:21 ` Lei Yang
  2025-11-05  1:30 ` patchwork-bot+netdevbpf
@ 2025-11-05  7:17 ` Michael S. Tsirkin
  2 siblings, 0 replies; 4+ messages in thread
From: Michael S. Tsirkin @ 2025-11-05  7:17 UTC (permalink / raw)
  To: Jason Wang
  Cc: xuanzhuo, eperezma, andrew+netdev, davem, edumazet, kuba, pabeni,
	virtualization, netdev, linux-kernel, stable

On Fri, Oct 31, 2025 at 02:05:51PM +0800, Jason Wang wrote:
> diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
> index 4d1780848d0e..b673c31569f3 100644
> --- a/include/linux/virtio_net.h
> +++ b/include/linux/virtio_net.h
> @@ -401,7 +401,8 @@ virtio_net_hdr_tnl_from_skb(const struct sk_buff *skb,
>  	if (!tnl_hdr_negotiated)
>  		return -EINVAL;
>  
> -        vhdr->hash_hdr.hash_value = 0;
> +	vhdr->hash_hdr.hash_value_lo = 0;
> +	vhdr->hash_hdr.hash_value_hi = 0;
>          vhdr->hash_hdr.hash_report = 0;
>          vhdr->hash_hdr.padding = 0;
>  

BTW is it just me or is old code space-indented here?
We should probably switch it to tabs.

-- 
MST


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

end of thread, other threads:[~2025-11-05  7:17 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-31  6:05 [PATCH net V2] virtio_net: fix alignment for virtio_net_hdr_v1_hash Jason Wang
2025-11-04 17:21 ` Lei Yang
2025-11-05  1:30 ` patchwork-bot+netdevbpf
2025-11-05  7:17 ` Michael S. Tsirkin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).