mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-15 23:14:31 +08:00
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>
This commit is contained in:
parent
0b068c714c
commit
d12a26b74f
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user