Skip to content

Commit 1daa879

Browse files
mstsirkindavem330
authored andcommitted
virtio_net: fix truesize for mergeable buffers
Seth Forshee noticed a performance degradation with some workloads. This turns out to be due to packet drops. Euan Kemp noticed that this is because we drop all packets where length exceeds the truesize, but for some packets we add in extra memory without updating the truesize. This in turn was kept around unchanged from ab7db91 ("virtio-net: auto-tune mergeable rx buffer size for improved performance"). That commit had an internal reason not to account for the extra space: not enough bits to do it. No longer true so let's account for the allocated length exactly. Many thanks to Seth Forshee for the report and bisecting and Euan Kemp for debugging the issue. Fixes: 680557c ("virtio_net: rework mergeable buffer handling") Reported-by: Euan Kemp <[email protected]> Tested-by: Euan Kemp <[email protected]> Reported-by: Seth Forshee <[email protected]> Tested-by: Seth Forshee <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent cfbcb61 commit 1daa879

File tree

1 file changed

+2
-3
lines changed

1 file changed

+2
-3
lines changed

drivers/net/virtio_net.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -889,21 +889,20 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi,
889889

890890
buf = (char *)page_address(alloc_frag->page) + alloc_frag->offset;
891891
buf += headroom; /* advance address leaving hole at front of pkt */
892-
ctx = (void *)(unsigned long)len;
893892
get_page(alloc_frag->page);
894893
alloc_frag->offset += len + headroom;
895894
hole = alloc_frag->size - alloc_frag->offset;
896895
if (hole < len + headroom) {
897896
/* To avoid internal fragmentation, if there is very likely not
898897
* enough space for another buffer, add the remaining space to
899-
* the current buffer. This extra space is not included in
900-
* the truesize stored in ctx.
898+
* the current buffer.
901899
*/
902900
len += hole;
903901
alloc_frag->offset += hole;
904902
}
905903

906904
sg_init_one(rq->sg, buf, len);
905+
ctx = (void *)(unsigned long)len;
907906
err = virtqueue_add_inbuf_ctx(rq->vq, rq->sg, 1, buf, ctx, gfp);
908907
if (err < 0)
909908
put_page(virt_to_head_page(buf));

0 commit comments

Comments
 (0)