* [PATCH net-next] virtio_net: sync RX buffer before reading the header
@ 2026-03-24 15:15 Michael S. Tsirkin
2026-03-25 13:20 ` Vishwanath Seshagiri
2026-03-26 2:09 ` Jason Wang
0 siblings, 2 replies; 3+ messages in thread
From: Michael S. Tsirkin @ 2026-03-24 15:15 UTC (permalink / raw)
To: linux-kernel
Cc: Omar Elghoul, Srikanth Aithal, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev,
Vishwanath Seshagiri, netdev, virtualization, bpf
receive_buf() reads the virtio header through buf before
page_pool_dma_sync_for_cpu() runs in receive_small() or
receive_mergeable(). The header buffer is thus unsynchronized at the
point where flags and, for mergeable buffers, num_buffers are consumed.
Omar Elghoul reported that on s390x Secure Execution this showed up as
greatly reduced virtio-net performance together with "bad gso" and
"bad csum" messages in dmesg. This is because with SE sync actually
copies data, so the header is uninitialized.
Move the sync into receive_buf() so the
header is synchronized before any access through buf.
Tool use: Cursor with GPT-5.4 drafted the initial code move from prompt:
"in drivers/net/virtio_net.c, move page_pool_dma_sync_for_cpu on receive
path to before memory is accessed through buf".
The result and the commit log were reviewed and edited manually.
Fixes: 168b61da6871 ("virtio_net: add page_pool support for buffer allocation")
Reported-by: Omar Elghoul <oelghoul@linux.ibm.com>
Tested-by: Srikanth Aithal <sraithal@amd.com>
Tested-by: Omar Elghoul <oelghoul@linux.ibm.com>
Link: https://lore.kernel.org/r/20260323150136.14452-1-oelghoul@linux.ibm.com
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
drivers/net/virtio_net.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 97035b49bae7..2f57245c682d 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1956,13 +1956,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
*/
buf -= VIRTNET_RX_PAD + xdp_headroom;
- if (rq->use_page_pool_dma) {
- int offset = buf - page_address(page) +
- VIRTNET_RX_PAD + xdp_headroom;
-
- page_pool_dma_sync_for_cpu(rq->page_pool, page, offset, len);
- }
-
len -= vi->hdr_len;
u64_stats_add(&stats->bytes, len);
@@ -2398,9 +2391,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
head_skb = NULL;
- if (rq->use_page_pool_dma)
- page_pool_dma_sync_for_cpu(rq->page_pool, page, offset, len);
-
u64_stats_add(&stats->bytes, len - vi->hdr_len);
if (check_mergeable_len(dev, ctx, len))
@@ -2563,6 +2553,16 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
return;
}
+ /* Sync the memory before touching anything through buf,
+ * unless virtio core did it already.
+ */
+ if (rq->use_page_pool_dma) {
+ struct page *page = virt_to_head_page(buf);
+ int offset = buf - page_address(page);
+
+ page_pool_dma_sync_for_cpu(rq->page_pool, page, offset, len);
+ }
+
/* About the flags below:
* 1. Save the flags early, as the XDP program might overwrite them.
* These flags ensure packets marked as VIRTIO_NET_HDR_F_DATA_VALID
--
MST
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH net-next] virtio_net: sync RX buffer before reading the header
2026-03-24 15:15 [PATCH net-next] virtio_net: sync RX buffer before reading the header Michael S. Tsirkin
@ 2026-03-25 13:20 ` Vishwanath Seshagiri
2026-03-26 2:09 ` Jason Wang
1 sibling, 0 replies; 3+ messages in thread
From: Vishwanath Seshagiri @ 2026-03-25 13:20 UTC (permalink / raw)
To: Michael S. Tsirkin, linux-kernel
Cc: Omar Elghoul, Srikanth Aithal, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev,
netdev, virtualization, bpf
On 3/24/26 11:15 AM, Michael S. Tsirkin wrote:
> receive_buf() reads the virtio header through buf before
> page_pool_dma_sync_for_cpu() runs in receive_small() or
> receive_mergeable(). The header buffer is thus unsynchronized at the
> point where flags and, for mergeable buffers, num_buffers are consumed.
>
> Omar Elghoul reported that on s390x Secure Execution this showed up as
> greatly reduced virtio-net performance together with "bad gso" and
> "bad csum" messages in dmesg. This is because with SE sync actually
> copies data, so the header is uninitialized.
>
> Move the sync into receive_buf() so the
> header is synchronized before any access through buf.
>
> Tool use: Cursor with GPT-5.4 drafted the initial code move from prompt:
> "in drivers/net/virtio_net.c, move page_pool_dma_sync_for_cpu on receive
> path to before memory is accessed through buf".
> The result and the commit log were reviewed and edited manually.
>
> Fixes: 168b61da6871 ("virtio_net: add page_pool support for buffer allocation")
> Reported-by: Omar Elghoul <oelghoul@linux.ibm.com>
> Tested-by: Srikanth Aithal <sraithal@amd.com>
> Tested-by: Omar Elghoul <oelghoul@linux.ibm.com>
> Link: https://lore.kernel.org/r/20260323150136.14452-1-oelghoul@linux.ibm.com
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> drivers/net/virtio_net.c | 20 ++++++++++----------
> 1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 97035b49bae7..2f57245c682d 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1956,13 +1956,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
> */
> buf -= VIRTNET_RX_PAD + xdp_headroom;
>
> - if (rq->use_page_pool_dma) {
> - int offset = buf - page_address(page) +
> - VIRTNET_RX_PAD + xdp_headroom;
> -
> - page_pool_dma_sync_for_cpu(rq->page_pool, page, offset, len);
> - }
> -
> len -= vi->hdr_len;
> u64_stats_add(&stats->bytes, len);
>
> @@ -2398,9 +2391,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
>
> head_skb = NULL;
>
> - if (rq->use_page_pool_dma)
> - page_pool_dma_sync_for_cpu(rq->page_pool, page, offset, len);
> -
> u64_stats_add(&stats->bytes, len - vi->hdr_len);
>
> if (check_mergeable_len(dev, ctx, len))
> @@ -2563,6 +2553,16 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
> return;
> }
>
> + /* Sync the memory before touching anything through buf,
> + * unless virtio core did it already.
> + */
> + if (rq->use_page_pool_dma) {
> + struct page *page = virt_to_head_page(buf);
> + int offset = buf - page_address(page);
> +
> + page_pool_dma_sync_for_cpu(rq->page_pool, page, offset, len);
> + }
> +
> /* About the flags below:
> * 1. Save the flags early, as the XDP program might overwrite them.
> * These flags ensure packets marked as VIRTIO_NET_HDR_F_DATA_VALID
Tested on x86_64 vhost-net/KVM, no regressions
found. I will send out the benchmark numbers soon.
Tested-by: Vishwanath Seshagiri <vishs@meta.com>
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH net-next] virtio_net: sync RX buffer before reading the header
2026-03-24 15:15 [PATCH net-next] virtio_net: sync RX buffer before reading the header Michael S. Tsirkin
2026-03-25 13:20 ` Vishwanath Seshagiri
@ 2026-03-26 2:09 ` Jason Wang
1 sibling, 0 replies; 3+ messages in thread
From: Jason Wang @ 2026-03-26 2:09 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: linux-kernel, Omar Elghoul, Srikanth Aithal, Xuan Zhuo,
Eugenio Pérez, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev,
Vishwanath Seshagiri, netdev, virtualization, bpf
On Tue, Mar 24, 2026 at 11:16 PM Michael S. Tsirkin <mst@redhat.com> wrote:
>
> receive_buf() reads the virtio header through buf before
> page_pool_dma_sync_for_cpu() runs in receive_small() or
> receive_mergeable(). The header buffer is thus unsynchronized at the
> point where flags and, for mergeable buffers, num_buffers are consumed.
>
> Omar Elghoul reported that on s390x Secure Execution this showed up as
> greatly reduced virtio-net performance together with "bad gso" and
> "bad csum" messages in dmesg. This is because with SE sync actually
> copies data, so the header is uninitialized.
>
> Move the sync into receive_buf() so the
> header is synchronized before any access through buf.
>
> Tool use: Cursor with GPT-5.4 drafted the initial code move from prompt:
> "in drivers/net/virtio_net.c, move page_pool_dma_sync_for_cpu on receive
> path to before memory is accessed through buf".
> The result and the commit log were reviewed and edited manually.
>
> Fixes: 168b61da6871 ("virtio_net: add page_pool support for buffer allocation")
> Reported-by: Omar Elghoul <oelghoul@linux.ibm.com>
> Tested-by: Srikanth Aithal <sraithal@amd.com>
> Tested-by: Omar Elghoul <oelghoul@linux.ibm.com>
> Link: https://lore.kernel.org/r/20260323150136.14452-1-oelghoul@linux.ibm.com
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Thanks
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-03-26 2:09 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-24 15:15 [PATCH net-next] virtio_net: sync RX buffer before reading the header Michael S. Tsirkin
2026-03-25 13:20 ` Vishwanath Seshagiri
2026-03-26 2:09 ` Jason Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox