summaryrefslogtreecommitdiff
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2023-09-21 11:52:17 +0300
committerDavid S. Miller <davem@davemloft.net>2023-10-01 18:33:01 +0300
commitd12a26b74fb77434b73fe39022266c4b00907219 (patch)
tree4d79cdfe38a5995d60bc06d0dbe3df40130185af /drivers/net/virtio_net.c
parent0b068c714ca9479d2783cc333fff5bc2d4a6d45c (diff)
downloadlinux-d12a26b74fb77434b73fe39022266c4b00907219.tar.xz
virtio_net: avoid data-races on dev->stats fields
Use DEV_STATS_INC() and DEV_STATS_READ() which provide atomicity on paths that can be used concurrently. Reported-by: syzbot <syzkaller@googlegroups.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Cc: "Michael S. Tsirkin" <mst@redhat.com> Cc: Jason Wang <jasowang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index fe7f314d65c9..1ed6bcc4cbb1 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1258,7 +1258,7 @@ static struct sk_buff *receive_small(struct net_device *dev,
if (unlikely(len > GOOD_PACKET_LEN)) {
pr_debug("%s: rx error: len %u exceeds max size %d\n",
dev->name, len, GOOD_PACKET_LEN);
- dev->stats.rx_length_errors++;
+ DEV_STATS_INC(dev, rx_length_errors);
goto err;
}
@@ -1323,7 +1323,7 @@ static void mergeable_buf_free(struct receive_queue *rq, int num_buf,
if (unlikely(!buf)) {
pr_debug("%s: rx error: %d buffers missing\n",
dev->name, num_buf);
- dev->stats.rx_length_errors++;
+ DEV_STATS_INC(dev, rx_length_errors);
break;
}
stats->bytes += len;
@@ -1432,7 +1432,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
pr_debug("%s: rx error: %d buffers out of %d missing\n",
dev->name, *num_buf,
virtio16_to_cpu(vi->vdev, hdr->num_buffers));
- dev->stats.rx_length_errors++;
+ DEV_STATS_INC(dev, rx_length_errors);
goto err;
}
@@ -1451,7 +1451,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
put_page(page);
pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
dev->name, len, (unsigned long)(truesize - room));
- dev->stats.rx_length_errors++;
+ DEV_STATS_INC(dev, rx_length_errors);
goto err;
}
@@ -1630,7 +1630,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
if (unlikely(len > truesize - room)) {
pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
dev->name, len, (unsigned long)(truesize - room));
- dev->stats.rx_length_errors++;
+ DEV_STATS_INC(dev, rx_length_errors);
goto err_skb;
}
@@ -1662,7 +1662,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
dev->name, num_buf,
virtio16_to_cpu(vi->vdev,
hdr->num_buffers));
- dev->stats.rx_length_errors++;
+ DEV_STATS_INC(dev, rx_length_errors);
goto err_buf;
}
@@ -1676,7 +1676,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
if (unlikely(len > truesize - room)) {
pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
dev->name, len, (unsigned long)(truesize - room));
- dev->stats.rx_length_errors++;
+ DEV_STATS_INC(dev, rx_length_errors);
goto err_skb;
}
@@ -1763,7 +1763,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
if (unlikely(len < vi->hdr_len + ETH_HLEN)) {
pr_debug("%s: short packet %i\n", dev->name, len);
- dev->stats.rx_length_errors++;
+ DEV_STATS_INC(dev, rx_length_errors);
virtnet_rq_free_unused_buf(rq->vq, buf);
return;
}
@@ -1803,7 +1803,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
return;
frame_err:
- dev->stats.rx_frame_errors++;
+ DEV_STATS_INC(dev, rx_frame_errors);
dev_kfree_skb(skb);
}
@@ -2349,12 +2349,12 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
/* This should not happen! */
if (unlikely(err)) {
- dev->stats.tx_fifo_errors++;
+ DEV_STATS_INC(dev, tx_fifo_errors);
if (net_ratelimit())
dev_warn(&dev->dev,
"Unexpected TXQ (%d) queue failure: %d\n",
qnum, err);
- dev->stats.tx_dropped++;
+ DEV_STATS_INC(dev, tx_dropped);
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -2573,10 +2573,10 @@ static void virtnet_stats(struct net_device *dev,
tot->tx_errors += terrors;
}
- tot->tx_dropped = dev->stats.tx_dropped;
- tot->tx_fifo_errors = dev->stats.tx_fifo_errors;
- tot->rx_length_errors = dev->stats.rx_length_errors;
- tot->rx_frame_errors = dev->stats.rx_frame_errors;
+ tot->tx_dropped = DEV_STATS_READ(dev, tx_dropped);
+ tot->tx_fifo_errors = DEV_STATS_READ(dev, tx_fifo_errors);
+ tot->rx_length_errors = DEV_STATS_READ(dev, rx_length_errors);
+ tot->rx_frame_errors = DEV_STATS_READ(dev, rx_frame_errors);
}
static void virtnet_ack_link_announce(struct virtnet_info *vi)