* [PATCH v2] virtio_net: Fix mismatched buf address when unmapping for small packets
@ 2024-09-04 6:10 Wenbo Li
2024-09-04 6:31 ` Jason Wang
2024-09-04 6:45 ` Xuan Zhuo
0 siblings, 2 replies; 6+ messages in thread
From: Wenbo Li @ 2024-09-04 6:10 UTC (permalink / raw)
To: mst, jasowang, xuanzhuo, eperezma, davem, edumazet, kuba, pabeni
Cc: virtualization, netdev, linux-kernel, Wenbo Li, Jiahui Cen,
Ying Fang
Currently, the virtio-net driver will perform a pre-dma-mapping for
small or mergeable RX buffer. But for small packets, a mismatched address
without VIRTNET_RX_PAD and xdp_headroom is used for unmapping.
That will result in unsynchronized buffers when SWIOTLB is enabled, for
example, when running as a TDX guest.
This patch handles small and mergeable packets separately and fixes
the mismatched buffer address.
Changes from v1: Use ctx to get xdp_headroom.
Fixes: 295525e29a5b ("virtio_net: merge dma operations when filling mergeable buffers")
Signed-off-by: Wenbo Li <liwenbo.martin@bytedance.com>
Signed-off-by: Jiahui Cen <cenjiahui@bytedance.com>
Signed-off-by: Ying Fang <fangying.tommy@bytedance.com>
---
drivers/net/virtio_net.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c6af18948..cbc3c0ae4 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -891,6 +891,23 @@ static void *virtnet_rq_get_buf(struct receive_queue *rq, u32 *len, void **ctx)
return buf;
}
+static void *virtnet_rq_get_buf_small(struct receive_queue *rq,
+ u32 *len,
+ void **ctx,
+ unsigned int header_offset)
+{
+ void *buf;
+ unsigned int xdp_headroom;
+
+ buf = virtqueue_get_buf_ctx(rq->vq, len, ctx);
+ if (buf) {
+ xdp_headroom = (unsigned long)*ctx;
+ virtnet_rq_unmap(rq, buf + VIRTNET_RX_PAD + xdp_headroom, *len);
+ }
+
+ return buf;
+}
+
static void virtnet_rq_init_one_sg(struct receive_queue *rq, void *buf, u32 len)
{
struct virtnet_rq_dma *dma;
@@ -2692,13 +2709,23 @@ static int virtnet_receive_packets(struct virtnet_info *vi,
int packets = 0;
void *buf;
- if (!vi->big_packets || vi->mergeable_rx_bufs) {
+ if (vi->mergeable_rx_bufs) {
void *ctx;
while (packets < budget &&
(buf = virtnet_rq_get_buf(rq, &len, &ctx))) {
receive_buf(vi, rq, buf, len, ctx, xdp_xmit, stats);
packets++;
}
+ } else if (!vi->big_packets) {
+ void *ctx;
+ unsigned int xdp_headroom = virtnet_get_headroom(vi);
+ unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
+
+ while (packets < budget &&
+ (buf = virtnet_rq_get_buf_small(rq, &len, &ctx, header_offset))) {
+ receive_buf(vi, rq, buf, len, ctx, xdp_xmit, stats);
+ packets++;
+ }
} else {
while (packets < budget &&
(buf = virtqueue_get_buf(rq->vq, &len)) != NULL) {
--
2.20.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH v2] virtio_net: Fix mismatched buf address when unmapping for small packets 2024-09-04 6:10 [PATCH v2] virtio_net: Fix mismatched buf address when unmapping for small packets Wenbo Li @ 2024-09-04 6:31 ` Jason Wang 2024-09-04 6:45 ` Xuan Zhuo 1 sibling, 0 replies; 6+ messages in thread From: Jason Wang @ 2024-09-04 6:31 UTC (permalink / raw) To: Wenbo Li Cc: mst, xuanzhuo, eperezma, davem, edumazet, kuba, pabeni, virtualization, netdev, linux-kernel, Jiahui Cen, Ying Fang On Wed, Sep 4, 2024 at 2:10 PM Wenbo Li <liwenbo.martin@bytedance.com> wrote: > > Currently, the virtio-net driver will perform a pre-dma-mapping for > small or mergeable RX buffer. But for small packets, a mismatched address > without VIRTNET_RX_PAD and xdp_headroom is used for unmapping. > > That will result in unsynchronized buffers when SWIOTLB is enabled, for > example, when running as a TDX guest. > > This patch handles small and mergeable packets separately and fixes > the mismatched buffer address. > > Changes from v1: Use ctx to get xdp_headroom. > > Fixes: 295525e29a5b ("virtio_net: merge dma operations when filling mergeable buffers") > Signed-off-by: Wenbo Li <liwenbo.martin@bytedance.com> > Signed-off-by: Jiahui Cen <cenjiahui@bytedance.com> > Signed-off-by: Ying Fang <fangying.tommy@bytedance.com> > --- > drivers/net/virtio_net.c | 29 ++++++++++++++++++++++++++++- > 1 file changed, 28 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index c6af18948..cbc3c0ae4 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -891,6 +891,23 @@ static void *virtnet_rq_get_buf(struct receive_queue *rq, u32 *len, void **ctx) > return buf; > } > > +static void *virtnet_rq_get_buf_small(struct receive_queue *rq, > + u32 *len, > + void **ctx, > + unsigned int header_offset) header_offset is unused? > +{ > + void *buf; > + unsigned int xdp_headroom; > + > + buf = virtqueue_get_buf_ctx(rq->vq, len, ctx); > + if (buf) { > + xdp_headroom = (unsigned long)*ctx; > + virtnet_rq_unmap(rq, buf + VIRTNET_RX_PAD + xdp_headroom, *len); > + } > + > + return buf; > +} > + > static void virtnet_rq_init_one_sg(struct receive_queue *rq, void *buf, u32 len) > { > struct virtnet_rq_dma *dma; > @@ -2692,13 +2709,23 @@ static int virtnet_receive_packets(struct virtnet_info *vi, > int packets = 0; > void *buf; > > - if (!vi->big_packets || vi->mergeable_rx_bufs) { > + if (vi->mergeable_rx_bufs) { > void *ctx; > while (packets < budget && > (buf = virtnet_rq_get_buf(rq, &len, &ctx))) { > receive_buf(vi, rq, buf, len, ctx, xdp_xmit, stats); > packets++; > } > + } else if (!vi->big_packets) { > + void *ctx; > + unsigned int xdp_headroom = virtnet_get_headroom(vi); > + unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom; > + > + while (packets < budget && > + (buf = virtnet_rq_get_buf_small(rq, &len, &ctx, header_offset))) { > + receive_buf(vi, rq, buf, len, ctx, xdp_xmit, stats); > + packets++; > + } > } else { > while (packets < budget && > (buf = virtqueue_get_buf(rq->vq, &len)) != NULL) { > -- > 2.20.1 > Thanks ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] virtio_net: Fix mismatched buf address when unmapping for small packets 2024-09-04 6:10 [PATCH v2] virtio_net: Fix mismatched buf address when unmapping for small packets Wenbo Li 2024-09-04 6:31 ` Jason Wang @ 2024-09-04 6:45 ` Xuan Zhuo [not found] ` <CABwj4+hMwUQ+=m+XyG=66e+PUbOzOvHEsQzboB17DE+3aBHA3g@mail.gmail.com> 1 sibling, 1 reply; 6+ messages in thread From: Xuan Zhuo @ 2024-09-04 6:45 UTC (permalink / raw) To: Wenbo Li Cc: virtualization, netdev, linux-kernel, Wenbo Li, Jiahui Cen, Ying Fang, mst, jasowang, eperezma, davem, edumazet, kuba, pabeni On Wed, 4 Sep 2024 14:10:09 +0800, Wenbo Li <liwenbo.martin@bytedance.com> wrote: > Currently, the virtio-net driver will perform a pre-dma-mapping for > small or mergeable RX buffer. But for small packets, a mismatched address > without VIRTNET_RX_PAD and xdp_headroom is used for unmapping. Will used virt_to_head_page(), so could you say more about it? struct page *page = virt_to_head_page(buf); Thanks. > > That will result in unsynchronized buffers when SWIOTLB is enabled, for > example, when running as a TDX guest. > > This patch handles small and mergeable packets separately and fixes > the mismatched buffer address. > > Changes from v1: Use ctx to get xdp_headroom. > > Fixes: 295525e29a5b ("virtio_net: merge dma operations when filling mergeable buffers") > Signed-off-by: Wenbo Li <liwenbo.martin@bytedance.com> > Signed-off-by: Jiahui Cen <cenjiahui@bytedance.com> > Signed-off-by: Ying Fang <fangying.tommy@bytedance.com> > --- > drivers/net/virtio_net.c | 29 ++++++++++++++++++++++++++++- > 1 file changed, 28 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index c6af18948..cbc3c0ae4 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -891,6 +891,23 @@ static void *virtnet_rq_get_buf(struct receive_queue *rq, u32 *len, void **ctx) > return buf; > } > > +static void *virtnet_rq_get_buf_small(struct receive_queue *rq, > + u32 *len, > + void **ctx, > + unsigned int header_offset) > +{ > + void *buf; > + unsigned int xdp_headroom; > + > + buf = virtqueue_get_buf_ctx(rq->vq, len, ctx); > + if (buf) { > + xdp_headroom = (unsigned long)*ctx; > + virtnet_rq_unmap(rq, buf + VIRTNET_RX_PAD + xdp_headroom, *len); > + } > + > + return buf; > +} > + > static void virtnet_rq_init_one_sg(struct receive_queue *rq, void *buf, u32 len) > { > struct virtnet_rq_dma *dma; > @@ -2692,13 +2709,23 @@ static int virtnet_receive_packets(struct virtnet_info *vi, > int packets = 0; > void *buf; > > - if (!vi->big_packets || vi->mergeable_rx_bufs) { > + if (vi->mergeable_rx_bufs) { > void *ctx; > while (packets < budget && > (buf = virtnet_rq_get_buf(rq, &len, &ctx))) { > receive_buf(vi, rq, buf, len, ctx, xdp_xmit, stats); > packets++; > } > + } else if (!vi->big_packets) { > + void *ctx; > + unsigned int xdp_headroom = virtnet_get_headroom(vi); > + unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom; > + > + while (packets < budget && > + (buf = virtnet_rq_get_buf_small(rq, &len, &ctx, header_offset))) { > + receive_buf(vi, rq, buf, len, ctx, xdp_xmit, stats); > + packets++; > + } > } else { > while (packets < budget && > (buf = virtqueue_get_buf(rq->vq, &len)) != NULL) { > -- > 2.20.1 > ^ permalink raw reply [flat|nested] 6+ messages in thread
[parent not found: <CABwj4+hMwUQ+=m+XyG=66e+PUbOzOvHEsQzboB17DE+3aBHA3g@mail.gmail.com>]
* Re: [External] Re: [PATCH v2] virtio_net: Fix mismatched buf address when unmapping for small packets [not found] ` <CABwj4+hMwUQ+=m+XyG=66e+PUbOzOvHEsQzboB17DE+3aBHA3g@mail.gmail.com> @ 2024-09-04 7:30 ` Xuan Zhuo 2024-09-04 7:51 ` Wenbo Li 2024-09-04 10:57 ` Michael S. Tsirkin 0 siblings, 2 replies; 6+ messages in thread From: Xuan Zhuo @ 2024-09-04 7:30 UTC (permalink / raw) To: 文博李 Cc: virtualization, netdev, linux-kernel, Jiahui Cen, Ying Fang, mst, jasowang, eperezma, davem, edumazet, kuba, pabeni On Wed, 4 Sep 2024 15:21:28 +0800, =?utf-8?b?5paH5Y2a5p2O?= <liwenbo.martin@bytedance.com> wrote: > When SWIOTLB is enabled, a DMA map will allocate a bounce buffer for real > DMA operations, > and when unmapping, SWIOTLB copies the content in the bounce buffer to the > driver-allocated > buffer (the `buf` variable). Such copy only synchronizes data in the buffer > range, not the whole page. > So we should give the correct offset for DMA unmapping. I see. But I think we should pass the "correct" buf to virtio core as the "data" by virtqueue_add_inbuf_ctx(). In the merge mode, we pass the pointer that points to the virtnet header. In the small mode, we pass the pointer that points to the virtnet header - offset. But this is not the only problem, we try to get the virtnet header by the buf inside receive_buf(before receive_small). flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags; So I think it is time to unify the buf that passed to the virtio core into a pointer pointed to the virtnet header. Thanks. > > Thanks. > > On Wed, Sep 4, 2024 at 2:46 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote: > > > > On Wed, 4 Sep 2024 14:10:09 +0800, Wenbo Li <liwenbo.martin@bytedance.com> > wrote: > > > Currently, the virtio-net driver will perform a pre-dma-mapping for > > > small or mergeable RX buffer. But for small packets, a mismatched > address > > > without VIRTNET_RX_PAD and xdp_headroom is used for unmapping. > > > > Will used virt_to_head_page(), so could you say more about it? > > > > struct page *page = virt_to_head_page(buf); > > > > Thanks. > > > > > > > > That will result in unsynchronized buffers when SWIOTLB is enabled, for > > > example, when running as a TDX guest. > > > > > > This patch handles small and mergeable packets separately and fixes > > > the mismatched buffer address. > > > > > > Changes from v1: Use ctx to get xdp_headroom. > > > > > > Fixes: 295525e29a5b ("virtio_net: merge dma operations when filling > mergeable buffers") > > > Signed-off-by: Wenbo Li <liwenbo.martin@bytedance.com> > > > Signed-off-by: Jiahui Cen <cenjiahui@bytedance.com> > > > Signed-off-by: Ying Fang <fangying.tommy@bytedance.com> > > > --- > > > drivers/net/virtio_net.c | 29 ++++++++++++++++++++++++++++- > > > 1 file changed, 28 insertions(+), 1 deletion(-) > > > > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > > > index c6af18948..cbc3c0ae4 100644 > > > --- a/drivers/net/virtio_net.c > > > +++ b/drivers/net/virtio_net.c > > > @@ -891,6 +891,23 @@ static void *virtnet_rq_get_buf(struct > receive_queue *rq, u32 *len, void **ctx) > > > return buf; > > > } > > > > > > +static void *virtnet_rq_get_buf_small(struct receive_queue *rq, > > > + u32 *len, > > > + void **ctx, > > > + unsigned int header_offset) > > > +{ > > > + void *buf; > > > + unsigned int xdp_headroom; > > > + > > > + buf = virtqueue_get_buf_ctx(rq->vq, len, ctx); > > > + if (buf) { > > > + xdp_headroom = (unsigned long)*ctx; > > > + virtnet_rq_unmap(rq, buf + VIRTNET_RX_PAD + xdp_headroom, > *len); > > > + } > > > + > > > + return buf; > > > +} > > > + > > > static void virtnet_rq_init_one_sg(struct receive_queue *rq, void > *buf, u32 len) > > > { > > > struct virtnet_rq_dma *dma; > > > @@ -2692,13 +2709,23 @@ static int virtnet_receive_packets(struct > virtnet_info *vi, > > > int packets = 0; > > > void *buf; > > > > > > - if (!vi->big_packets || vi->mergeable_rx_bufs) { > > > + if (vi->mergeable_rx_bufs) { > > > void *ctx; > > > while (packets < budget && > > > (buf = virtnet_rq_get_buf(rq, &len, &ctx))) { > > > receive_buf(vi, rq, buf, len, ctx, xdp_xmit, > stats); > > > packets++; > > > } > > > + } else if (!vi->big_packets) { > > > + void *ctx; > > > + unsigned int xdp_headroom = virtnet_get_headroom(vi); > > > + unsigned int header_offset = VIRTNET_RX_PAD + > xdp_headroom; > > > + > > > + while (packets < budget && > > > + (buf = virtnet_rq_get_buf_small(rq, &len, &ctx, > header_offset))) { > > > + receive_buf(vi, rq, buf, len, ctx, xdp_xmit, > stats); > > > + packets++; > > > + } > > > } else { > > > while (packets < budget && > > > (buf = virtqueue_get_buf(rq->vq, &len)) != NULL) { > > > -- > > > 2.20.1 > > > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [External] Re: [PATCH v2] virtio_net: Fix mismatched buf address when unmapping for small packets 2024-09-04 7:30 ` [External] " Xuan Zhuo @ 2024-09-04 7:51 ` Wenbo Li 2024-09-04 10:57 ` Michael S. Tsirkin 1 sibling, 0 replies; 6+ messages in thread From: Wenbo Li @ 2024-09-04 7:51 UTC (permalink / raw) To: Xuan Zhuo Cc: virtualization, netdev, linux-kernel, Jiahui Cen, Ying Fang, mst, jasowang, eperezma, davem, edumazet, kuba, pabeni Thank you. I'll fix these in v3. On 9/4/24 15:30, Xuan Zhuo wrote: > On Wed, 4 Sep 2024 15:21:28 +0800, =?utf-8?b?5paH5Y2a5p2O?= <liwenbo.martin@bytedance.com> wrote: >> When SWIOTLB is enabled, a DMA map will allocate a bounce buffer for real >> DMA operations, >> and when unmapping, SWIOTLB copies the content in the bounce buffer to the >> driver-allocated >> buffer (the `buf` variable). Such copy only synchronizes data in the buffer >> range, not the whole page. >> So we should give the correct offset for DMA unmapping. > I see. > > But I think we should pass the "correct" buf to virtio core as the "data" by > virtqueue_add_inbuf_ctx(). > > In the merge mode, we pass the pointer that points to the virtnet header. > In the small mode, we pass the pointer that points to the virtnet header - offset. > > But this is not the only problem, we try to get the virtnet header by the buf > inside receive_buf(before receive_small). > > flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags; > > So I think it is time to unify the buf that passed to the virtio core into a > pointer pointed to the virtnet header. > > Thanks. > > >> Thanks. >> >> On Wed, Sep 4, 2024 at 2:46 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote: >>> On Wed, 4 Sep 2024 14:10:09 +0800, Wenbo Li <liwenbo.martin@bytedance.com> >> wrote: >>>> Currently, the virtio-net driver will perform a pre-dma-mapping for >>>> small or mergeable RX buffer. But for small packets, a mismatched >> address >>>> without VIRTNET_RX_PAD and xdp_headroom is used for unmapping. >>> Will used virt_to_head_page(), so could you say more about it? >>> >>> struct page *page = virt_to_head_page(buf); >>> >>> Thanks. >>> >>>> That will result in unsynchronized buffers when SWIOTLB is enabled, for >>>> example, when running as a TDX guest. >>>> >>>> This patch handles small and mergeable packets separately and fixes >>>> the mismatched buffer address. >>>> >>>> Changes from v1: Use ctx to get xdp_headroom. >>>> >>>> Fixes: 295525e29a5b ("virtio_net: merge dma operations when filling >> mergeable buffers") >>>> Signed-off-by: Wenbo Li <liwenbo.martin@bytedance.com> >>>> Signed-off-by: Jiahui Cen <cenjiahui@bytedance.com> >>>> Signed-off-by: Ying Fang <fangying.tommy@bytedance.com> >>>> --- >>>> drivers/net/virtio_net.c | 29 ++++++++++++++++++++++++++++- >>>> 1 file changed, 28 insertions(+), 1 deletion(-) >>>> >>>> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c >>>> index c6af18948..cbc3c0ae4 100644 >>>> --- a/drivers/net/virtio_net.c >>>> +++ b/drivers/net/virtio_net.c >>>> @@ -891,6 +891,23 @@ static void *virtnet_rq_get_buf(struct >> receive_queue *rq, u32 *len, void **ctx) >>>> return buf; >>>> } >>>> >>>> +static void *virtnet_rq_get_buf_small(struct receive_queue *rq, >>>> + u32 *len, >>>> + void **ctx, >>>> + unsigned int header_offset) >>>> +{ >>>> + void *buf; >>>> + unsigned int xdp_headroom; >>>> + >>>> + buf = virtqueue_get_buf_ctx(rq->vq, len, ctx); >>>> + if (buf) { >>>> + xdp_headroom = (unsigned long)*ctx; >>>> + virtnet_rq_unmap(rq, buf + VIRTNET_RX_PAD + xdp_headroom, >> *len); >>>> + } >>>> + >>>> + return buf; >>>> +} >>>> + >>>> static void virtnet_rq_init_one_sg(struct receive_queue *rq, void >> *buf, u32 len) >>>> { >>>> struct virtnet_rq_dma *dma; >>>> @@ -2692,13 +2709,23 @@ static int virtnet_receive_packets(struct >> virtnet_info *vi, >>>> int packets = 0; >>>> void *buf; >>>> >>>> - if (!vi->big_packets || vi->mergeable_rx_bufs) { >>>> + if (vi->mergeable_rx_bufs) { >>>> void *ctx; >>>> while (packets < budget && >>>> (buf = virtnet_rq_get_buf(rq, &len, &ctx))) { >>>> receive_buf(vi, rq, buf, len, ctx, xdp_xmit, >> stats); >>>> packets++; >>>> } >>>> + } else if (!vi->big_packets) { >>>> + void *ctx; >>>> + unsigned int xdp_headroom = virtnet_get_headroom(vi); >>>> + unsigned int header_offset = VIRTNET_RX_PAD + >> xdp_headroom; >>>> + >>>> + while (packets < budget && >>>> + (buf = virtnet_rq_get_buf_small(rq, &len, &ctx, >> header_offset))) { >>>> + receive_buf(vi, rq, buf, len, ctx, xdp_xmit, >> stats); >>>> + packets++; >>>> + } >>>> } else { >>>> while (packets < budget && >>>> (buf = virtqueue_get_buf(rq->vq, &len)) != NULL) { >>>> -- >>>> 2.20.1 >>>> ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [External] Re: [PATCH v2] virtio_net: Fix mismatched buf address when unmapping for small packets 2024-09-04 7:30 ` [External] " Xuan Zhuo 2024-09-04 7:51 ` Wenbo Li @ 2024-09-04 10:57 ` Michael S. Tsirkin 1 sibling, 0 replies; 6+ messages in thread From: Michael S. Tsirkin @ 2024-09-04 10:57 UTC (permalink / raw) To: Xuan Zhuo Cc: 文博李, virtualization, netdev, linux-kernel, Jiahui Cen, Ying Fang, jasowang, eperezma, davem, edumazet, kuba, pabeni On Wed, Sep 04, 2024 at 03:30:02PM +0800, Xuan Zhuo wrote: > On Wed, 4 Sep 2024 15:21:28 +0800, =?utf-8?b?5paH5Y2a5p2O?= <liwenbo.martin@bytedance.com> wrote: > > When SWIOTLB is enabled, a DMA map will allocate a bounce buffer for real > > DMA operations, > > and when unmapping, SWIOTLB copies the content in the bounce buffer to the > > driver-allocated > > buffer (the `buf` variable). Such copy only synchronizes data in the buffer > > range, not the whole page. > > So we should give the correct offset for DMA unmapping. > > I see. > > But I think we should pass the "correct" buf to virtio core as the "data" by > virtqueue_add_inbuf_ctx(). > > In the merge mode, we pass the pointer that points to the virtnet header. > In the small mode, we pass the pointer that points to the virtnet header - offset. > > But this is not the only problem, we try to get the virtnet header by the buf > inside receive_buf(before receive_small). > > flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags; > > So I think it is time to unify the buf that passed to the virtio core into a > pointer pointed to the virtnet header. > > Thanks. Hard to say without seeing what is proposed, but I think data pointer is opaque to virtio, it does not have to point to anything specific - just !NULL. > > > > > Thanks. > > > > On Wed, Sep 4, 2024 at 2:46 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote: > > > > > > On Wed, 4 Sep 2024 14:10:09 +0800, Wenbo Li <liwenbo.martin@bytedance.com> > > wrote: > > > > Currently, the virtio-net driver will perform a pre-dma-mapping for > > > > small or mergeable RX buffer. But for small packets, a mismatched > > address > > > > without VIRTNET_RX_PAD and xdp_headroom is used for unmapping. > > > > > > Will used virt_to_head_page(), so could you say more about it? > > > > > > struct page *page = virt_to_head_page(buf); > > > > > > Thanks. > > > > > > > > > > > That will result in unsynchronized buffers when SWIOTLB is enabled, for > > > > example, when running as a TDX guest. > > > > > > > > This patch handles small and mergeable packets separately and fixes > > > > the mismatched buffer address. > > > > > > > > Changes from v1: Use ctx to get xdp_headroom. > > > > > > > > Fixes: 295525e29a5b ("virtio_net: merge dma operations when filling > > mergeable buffers") > > > > Signed-off-by: Wenbo Li <liwenbo.martin@bytedance.com> > > > > Signed-off-by: Jiahui Cen <cenjiahui@bytedance.com> > > > > Signed-off-by: Ying Fang <fangying.tommy@bytedance.com> > > > > --- > > > > drivers/net/virtio_net.c | 29 ++++++++++++++++++++++++++++- > > > > 1 file changed, 28 insertions(+), 1 deletion(-) > > > > > > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > > > > index c6af18948..cbc3c0ae4 100644 > > > > --- a/drivers/net/virtio_net.c > > > > +++ b/drivers/net/virtio_net.c > > > > @@ -891,6 +891,23 @@ static void *virtnet_rq_get_buf(struct > > receive_queue *rq, u32 *len, void **ctx) > > > > return buf; > > > > } > > > > > > > > +static void *virtnet_rq_get_buf_small(struct receive_queue *rq, > > > > + u32 *len, > > > > + void **ctx, > > > > + unsigned int header_offset) > > > > +{ > > > > + void *buf; > > > > + unsigned int xdp_headroom; > > > > + > > > > + buf = virtqueue_get_buf_ctx(rq->vq, len, ctx); > > > > + if (buf) { > > > > + xdp_headroom = (unsigned long)*ctx; > > > > + virtnet_rq_unmap(rq, buf + VIRTNET_RX_PAD + xdp_headroom, > > *len); > > > > + } > > > > + > > > > + return buf; > > > > +} > > > > + > > > > static void virtnet_rq_init_one_sg(struct receive_queue *rq, void > > *buf, u32 len) > > > > { > > > > struct virtnet_rq_dma *dma; > > > > @@ -2692,13 +2709,23 @@ static int virtnet_receive_packets(struct > > virtnet_info *vi, > > > > int packets = 0; > > > > void *buf; > > > > > > > > - if (!vi->big_packets || vi->mergeable_rx_bufs) { > > > > + if (vi->mergeable_rx_bufs) { > > > > void *ctx; > > > > while (packets < budget && > > > > (buf = virtnet_rq_get_buf(rq, &len, &ctx))) { > > > > receive_buf(vi, rq, buf, len, ctx, xdp_xmit, > > stats); > > > > packets++; > > > > } > > > > + } else if (!vi->big_packets) { > > > > + void *ctx; > > > > + unsigned int xdp_headroom = virtnet_get_headroom(vi); > > > > + unsigned int header_offset = VIRTNET_RX_PAD + > > xdp_headroom; > > > > + > > > > + while (packets < budget && > > > > + (buf = virtnet_rq_get_buf_small(rq, &len, &ctx, > > header_offset))) { > > > > + receive_buf(vi, rq, buf, len, ctx, xdp_xmit, > > stats); > > > > + packets++; > > > > + } > > > > } else { > > > > while (packets < budget && > > > > (buf = virtqueue_get_buf(rq->vq, &len)) != NULL) { > > > > -- > > > > 2.20.1 > > > > > > ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-09-04 10:57 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-04 6:10 [PATCH v2] virtio_net: Fix mismatched buf address when unmapping for small packets Wenbo Li
2024-09-04 6:31 ` Jason Wang
2024-09-04 6:45 ` Xuan Zhuo
[not found] ` <CABwj4+hMwUQ+=m+XyG=66e+PUbOzOvHEsQzboB17DE+3aBHA3g@mail.gmail.com>
2024-09-04 7:30 ` [External] " Xuan Zhuo
2024-09-04 7:51 ` Wenbo Li
2024-09-04 10:57 ` 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).