Skip to content

Commit ecbc42c

Browse files
Toshiaki Makitadavem330
authored andcommitted
virtio_net: Fix incosistent received bytes counter
When received packets are dropped in virtio_net driver, received packets counter is incremented but bytes counter is not. As a result, for instance if we drop all packets by XDP, only received is counted and bytes stays 0, which looks inconsistent. IMHO received packets/bytes should be counted if packets are produced by the hypervisor, like what common NICs on physical machines are doing. So fix the bytes counter. Signed-off-by: Toshiaki Makita <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9981b4f commit ecbc42c

File tree

1 file changed

+23
-18
lines changed

1 file changed

+23
-18
lines changed

drivers/net/virtio_net.c

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,8 @@ static struct sk_buff *receive_small(struct net_device *dev,
586586
struct receive_queue *rq,
587587
void *buf, void *ctx,
588588
unsigned int len,
589-
unsigned int *xdp_xmit)
589+
unsigned int *xdp_xmit,
590+
unsigned int *rbytes)
590591
{
591592
struct sk_buff *skb;
592593
struct bpf_prog *xdp_prog;
@@ -601,6 +602,7 @@ static struct sk_buff *receive_small(struct net_device *dev,
601602
int err;
602603

603604
len -= vi->hdr_len;
605+
*rbytes += len;
604606

605607
rcu_read_lock();
606608
xdp_prog = rcu_dereference(rq->xdp_prog);
@@ -705,11 +707,13 @@ static struct sk_buff *receive_big(struct net_device *dev,
705707
struct virtnet_info *vi,
706708
struct receive_queue *rq,
707709
void *buf,
708-
unsigned int len)
710+
unsigned int len,
711+
unsigned int *rbytes)
709712
{
710713
struct page *page = buf;
711714
struct sk_buff *skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE);
712715

716+
*rbytes += len - vi->hdr_len;
713717
if (unlikely(!skb))
714718
goto err;
715719

@@ -727,7 +731,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
727731
void *buf,
728732
void *ctx,
729733
unsigned int len,
730-
unsigned int *xdp_xmit)
734+
unsigned int *xdp_xmit,
735+
unsigned int *rbytes)
731736
{
732737
struct virtio_net_hdr_mrg_rxbuf *hdr = buf;
733738
u16 num_buf = virtio16_to_cpu(vi->vdev, hdr->num_buffers);
@@ -740,6 +745,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
740745
int err;
741746

742747
head_skb = NULL;
748+
*rbytes += len - vi->hdr_len;
743749

744750
rcu_read_lock();
745751
xdp_prog = rcu_dereference(rq->xdp_prog);
@@ -877,6 +883,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
877883
goto err_buf;
878884
}
879885

886+
*rbytes += len;
880887
page = virt_to_head_page(buf);
881888

882889
truesize = mergeable_ctx_to_truesize(ctx);
@@ -932,6 +939,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
932939
dev->stats.rx_length_errors++;
933940
break;
934941
}
942+
*rbytes += len;
935943
page = virt_to_head_page(buf);
936944
put_page(page);
937945
}
@@ -942,14 +950,13 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
942950
return NULL;
943951
}
944952

945-
static int receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
946-
void *buf, unsigned int len, void **ctx,
947-
unsigned int *xdp_xmit)
953+
static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
954+
void *buf, unsigned int len, void **ctx,
955+
unsigned int *xdp_xmit, unsigned int *rbytes)
948956
{
949957
struct net_device *dev = vi->dev;
950958
struct sk_buff *skb;
951959
struct virtio_net_hdr_mrg_rxbuf *hdr;
952-
int ret;
953960

954961
if (unlikely(len < vi->hdr_len + ETH_HLEN)) {
955962
pr_debug("%s: short packet %i\n", dev->name, len);
@@ -961,23 +968,22 @@ static int receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
961968
} else {
962969
put_page(virt_to_head_page(buf));
963970
}
964-
return 0;
971+
return;
965972
}
966973

967974
if (vi->mergeable_rx_bufs)
968-
skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit);
975+
skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
976+
rbytes);
969977
else if (vi->big_packets)
970-
skb = receive_big(dev, vi, rq, buf, len);
978+
skb = receive_big(dev, vi, rq, buf, len, rbytes);
971979
else
972-
skb = receive_small(dev, vi, rq, buf, ctx, len, xdp_xmit);
980+
skb = receive_small(dev, vi, rq, buf, ctx, len, xdp_xmit, rbytes);
973981

974982
if (unlikely(!skb))
975-
return 0;
983+
return;
976984

977985
hdr = skb_vnet_hdr(skb);
978986

979-
ret = skb->len;
980-
981987
if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID)
982988
skb->ip_summed = CHECKSUM_UNNECESSARY;
983989

@@ -994,12 +1000,11 @@ static int receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
9941000
ntohs(skb->protocol), skb->len, skb->pkt_type);
9951001

9961002
napi_gro_receive(&rq->napi, skb);
997-
return ret;
1003+
return;
9981004

9991005
frame_err:
10001006
dev->stats.rx_frame_errors++;
10011007
dev_kfree_skb(skb);
1002-
return 0;
10031008
}
10041009

10051010
/* Unlike mergeable buffers, all buffers are allocated to the
@@ -1249,13 +1254,13 @@ static int virtnet_receive(struct receive_queue *rq, int budget,
12491254

12501255
while (received < budget &&
12511256
(buf = virtqueue_get_buf_ctx(rq->vq, &len, &ctx))) {
1252-
bytes += receive_buf(vi, rq, buf, len, ctx, xdp_xmit);
1257+
receive_buf(vi, rq, buf, len, ctx, xdp_xmit, &bytes);
12531258
received++;
12541259
}
12551260
} else {
12561261
while (received < budget &&
12571262
(buf = virtqueue_get_buf(rq->vq, &len)) != NULL) {
1258-
bytes += receive_buf(vi, rq, buf, len, NULL, xdp_xmit);
1263+
receive_buf(vi, rq, buf, len, NULL, xdp_xmit, &bytes);
12591264
received++;
12601265
}
12611266
}

0 commit comments

Comments
 (0)