Le mercredi 15 juin 2011 Ã 11:43 -0400, Stephen Hemminger a Ãcrit : > Use per-cpu variables to maintain 64 bit statistics. > Compile tested only. > > Signed-off-by: Stephen Hemminger <shemminger@xxxxxxxxxx> > > --- a/drivers/net/virtio_net.c 2011-06-14 15:18:46.448596355 -0400 > +++ b/drivers/net/virtio_net.c 2011-06-15 09:54:22.914426067 -0400 > @@ -40,6 +40,15 @@ module_param(gso, bool, 0444); > > #define VIRTNET_SEND_COMMAND_SG_MAX 2 > > +struct virtnet_stats { > + struct u64_stats_sync syncp; > + u64 tx_bytes; > + u64 tx_packets; > + > + u64 rx_bytes; > + u64 rx_packets; > +}; > + > struct virtnet_info { > struct virtio_device *vdev; > struct virtqueue *rvq, *svq, *cvq; > @@ -56,6 +65,9 @@ struct virtnet_info { > /* Host will merge rx buffers for big packets (shake it! shake it!) */ > bool mergeable_rx_bufs; > > + /* Active statistics */ > + struct virtnet_stats __percpu *stats; > + > /* Work struct for refilling if we run low on memory. */ > struct delayed_work refill; > > @@ -209,7 +221,6 @@ static int receive_mergeable(struct virt > skb->dev->stats.rx_length_errors++; > return -EINVAL; > } > - > page = virtqueue_get_buf(vi->rvq, &len); > if (!page) { > pr_debug("%s: rx error: %d buffers missing\n", > @@ -217,6 +228,7 @@ static int receive_mergeable(struct virt > skb->dev->stats.rx_length_errors++; > return -EINVAL; > } > + > if (len > PAGE_SIZE) > len = PAGE_SIZE; > > @@ -230,6 +242,7 @@ static int receive_mergeable(struct virt > static void receive_buf(struct net_device *dev, void *buf, unsigned int len) > { > struct virtnet_info *vi = netdev_priv(dev); > + struct virtnet_stats __percpu *stats = this_cpu_ptr(vi->stats); > struct sk_buff *skb; > struct page *page; > struct skb_vnet_hdr *hdr; > @@ -265,8 +278,11 @@ static void receive_buf(struct net_devic > > hdr = skb_vnet_hdr(skb); > skb->truesize += skb->data_len; > - dev->stats.rx_bytes += skb->len; > - dev->stats.rx_packets++; > + > + u64_stats_update_begin(&stats->syncp); > + stats->rx_bytes += skb->len; > + stats->rx_packets++; > + u64_stats_update_begin(&stats->syncp); u64_stats_update_end(&stats->syncp); > > if (hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { > pr_debug("Needs csum!\n"); > @@ -515,11 +531,16 @@ static unsigned int free_old_xmit_skbs(s > { > struct sk_buff *skb; > unsigned int len, tot_sgs = 0; > + struct virtnet_stats __percpu *stats = this_cpu_ptr(vi->stats); > > while ((skb = virtqueue_get_buf(vi->svq, &len)) != NULL) { > pr_debug("Sent skb %p\n", skb); > - vi->dev->stats.tx_bytes += skb->len; > - vi->dev->stats.tx_packets++; > + > + u64_stats_update_begin(&stats->syncp); > + stats->tx_bytes += skb->len; > + stats->tx_packets++; > + u64_stats_update_begin(&stats->syncp); u64_stats_update_end(&stats->syncp); > + > tot_sgs += skb_vnet_hdr(skb)->num_sg; > dev_kfree_skb_any(skb); > } > @@ -641,6 +662,40 @@ static int virtnet_set_mac_address(struc > return 0; > } > _______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/virtualization