netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/5] more statistics updates
@ 2011-06-20 20:35 Stephen Hemminger
  2011-06-20 20:35 ` [PATCH net-next 1/5] vxge: fix 64 bit access on 32 bit platforms Stephen Hemminger
                   ` (4 more replies)
  0 siblings, 5 replies; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-20 20:35 UTC (permalink / raw)
  To: davem; +Cc: netdev

Fix drivers that are using 64 bit statistics with unsafe access on 32 bit.
These are compile tested only, because the hardware to test it is not
easily available.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH net-next 1/5] vxge: fix 64 bit access on 32 bit platforms
  2011-06-20 20:35 [PATCH net-next 0/5] more statistics updates Stephen Hemminger
@ 2011-06-20 20:35 ` Stephen Hemminger
  2011-06-21 22:56   ` David Miller
  2011-06-20 20:35 ` [PATCH net-next 2/5] niu: fix 64 bit statistics on 32 bit platform Stephen Hemminger
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-20 20:35 UTC (permalink / raw)
  To: davem, Jon Mason; +Cc: netdev

[-- Attachment #1: vxge-stats-sync.patch --]
[-- Type: text/plain, Size: 5420 bytes --]

Need to add stat_sync wrapper around 64 bit statistic values.
Fix wraparound bug in lockup detector where it is unsafely comparing
64 bit value that is not atomic. Since only care about detecting activity
just looking at current low order bits will work.

Remove unused entries in old vxge_sw_stats structure.
Change the error counters to unsigned long since they won't grow so large
as to have to be 64 bits.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

--- a/drivers/net/vxge/vxge-main.c	2011-06-20 11:46:03.811996124 -0700
+++ b/drivers/net/vxge/vxge-main.c	2011-06-20 12:19:42.023994994 -0700
@@ -296,11 +296,13 @@ vxge_rx_complete(struct vxge_ring *ring,
 	skb_record_rx_queue(skb, ring->driver_id);
 	skb->protocol = eth_type_trans(skb, ring->ndev);
 
+	u64_stats_update_begin(&ring->stats.syncp);
 	ring->stats.rx_frms++;
 	ring->stats.rx_bytes += pkt_length;
 
 	if (skb->pkt_type == PACKET_MULTICAST)
 		ring->stats.rx_mcast++;
+	u64_stats_update_end(&ring->stats.syncp);
 
 	vxge_debug_rx(VXGE_TRACE,
 		"%s: %s:%d  skb protocol = %d",
@@ -592,8 +594,10 @@ vxge_xmit_compl(struct __vxge_hw_fifo *f
 		vxge_hw_fifo_txdl_free(fifo_hw, dtr);
 
 		/* Updating the statistics block */
+		u64_stats_update_begin(&fifo->stats.syncp);
 		fifo->stats.tx_frms++;
 		fifo->stats.tx_bytes += skb->len;
+		u64_stats_update_end(&fifo->stats.syncp);
 
 		*done_skb++ = skb;
 
@@ -2630,11 +2634,16 @@ static void vxge_poll_vp_lockup(unsigned
 	struct vxge_vpath *vpath;
 	struct vxge_ring *ring;
 	int i;
+	unsigned long rx_frms;
 
 	for (i = 0; i < vdev->no_of_vpath; i++) {
 		ring = &vdev->vpaths[i].ring;
+
+		/* Truncated to machine word size number of frames */
+		rx_frms = ACCESS_ONCE(ring->stats.rx_frms);
+
 		/* Did this vpath received any packets */
-		if (ring->stats.prev_rx_frms == ring->stats.rx_frms) {
+		if (ring->stats.prev_rx_frms == rx_frms) {
 			status = vxge_hw_vpath_check_leak(ring->handle);
 
 			/* Did it received any packets last time */
@@ -2654,7 +2663,7 @@ static void vxge_poll_vp_lockup(unsigned
 				}
 			}
 		}
-		ring->stats.prev_rx_frms = ring->stats.rx_frms;
+		ring->stats.prev_rx_frms = rx_frms;
 		ring->last_status = status;
 	}
 
@@ -3125,14 +3134,36 @@ vxge_get_stats64(struct net_device *dev,
 
 	/* net_stats already zeroed by caller */
 	for (k = 0; k < vdev->no_of_vpath; k++) {
-		net_stats->rx_packets += vdev->vpaths[k].ring.stats.rx_frms;
-		net_stats->rx_bytes += vdev->vpaths[k].ring.stats.rx_bytes;
-		net_stats->rx_errors += vdev->vpaths[k].ring.stats.rx_errors;
-		net_stats->multicast += vdev->vpaths[k].ring.stats.rx_mcast;
-		net_stats->rx_dropped += vdev->vpaths[k].ring.stats.rx_dropped;
-		net_stats->tx_packets += vdev->vpaths[k].fifo.stats.tx_frms;
-		net_stats->tx_bytes += vdev->vpaths[k].fifo.stats.tx_bytes;
-		net_stats->tx_errors += vdev->vpaths[k].fifo.stats.tx_errors;
+		struct vxge_ring_stats *rxstats = &vdev->vpaths[k].ring.stats;
+		struct vxge_fifo_stats *txstats = &vdev->vpaths[k].fifo.stats;
+		unsigned int start;
+		u64 packets, bytes, multicast;
+
+		do {
+			start = u64_stats_fetch_begin(&rxstats->syncp);
+
+			packets   = rxstats->rx_frms;
+			multicast = rxstats->rx_mcast;
+			bytes     = rxstats->rx_bytes;
+		} while (u64_stats_fetch_retry(&rxstats->syncp, start));
+
+		net_stats->rx_packets += packets;
+		net_stats->rx_bytes += bytes;
+		net_stats->multicast += multicast;
+
+		net_stats->rx_errors += rxstats->rx_errors;
+		net_stats->rx_dropped += rxstats->rx_dropped;
+
+		do {
+			start = u64_stats_fetch_begin(&txstats->syncp);
+
+			packets = txstats->tx_frms;
+			bytes   = txstats->tx_bytes;
+		} while (u64_stats_fetch_retry(&txstats->syncp, start));
+
+		net_stats->tx_packets += packets;
+		net_stats->tx_bytes += bytes;
+		net_stats->tx_errors += txstats->tx_errors;
 	}
 
 	return net_stats;
--- a/drivers/net/vxge/vxge-main.h	2011-06-20 11:46:33.195996108 -0700
+++ b/drivers/net/vxge/vxge-main.h	2011-06-20 12:16:35.527995099 -0700
@@ -201,30 +201,14 @@ struct vxge_msix_entry {
 /* Software Statistics */
 
 struct vxge_sw_stats {
-	/* Network Stats (interface stats) */
-
-	/* Tx */
-	u64 tx_frms;
-	u64 tx_errors;
-	u64 tx_bytes;
-	u64 txd_not_free;
-	u64 txd_out_of_desc;
 
 	/* Virtual Path */
-	u64 vpaths_open;
-	u64 vpath_open_fail;
-
-	/* Rx */
-	u64 rx_frms;
-	u64 rx_errors;
-	u64 rx_bytes;
-	u64 rx_mcast;
+	unsigned long vpaths_open;
+	unsigned long vpath_open_fail;
 
 	/* Misc. */
-	u64 link_up;
-	u64 link_down;
-	u64 pci_map_fail;
-	u64 skb_alloc_fail;
+	unsigned long link_up;
+	unsigned long link_down;
 };
 
 struct vxge_mac_addrs {
@@ -237,12 +221,14 @@ struct vxge_mac_addrs {
 struct vxgedev;
 
 struct vxge_fifo_stats {
+	struct u64_stats_sync	syncp;
 	u64 tx_frms;
-	u64 tx_errors;
 	u64 tx_bytes;
-	u64 txd_not_free;
-	u64 txd_out_of_desc;
-	u64 pci_map_fail;
+
+	unsigned long tx_errors;
+	unsigned long txd_not_free;
+	unsigned long txd_out_of_desc;
+	unsigned long pci_map_fail;
 };
 
 struct vxge_fifo {
@@ -264,14 +250,16 @@ struct vxge_fifo {
 } ____cacheline_aligned;
 
 struct vxge_ring_stats {
-	u64 prev_rx_frms;
+	struct u64_stats_sync syncp;
 	u64 rx_frms;
-	u64 rx_errors;
-	u64 rx_dropped;
-	u64 rx_bytes;
 	u64 rx_mcast;
-	u64 pci_map_fail;
-	u64 skb_alloc_fail;
+	u64 rx_bytes;
+
+	unsigned long rx_errors;
+	unsigned long rx_dropped;
+	unsigned long prev_rx_frms;
+	unsigned long pci_map_fail;
+	unsigned long skb_alloc_fail;
 };
 
 struct vxge_ring {



^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH net-next 2/5] niu: fix 64 bit statistics on 32 bit platform
  2011-06-20 20:35 [PATCH net-next 0/5] more statistics updates Stephen Hemminger
  2011-06-20 20:35 ` [PATCH net-next 1/5] vxge: fix 64 bit access on 32 bit platforms Stephen Hemminger
@ 2011-06-20 20:35 ` Stephen Hemminger
  2011-06-20 21:45   ` Ben Hutchings
  2011-06-20 20:35 ` [PATCH net-next 3/5] netxen: make 64 bit stats safe " Stephen Hemminger
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-20 20:35 UTC (permalink / raw)
  To: davem; +Cc: netdev

[-- Attachment #1: niu-stats-sync.patch --]
[-- Type: text/plain, Size: 4481 bytes --]

This resolves issues with NIU driver statistics wrapping on 32 bit SMP.
Use stats_sync wrapper for bytes and packets, and change error counters
to natural word size (unsigned long).

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


--- a/drivers/net/niu.c	2011-06-20 12:27:58.015994716 -0700
+++ b/drivers/net/niu.c	2011-06-20 12:40:21.239994298 -0700
@@ -3512,8 +3512,10 @@ static int niu_process_rx_pkt(struct nap
 			       (u32)rh->hashval1_2 << 0);
 	skb_pull(skb, sizeof(*rh));
 
+	u64_stats_update_begin(&rp->syncp);
 	rp->rx_packets++;
 	rp->rx_bytes += skb->len;
+	u64_stats_update_end(&rp->syncp);
 
 	skb->protocol = eth_type_trans(skb, np->dev);
 	skb_record_rx_queue(skb, rp->rx_channel);
@@ -6252,59 +6254,59 @@ static void niu_sync_mac_stats(struct ni
 static void niu_get_rx_stats(struct niu *np,
 			     struct rtnl_link_stats64 *stats)
 {
-	u64 pkts, dropped, errors, bytes;
 	struct rx_ring_info *rx_rings;
 	int i;
 
-	pkts = dropped = errors = bytes = 0;
-
 	rx_rings = ACCESS_ONCE(np->rx_rings);
 	if (!rx_rings)
-		goto no_rings;
+		return;
 
 	for (i = 0; i < np->num_rx_rings; i++) {
 		struct rx_ring_info *rp = &rx_rings[i];
+		unsigned int start;
+		u64 pkts, bytes;
 
 		niu_sync_rx_discard_stats(np, rp, 0);
 
-		pkts += rp->rx_packets;
-		bytes += rp->rx_bytes;
-		dropped += rp->rx_dropped;
-		errors += rp->rx_errors;
-	}
+		do {
+			start = u64_stats_fetch_begin(&rp->syncp);
 
-no_rings:
-	stats->rx_packets = pkts;
-	stats->rx_bytes = bytes;
-	stats->rx_dropped = dropped;
-	stats->rx_errors = errors;
+			pkts    = rp->rx_packets;
+			bytes   = rp->rx_bytes;
+		} while (u64_stats_fetch_retry(&rp->syncp, start));
+
+		stats->rx_packets += pkts;
+		stats->rx_bytes   += bytes;
+		stats->rx_dropped += rp->rx_dropped;
+		stats->rx_errors  += rp->rx_errors;
+	}
 }
 
 static void niu_get_tx_stats(struct niu *np,
 			     struct rtnl_link_stats64 *stats)
 {
-	u64 pkts, errors, bytes;
 	struct tx_ring_info *tx_rings;
 	int i;
 
-	pkts = errors = bytes = 0;
-
 	tx_rings = ACCESS_ONCE(np->tx_rings);
 	if (!tx_rings)
-		goto no_rings;
+		return;
 
 	for (i = 0; i < np->num_tx_rings; i++) {
 		struct tx_ring_info *rp = &tx_rings[i];
+		unsigned int start;
+		u64 pkts, bytes;
 
-		pkts += rp->tx_packets;
-		bytes += rp->tx_bytes;
-		errors += rp->tx_errors;
+		do {
+			start = u64_stats_fetch_begin(&rp->syncp);
+			pkts   = rp->tx_packets;
+			bytes  = rp->tx_bytes;
+		} while (u64_stats_fetch_retry(&rp->syncp, start));
+
+		stats->tx_packets += pkts;
+		stats->tx_bytes   += bytes;
+		stats->tx_errors  += rp->tx_errors;
 	}
-
-no_rings:
-	stats->tx_packets = pkts;
-	stats->tx_bytes = bytes;
-	stats->tx_errors = errors;
 }
 
 static struct rtnl_link_stats64 *niu_get_stats(struct net_device *dev,
@@ -7818,6 +7820,7 @@ static void niu_get_ethtool_stats(struct
 				  struct ethtool_stats *stats, u64 *data)
 {
 	struct niu *np = netdev_priv(dev);
+	unsigned int start;
 	int i;
 
 	niu_sync_mac_stats(np);
@@ -7836,8 +7839,13 @@ static void niu_get_ethtool_stats(struct
 		niu_sync_rx_discard_stats(np, rp, 0);
 
 		data[0] = rp->rx_channel;
-		data[1] = rp->rx_packets;
-		data[2] = rp->rx_bytes;
+		do {
+			start = u64_stats_fetch_begin(&rp->syncp);
+
+			data[1] = rp->rx_packets;
+			data[2] = rp->rx_bytes;
+		} while (u64_stats_fetch_retry(&rp->syncp, start));
+
 		data[3] = rp->rx_dropped;
 		data[4] = rp->rx_errors;
 		data += 5;
@@ -7846,8 +7854,11 @@ static void niu_get_ethtool_stats(struct
 		struct tx_ring_info *rp = &np->tx_rings[i];
 
 		data[0] = rp->tx_channel;
-		data[1] = rp->tx_packets;
-		data[2] = rp->tx_bytes;
+		do {
+			start = u64_stats_fetch_begin(&rp->syncp);
+			data[1] = rp->tx_packets;
+			data[2] = rp->tx_bytes;
+		} while (u64_stats_fetch_retry(&rp->syncp, start));
 		data[3] = rp->tx_errors;
 		data += 4;
 	}
--- a/drivers/net/niu.h	2011-06-20 12:27:57.043994716 -0700
+++ b/drivers/net/niu.h	2011-06-20 12:35:41.343994455 -0700
@@ -2866,9 +2866,10 @@ struct tx_ring_info {
 	struct txdma_mailbox	*mbox;
 	__le64			*descr;
 
+	struct u64_stats_sync	syncp;
 	u64			tx_packets;
 	u64			tx_bytes;
-	u64			tx_errors;
+	unsigned long		tx_errors;
 
 	u64			mbox_dma;
 	u64			descr_dma;
@@ -2922,10 +2923,11 @@ struct rx_ring_info {
 	__le32			*rbr;
 #define RBR_DESCR_ADDR_SHIFT	12
 
+	struct u64_stats_sync	syncp;
 	u64			rx_packets;
 	u64			rx_bytes;
-	u64			rx_dropped;
-	u64			rx_errors;
+	unsigned long		rx_dropped;
+	unsigned long		rx_errors;
 
 	u64			mbox_dma;
 	u64			rcr_dma;



^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH net-next 3/5] netxen: make 64 bit stats safe on 32 bit platform
  2011-06-20 20:35 [PATCH net-next 0/5] more statistics updates Stephen Hemminger
  2011-06-20 20:35 ` [PATCH net-next 1/5] vxge: fix 64 bit access on 32 bit platforms Stephen Hemminger
  2011-06-20 20:35 ` [PATCH net-next 2/5] niu: fix 64 bit statistics on 32 bit platform Stephen Hemminger
@ 2011-06-20 20:35 ` Stephen Hemminger
  2011-06-20 21:50   ` Eric Dumazet
  2011-06-20 21:52   ` Ben Hutchings
  2011-06-20 20:35 ` [PATCH net-next 4/5] xen: convert to 64 bit stats interface Stephen Hemminger
  2011-06-20 20:56 ` [PATCH net-next 0/5] more statistics updates David Miller
  4 siblings, 2 replies; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-20 20:35 UTC (permalink / raw)
  To: davem, Amit Kumar Salecha; +Cc: netdev

[-- Attachment #1: netxen-stats-sync.patch --]
[-- Type: text/plain, Size: 2491 bytes --]

Use stats_update wrapper to avoid problems where 64 bit statistic update
is not atomic on 32 bit platform.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


---
 drivers/net/netxen/netxen_nic.h      |    1 +
 drivers/net/netxen/netxen_nic_init.c |    2 ++
 drivers/net/netxen/netxen_nic_main.c |   16 ++++++++++++----
 3 files changed, 15 insertions(+), 4 deletions(-)

--- a/drivers/net/netxen/netxen_nic.h	2011-06-20 12:42:05.035994241 -0700
+++ b/drivers/net/netxen/netxen_nic.h	2011-06-20 12:51:27.727993925 -0700
@@ -607,6 +607,7 @@ struct netxen_hardware_context {
 #define ETHERNET_FCS_SIZE		4
 
 struct netxen_adapter_stats {
+	struct u64_stats_sync syncp;
 	u64  xmitcalled;
 	u64  xmitfinished;
 	u64  rxdropped;
--- a/drivers/net/netxen/netxen_nic_init.c	2011-06-20 12:48:02.963994039 -0700
+++ b/drivers/net/netxen/netxen_nic_init.c	2011-06-20 12:50:27.887993959 -0700
@@ -1616,8 +1616,10 @@ netxen_process_lro(struct netxen_adapter
 
 	netif_receive_skb(skb);
 
+	u64_stats_update_begin(&adapter->stats.syncp);
 	adapter->stats.lro_pkts++;
 	adapter->stats.rxbytes += length;
+	u64_stats_update_end(&adapter->stats.syncp);
 
 	return buffer;
 }
--- a/drivers/net/netxen/netxen_nic_main.c	2011-06-20 12:41:47.739994250 -0700
+++ b/drivers/net/netxen/netxen_nic_main.c	2011-06-20 12:52:49.255993879 -0700
@@ -1968,8 +1968,10 @@ netxen_nic_xmit_frame(struct sk_buff *sk
 
 	netxen_nic_update_cmd_producer(adapter, tx_ring);
 
+	u64_stats_update_begin(&adapter->stats.syncp);
 	adapter->stats.txbytes += skb->len;
 	adapter->stats.xmitcalled++;
+	u64_stats_update_end(&adapter->stats.syncp);
 
 	return NETDEV_TX_OK;
 
@@ -2115,11 +2117,17 @@ static struct rtnl_link_stats64 *netxen_
 						      struct rtnl_link_stats64 *stats)
 {
 	struct netxen_adapter *adapter = netdev_priv(netdev);
+	unsigned int start;
+
+	do {
+		start = u64_stats_fetch_begin(&adapter->stats.syncp);
+
+		stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
+		stats->tx_packets = adapter->stats.xmitfinished;
+		stats->rx_bytes = adapter->stats.rxbytes;
+		stats->tx_bytes = adapter->stats.txbytes;
+	} while (u64_stats_fetch_retry(&adapter->stats.syncp, start));
 
-	stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
-	stats->tx_packets = adapter->stats.xmitfinished;
-	stats->rx_bytes = adapter->stats.rxbytes;
-	stats->tx_bytes = adapter->stats.txbytes;
 	stats->rx_dropped = adapter->stats.rxdropped;
 	stats->tx_dropped = adapter->stats.txdropped;
 



^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH net-next 4/5] xen: convert to 64 bit stats interface
  2011-06-20 20:35 [PATCH net-next 0/5] more statistics updates Stephen Hemminger
                   ` (2 preceding siblings ...)
  2011-06-20 20:35 ` [PATCH net-next 3/5] netxen: make 64 bit stats safe " Stephen Hemminger
@ 2011-06-20 20:35 ` Stephen Hemminger
  2011-06-21 14:05   ` [Xen-devel] " Ian Campbell
  2011-06-20 20:56 ` [PATCH net-next 0/5] more statistics updates David Miller
  4 siblings, 1 reply; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-20 20:35 UTC (permalink / raw)
  To: davem, Jeremy Fitzhardinge; +Cc: netdev, xen-devel

[-- Attachment #1: xen-stats64.patch --]
[-- Type: text/plain, Size: 8271 bytes --]

Convert xen driver to 64 bit statistics interface.
Use stats_sync to ensure that 64 bit update is read atomically
on 32 bit platform. Put hot statistics into per-cpu table.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
v2 - add stats_sync and per-cpu

--- a/drivers/net/xen-netfront.c	2011-06-20 13:34:56.383992463 -0700
+++ b/drivers/net/xen-netfront.c	2011-06-20 13:41:47.207992232 -0700
@@ -70,6 +70,14 @@ struct netfront_cb {
 #define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
 #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
 
+struct netfront_stats {
+	u64			rx_packets;
+	u64			tx_packets;
+	u64			rx_bytes;
+	u64			tx_bytes;
+	struct u64_stats_sync	syncp;
+};
+
 struct netfront_info {
 	struct list_head list;
 	struct net_device *netdev;
@@ -122,6 +130,8 @@ struct netfront_info {
 	struct mmu_update rx_mmu[NET_RX_RING_SIZE];
 
 	/* Statistics */
+	struct netfront_stats __percpu *stats;
+
 	unsigned long rx_gso_checksum_fixup;
 };
 
@@ -468,6 +478,7 @@ static int xennet_start_xmit(struct sk_b
 {
 	unsigned short id;
 	struct netfront_info *np = netdev_priv(dev);
+	struct netfront_stats *stats = this_cpu_ptr(np->stats);
 	struct xen_netif_tx_request *tx;
 	struct xen_netif_extra_info *extra;
 	char *data = skb->data;
@@ -552,8 +563,10 @@ static int xennet_start_xmit(struct sk_b
 	if (notify)
 		notify_remote_via_irq(np->netdev->irq);
 
-	dev->stats.tx_bytes += skb->len;
-	dev->stats.tx_packets++;
+	u64_stats_update_begin(&stats->syncp);
+	stats->tx_bytes += skb->len;
+	stats->tx_packets++;
+	u64_stats_update_end(&stats->syncp);
 
 	/* Note: It is not safe to access skb after xennet_tx_buf_gc()! */
 	xennet_tx_buf_gc(dev);
@@ -847,6 +860,8 @@ out:
 static int handle_incoming_queue(struct net_device *dev,
 				 struct sk_buff_head *rxq)
 {
+	struct netfront_info *np = netdev_priv(dev);
+	struct netfront_stats *stats = this_cpu_ptr(np->stats);
 	int packets_dropped = 0;
 	struct sk_buff *skb;
 
@@ -867,12 +882,13 @@ static int handle_incoming_queue(struct
 		if (checksum_setup(dev, skb)) {
 			kfree_skb(skb);
 			packets_dropped++;
-			dev->stats.rx_errors++;
 			continue;
 		}
 
-		dev->stats.rx_packets++;
-		dev->stats.rx_bytes += skb->len;
+		u64_stats_update_begin(&stats->syncp);
+		stats->rx_packets++;
+		stats->rx_bytes += skb->len;
+		u64_stats_update_end(&stats->syncp);
 
 		/* Pass it up. */
 		netif_receive_skb(skb);
@@ -1034,6 +1050,38 @@ static int xennet_change_mtu(struct net_
 	return 0;
 }
 
+static struct rtnl_link_stats64 *xennet_get_stats64(struct net_device *dev,
+						    struct rtnl_link_stats64 *tot)
+{
+	struct netfront_info *np = netdev_priv(dev);
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		struct netfront_stats *stats = per_cpu_ptr(np->stats, cpu);
+		u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
+		unsigned int start;
+
+		do {
+			start = u64_stats_fetch_begin_bh(&stats->syncp);
+
+			rx_packets = stats->rx_packets;
+			tx_packets = stats->tx_packets;
+			rx_bytes = stats->rx_bytes;
+			tx_bytes = stats->tx_bytes;
+		} while (u64_stats_fetch_retry_bh(&stats->syncp, start));
+
+		tot->rx_packets += rx_packets;
+		tot->tx_packets += tx_packets;
+		tot->rx_bytes   += rx_bytes;
+		tot->tx_bytes   += tx_bytes;
+	}
+
+	tot->rx_errors  = dev->stats.rx_errors;
+	tot->tx_dropped = dev->stats.tx_dropped;
+
+	return tot;
+}
+
 static void xennet_release_tx_bufs(struct netfront_info *np)
 {
 	struct sk_buff *skb;
@@ -1182,6 +1230,7 @@ static const struct net_device_ops xenne
 	.ndo_stop            = xennet_close,
 	.ndo_start_xmit      = xennet_start_xmit,
 	.ndo_change_mtu	     = xennet_change_mtu,
+	.ndo_get_stats64     = xennet_get_stats64,
 	.ndo_set_mac_address = eth_mac_addr,
 	.ndo_validate_addr   = eth_validate_addr,
 	.ndo_fix_features    = xennet_fix_features,
@@ -1216,6 +1265,11 @@ static struct net_device * __devinit xen
 	np->rx_refill_timer.data = (unsigned long)netdev;
 	np->rx_refill_timer.function = rx_refill_timeout;
 
+	err = -ENOMEM;
+	np->stats = alloc_percpu(struct netfront_stats);
+	if (np->stats == NULL)
+		goto exit;
+
 	/* Initialise tx_skbs as a free chain containing every entry. */
 	np->tx_skb_freelist = 0;
 	for (i = 0; i < NET_TX_RING_SIZE; i++) {
@@ -1234,7 +1288,7 @@ static struct net_device * __devinit xen
 					  &np->gref_tx_head) < 0) {
 		printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
 		err = -ENOMEM;
-		goto exit;
+		goto exit_free_stats;
 	}
 	/* A grant for every rx ring slot */
 	if (gnttab_alloc_grant_references(RX_MAX_TARGET,
@@ -1270,6 +1324,8 @@ static struct net_device * __devinit xen
 
  exit_free_tx:
 	gnttab_free_grant_references(np->gref_tx_head);
+ exit_free_stats:
+	free_percpu(np->stats);
  exit:
 	free_netdev(netdev);
 	return ERR_PTR(err);
@@ -1869,6 +1925,8 @@ static int __devexit xennet_remove(struc
 
 	xennet_sysfs_delif(info->netdev);
 
+	free_percpu(info->stats);
+
 	free_netdev(info->netdev);
 
 	return 0;
>From shemminger@vyatta.com Mon Jun 20 13:36:03 2011
Message-Id: <20110620203603.019928129@vyatta.com>
User-Agent: quilt/0.48-1
Date: Mon, 20 Jun 2011 13:35:11 -0700
From: Stephen Hemminger <shemminger@vyatta.com>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org
Subject: [PATCH net-next 5/5] ifb: convert to 64 bit stats
References: <20110620203506.363818794@vyatta.com>
Content-Disposition: inline; filename=ifb-stats64.patch

Convert input functional block device to use 64 bit stats.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
v2 - add stats_sync


--- a/drivers/net/ifb.c	2011-06-09 14:39:25.000000000 -0700
+++ b/drivers/net/ifb.c	2011-06-20 13:30:30.135992612 -0700
@@ -41,8 +41,18 @@
 struct ifb_private {
 	struct tasklet_struct   ifb_tasklet;
 	int     tasklet_pending;
+
 	struct sk_buff_head     rq;
+	u64 rx_packets;
+	u64 rx_bytes;
+	unsigned long rx_dropped;
+
 	struct sk_buff_head     tq;
+	u64 tx_packets;
+	u64 tx_bytes;
+	unsigned long tx_dropped;
+
+	struct u64_stats_sync	stats_sync;
 };
 
 static int numifbs = 2;
@@ -57,7 +67,6 @@ static void ri_tasklet(unsigned long dev
 
 	struct net_device *_dev = (struct net_device *)dev;
 	struct ifb_private *dp = netdev_priv(_dev);
-	struct net_device_stats *stats = &_dev->stats;
 	struct netdev_queue *txq;
 	struct sk_buff *skb;
 
@@ -77,15 +86,18 @@ static void ri_tasklet(unsigned long dev
 
 		skb->tc_verd = 0;
 		skb->tc_verd = SET_TC_NCLS(skb->tc_verd);
-		stats->tx_packets++;
-		stats->tx_bytes +=skb->len;
+
+		u64_stats_update_begin(&dp->stats_sync);
+		dp->tx_packets++;
+		dp->tx_bytes += skb->len;
+		u64_stats_update_end(&dp->stats_sync);
 
 		rcu_read_lock();
 		skb->dev = dev_get_by_index_rcu(&init_net, skb->skb_iif);
 		if (!skb->dev) {
 			rcu_read_unlock();
 			dev_kfree_skb(skb);
-			stats->tx_dropped++;
+			dp->tx_dropped++;
 			if (skb_queue_len(&dp->tq) != 0)
 				goto resched;
 			break;
@@ -120,9 +132,33 @@ resched:
 
 }
 
+static struct rtnl_link_stats64 *ifb_stats64(struct net_device *dev,
+					     struct rtnl_link_stats64 *stats)
+{
+	struct ifb_private *dp = netdev_priv(dev);
+	unsigned int start;
+
+	do {
+		start = u64_stats_fetch_begin_bh(&dp->stats_sync);
+
+		stats->rx_packets = dp->rx_packets;
+		stats->rx_bytes = dp->rx_bytes;
+		stats->tx_packets = dp->tx_packets;
+		stats->tx_bytes = dp->tx_bytes;
+
+	} while (u64_stats_fetch_retry_bh(&dp->stats_sync, start));
+
+	stats->rx_dropped = dp->rx_dropped;
+	stats->tx_dropped = dp->tx_dropped;
+
+	return stats;
+}
+
+
 static const struct net_device_ops ifb_netdev_ops = {
 	.ndo_open	= ifb_open,
 	.ndo_stop	= ifb_close,
+	.ndo_get_stats64 = ifb_stats64,
 	.ndo_start_xmit	= ifb_xmit,
 	.ndo_validate_addr = eth_validate_addr,
 };
@@ -153,15 +189,16 @@ static void ifb_setup(struct net_device
 static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ifb_private *dp = netdev_priv(dev);
-	struct net_device_stats *stats = &dev->stats;
 	u32 from = G_TC_FROM(skb->tc_verd);
 
-	stats->rx_packets++;
-	stats->rx_bytes+=skb->len;
+	u64_stats_update_begin(&dp->stats_sync);
+	dp->rx_packets++;
+	dp->rx_bytes += skb->len;
+	u64_stats_update_end(&dp->stats_sync);
 
 	if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->skb_iif) {
 		dev_kfree_skb(skb);
-		stats->rx_dropped++;
+		dp->rx_dropped++;
 		return NETDEV_TX_OK;
 	}

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 0/5] more statistics updates
  2011-06-20 20:35 [PATCH net-next 0/5] more statistics updates Stephen Hemminger
                   ` (3 preceding siblings ...)
  2011-06-20 20:35 ` [PATCH net-next 4/5] xen: convert to 64 bit stats interface Stephen Hemminger
@ 2011-06-20 20:56 ` David Miller
  2011-06-20 21:12   ` [PATCH net-next 5/5] ifb: convert to 64 bit stats Stephen Hemminger
  4 siblings, 1 reply; 28+ messages in thread
From: David Miller @ 2011-06-20 20:56 UTC (permalink / raw)
  To: shemminger; +Cc: netdev

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Mon, 20 Jun 2011 13:35:06 -0700

> Fix drivers that are using 64 bit statistics with unsafe access on 32 bit.
> These are compile tested only, because the hardware to test it is not
> easily available.

Where is patch #5?

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH net-next 5/5] ifb: convert to 64 bit stats
  2011-06-20 20:56 ` [PATCH net-next 0/5] more statistics updates David Miller
@ 2011-06-20 21:12   ` Stephen Hemminger
  2011-06-20 21:23     ` Eric Dumazet
  0 siblings, 1 reply; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-20 21:12 UTC (permalink / raw)
  To: David Miller, jamal; +Cc: netdev

Convert input functional block device to use 64 bit stats.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
v2 - add stats_sync


--- a/drivers/net/ifb.c	2011-06-20 13:38:54.271992329 -0700
+++ b/drivers/net/ifb.c	2011-06-20 14:11:30.935991232 -0700
@@ -41,8 +41,16 @@
 struct ifb_private {
 	struct tasklet_struct   ifb_tasklet;
 	int     tasklet_pending;
+
+	struct u64_stats_sync	stats_sync;
+
 	struct sk_buff_head     rq;
+	u64 rx_packets;
+	u64 rx_bytes;
+
 	struct sk_buff_head     tq;
+	u64 tx_packets;
+	u64 tx_bytes;
 };
 
 static int numifbs = 2;
@@ -54,10 +62,8 @@ static int ifb_close(struct net_device *
 
 static void ri_tasklet(unsigned long dev)
 {
-
 	struct net_device *_dev = (struct net_device *)dev;
 	struct ifb_private *dp = netdev_priv(_dev);
-	struct net_device_stats *stats = &_dev->stats;
 	struct netdev_queue *txq;
 	struct sk_buff *skb;
 
@@ -77,15 +83,18 @@ static void ri_tasklet(unsigned long dev
 
 		skb->tc_verd = 0;
 		skb->tc_verd = SET_TC_NCLS(skb->tc_verd);
-		stats->tx_packets++;
-		stats->tx_bytes +=skb->len;
+
+		u64_stats_update_begin(&dp->stats_sync);
+		dp->tx_packets++;
+		dp->tx_bytes += skb->len;
+		u64_stats_update_end(&dp->stats_sync);
 
 		rcu_read_lock();
 		skb->dev = dev_get_by_index_rcu(&init_net, skb->skb_iif);
 		if (!skb->dev) {
 			rcu_read_unlock();
 			dev_kfree_skb(skb);
-			stats->tx_dropped++;
+			_dev->stats.tx_dropped++;
 			if (skb_queue_len(&dp->tq) != 0)
 				goto resched;
 			break;
@@ -120,9 +129,33 @@ resched:
 
 }
 
+static struct rtnl_link_stats64 *ifb_stats64(struct net_device *dev,
+					     struct rtnl_link_stats64 *stats)
+{
+	struct ifb_private *dp = netdev_priv(dev);
+	unsigned int start;
+
+	do {
+		start = u64_stats_fetch_begin_bh(&dp->stats_sync);
+
+		stats->rx_packets = dp->rx_packets;
+		stats->rx_bytes = dp->rx_bytes;
+		stats->tx_packets = dp->tx_packets;
+		stats->tx_bytes = dp->tx_bytes;
+
+	} while (u64_stats_fetch_retry_bh(&dp->stats_sync, start));
+
+	stats->rx_dropped = dev->stats.rx_dropped;
+	stats->tx_dropped = dev->stats.tx_dropped;
+
+	return stats;
+}
+
+
 static const struct net_device_ops ifb_netdev_ops = {
 	.ndo_open	= ifb_open,
 	.ndo_stop	= ifb_close,
+	.ndo_get_stats64 = ifb_stats64,
 	.ndo_start_xmit	= ifb_xmit,
 	.ndo_validate_addr = eth_validate_addr,
 };
@@ -153,15 +186,16 @@ static void ifb_setup(struct net_device
 static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ifb_private *dp = netdev_priv(dev);
-	struct net_device_stats *stats = &dev->stats;
 	u32 from = G_TC_FROM(skb->tc_verd);
 
-	stats->rx_packets++;
-	stats->rx_bytes+=skb->len;
+	u64_stats_update_begin(&dp->stats_sync);
+	dp->rx_packets++;
+	dp->rx_bytes += skb->len;
+	u64_stats_update_end(&dp->stats_sync);
 
 	if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->skb_iif) {
 		dev_kfree_skb(skb);
-		stats->rx_dropped++;
+		dev->stats.rx_dropped++;
 		return NETDEV_TX_OK;
 	}
 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 5/5] ifb: convert to 64 bit stats
  2011-06-20 21:12   ` [PATCH net-next 5/5] ifb: convert to 64 bit stats Stephen Hemminger
@ 2011-06-20 21:23     ` Eric Dumazet
  2011-06-20 21:27       ` Eric Dumazet
  0 siblings, 1 reply; 28+ messages in thread
From: Eric Dumazet @ 2011-06-20 21:23 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, jamal, netdev

Le lundi 20 juin 2011 à 14:12 -0700, Stephen Hemminger a écrit :
> Convert input functional block device to use 64 bit stats.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> ---
> v2 - add stats_sync
> 

Acked-by: Eric Dumazet <eric.dumazet@gmail.com>



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 5/5] ifb: convert to 64 bit stats
  2011-06-20 21:23     ` Eric Dumazet
@ 2011-06-20 21:27       ` Eric Dumazet
  2011-06-20 21:38         ` Stephen Hemminger
  2011-06-20 21:42         ` [PATCH net-next 5/5] ifb: convert to 64 bit stats (v3) Stephen Hemminger
  0 siblings, 2 replies; 28+ messages in thread
From: Eric Dumazet @ 2011-06-20 21:27 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, jamal, netdev

Le lundi 20 juin 2011 à 23:23 +0200, Eric Dumazet a écrit :
> Le lundi 20 juin 2011 à 14:12 -0700, Stephen Hemminger a écrit :
> > Convert input functional block device to use 64 bit stats.
> > 
> > Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> > 
> > ---
> > v2 - add stats_sync
> > 
> 
> Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
> 

Ah well, I am wondering if ri_tasklet() & ifb_xmit() could run
concurrently

If so, we need two separate syncp, one for each function.




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 5/5] ifb: convert to 64 bit stats
  2011-06-20 21:27       ` Eric Dumazet
@ 2011-06-20 21:38         ` Stephen Hemminger
  2011-06-20 21:42           ` Eric Dumazet
  2011-06-20 21:42         ` [PATCH net-next 5/5] ifb: convert to 64 bit stats (v3) Stephen Hemminger
  1 sibling, 1 reply; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-20 21:38 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, jamal, netdev

On Mon, 20 Jun 2011 23:27:01 +0200
Eric Dumazet <eric.dumazet@gmail.com> wrote:

> Le lundi 20 juin 2011 à 23:23 +0200, Eric Dumazet a écrit :
> > Le lundi 20 juin 2011 à 14:12 -0700, Stephen Hemminger a écrit :
> > > Convert input functional block device to use 64 bit stats.
> > > 
> > > Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> > > 
> > > ---
> > > v2 - add stats_sync
> > > 
> > 
> > Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
> > 
> 
> Ah well, I am wondering if ri_tasklet() & ifb_xmit() could run
> concurrently
> 
> If so, we need two separate syncp, one for each function.

For the normal case that isn't possible but
someone could be perverse and put an address on the ifb device and
try and use like loopback?

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH net-next 5/5] ifb: convert to 64 bit stats (v3)
  2011-06-20 21:27       ` Eric Dumazet
  2011-06-20 21:38         ` Stephen Hemminger
@ 2011-06-20 21:42         ` Stephen Hemminger
  2011-06-20 21:44           ` Eric Dumazet
  1 sibling, 1 reply; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-20 21:42 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, jamal, netdev

Subject: ifb: convert to 64 bit stats

Convert input functional block device to use 64 bit stats.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
v3 - split tx/rsync 

--- a/drivers/net/ifb.c	2011-06-20 13:38:54.271992329 -0700
+++ b/drivers/net/ifb.c	2011-06-20 14:40:52.295990246 -0700
@@ -41,8 +41,16 @@
 struct ifb_private {
 	struct tasklet_struct   ifb_tasklet;
 	int     tasklet_pending;
+
+	struct u64_stats_sync	rsync;
 	struct sk_buff_head     rq;
+	u64 rx_packets;
+	u64 rx_bytes;
+
+	struct u64_stats_sync	tsync;
 	struct sk_buff_head     tq;
+	u64 tx_packets;
+	u64 tx_bytes;
 };
 
 static int numifbs = 2;
@@ -54,10 +62,8 @@ static int ifb_close(struct net_device *
 
 static void ri_tasklet(unsigned long dev)
 {
-
 	struct net_device *_dev = (struct net_device *)dev;
 	struct ifb_private *dp = netdev_priv(_dev);
-	struct net_device_stats *stats = &_dev->stats;
 	struct netdev_queue *txq;
 	struct sk_buff *skb;
 
@@ -77,15 +83,18 @@ static void ri_tasklet(unsigned long dev
 
 		skb->tc_verd = 0;
 		skb->tc_verd = SET_TC_NCLS(skb->tc_verd);
-		stats->tx_packets++;
-		stats->tx_bytes +=skb->len;
+
+		u64_stats_update_begin(&dp->tsync);
+		dp->tx_packets++;
+		dp->tx_bytes += skb->len;
+		u64_stats_update_end(&dp->tsync);
 
 		rcu_read_lock();
 		skb->dev = dev_get_by_index_rcu(&init_net, skb->skb_iif);
 		if (!skb->dev) {
 			rcu_read_unlock();
 			dev_kfree_skb(skb);
-			stats->tx_dropped++;
+			_dev->stats.tx_dropped++;
 			if (skb_queue_len(&dp->tq) != 0)
 				goto resched;
 			break;
@@ -120,9 +129,37 @@ resched:
 
 }
 
+static struct rtnl_link_stats64 *ifb_stats64(struct net_device *dev,
+					     struct rtnl_link_stats64 *stats)
+{
+	struct ifb_private *dp = netdev_priv(dev);
+	unsigned int start;
+
+	do {
+		start = u64_stats_fetch_begin_bh(&dp->rsync);
+		stats->rx_packets = dp->rx_packets;
+		stats->rx_bytes = dp->rx_bytes;
+	} while (u64_stats_fetch_retry_bh(&dp->rsync, start));
+
+	do {
+		start = u64_stats_fetch_begin_bh(&dp->tsync);
+
+		stats->tx_packets = dp->tx_packets;
+		stats->tx_bytes = dp->tx_bytes;
+
+	} while (u64_stats_fetch_retry_bh(&dp->tsync, start));
+
+	stats->rx_dropped = dev->stats.rx_dropped;
+	stats->tx_dropped = dev->stats.tx_dropped;
+
+	return stats;
+}
+
+
 static const struct net_device_ops ifb_netdev_ops = {
 	.ndo_open	= ifb_open,
 	.ndo_stop	= ifb_close,
+	.ndo_get_stats64 = ifb_stats64,
 	.ndo_start_xmit	= ifb_xmit,
 	.ndo_validate_addr = eth_validate_addr,
 };
@@ -153,15 +190,16 @@ static void ifb_setup(struct net_device
 static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ifb_private *dp = netdev_priv(dev);
-	struct net_device_stats *stats = &dev->stats;
 	u32 from = G_TC_FROM(skb->tc_verd);
 
-	stats->rx_packets++;
-	stats->rx_bytes+=skb->len;
+	u64_stats_update_begin(&dp->rsync);
+	dp->rx_packets++;
+	dp->rx_bytes += skb->len;
+	u64_stats_update_end(&dp->rsync);
 
 	if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->skb_iif) {
 		dev_kfree_skb(skb);
-		stats->rx_dropped++;
+		dev->stats.rx_dropped++;
 		return NETDEV_TX_OK;
 	}
 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 5/5] ifb: convert to 64 bit stats
  2011-06-20 21:38         ` Stephen Hemminger
@ 2011-06-20 21:42           ` Eric Dumazet
  0 siblings, 0 replies; 28+ messages in thread
From: Eric Dumazet @ 2011-06-20 21:42 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, jamal, netdev

From: Stephen Hemminger <shemminger@vyatta.com>


Le lundi 20 juin 2011 à 14:38 -0700, Stephen Hemminger a écrit :
> On Mon, 20 Jun 2011 23:27:01 +0200
> Eric Dumazet <eric.dumazet@gmail.com> wrote:
> 
> > Le lundi 20 juin 2011 à 23:23 +0200, Eric Dumazet a écrit :
> > > Le lundi 20 juin 2011 à 14:12 -0700, Stephen Hemminger a écrit :
> > > > Convert input functional block device to use 64 bit stats.
> > > > 
> > > > Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> > > > 
> > > > ---
> > > > v2 - add stats_sync
> > > > 
> > > 
> > > Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
> > > 
> > 
> > Ah well, I am wondering if ri_tasklet() & ifb_xmit() could run
> > concurrently
> > 
> > If so, we need two separate syncp, one for each function.
> 
> For the normal case that isn't possible but
> someone could be perverse and put an address on the ifb device and
> try and use like loopback?

Hmm, this can occur on normal case I think, on SMP.

Here is an updated patch

[PATCH net-next v3] ifb: convert to 64 bit stats

Convert input functional block device to use 64 bit stats.

[Eric Dumazet]: Use two different synchronization points for rx and tx.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
v2 - add stats_sync
v3 - must use two different sync

 drivers/net/ifb.c |   58 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 49 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index ce53f4a..2443e90 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -41,8 +41,16 @@
 struct ifb_private {
 	struct tasklet_struct   ifb_tasklet;
 	int     tasklet_pending;
+
 	struct sk_buff_head     rq;
+	u64			rx_packets;
+	u64			rx_bytes;
+	struct u64_stats_sync	stats_rx_sync;
+
 	struct sk_buff_head     tq;
+	u64			tx_packets;
+	u64			tx_bytes;
+	struct u64_stats_sync	stats_tx_sync;
 };
 
 static int numifbs = 2;
@@ -54,10 +62,8 @@ static int ifb_close(struct net_device *dev);
 
 static void ri_tasklet(unsigned long dev)
 {
-
 	struct net_device *_dev = (struct net_device *)dev;
 	struct ifb_private *dp = netdev_priv(_dev);
-	struct net_device_stats *stats = &_dev->stats;
 	struct netdev_queue *txq;
 	struct sk_buff *skb;
 
@@ -77,15 +83,18 @@ static void ri_tasklet(unsigned long dev)
 
 		skb->tc_verd = 0;
 		skb->tc_verd = SET_TC_NCLS(skb->tc_verd);
-		stats->tx_packets++;
-		stats->tx_bytes +=skb->len;
+
+		u64_stats_update_begin(&dp->stats_tx_sync);
+		dp->tx_packets++;
+		dp->tx_bytes += skb->len;
+		u64_stats_update_end(&dp->stats_tx_sync);
 
 		rcu_read_lock();
 		skb->dev = dev_get_by_index_rcu(&init_net, skb->skb_iif);
 		if (!skb->dev) {
 			rcu_read_unlock();
 			dev_kfree_skb(skb);
-			stats->tx_dropped++;
+			_dev->stats.tx_dropped++;
 			if (skb_queue_len(&dp->tq) != 0)
 				goto resched;
 			break;
@@ -120,9 +129,39 @@ resched:
 
 }
 
+static struct rtnl_link_stats64 *ifb_stats64(struct net_device *dev,
+					     struct rtnl_link_stats64 *stats)
+{
+	const struct ifb_private *dp = netdev_priv(dev);
+	unsigned int start;
+
+	do {
+		start = u64_stats_fetch_begin_bh(&dp->stats_rx_sync);
+
+		stats->rx_packets = dp->rx_packets;
+		stats->rx_bytes = dp->rx_bytes;
+
+	} while (u64_stats_fetch_retry_bh(&dp->stats_rx_sync, start));
+
+	do {
+		start = u64_stats_fetch_begin_bh(&dp->stats_tx_sync);
+
+		stats->tx_packets = dp->tx_packets;
+		stats->tx_bytes = dp->tx_bytes;
+
+	} while (u64_stats_fetch_retry_bh(&dp->stats_tx_sync, start));
+
+	stats->rx_dropped = dev->stats.rx_dropped;
+	stats->tx_dropped = dev->stats.tx_dropped;
+
+	return stats;
+}
+
+
 static const struct net_device_ops ifb_netdev_ops = {
 	.ndo_open	= ifb_open,
 	.ndo_stop	= ifb_close,
+	.ndo_get_stats64 = ifb_stats64,
 	.ndo_start_xmit	= ifb_xmit,
 	.ndo_validate_addr = eth_validate_addr,
 };
@@ -153,15 +192,16 @@ static void ifb_setup(struct net_device *dev)
 static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ifb_private *dp = netdev_priv(dev);
-	struct net_device_stats *stats = &dev->stats;
 	u32 from = G_TC_FROM(skb->tc_verd);
 
-	stats->rx_packets++;
-	stats->rx_bytes+=skb->len;
+	u64_stats_update_begin(&dp->stats_rx_sync);
+	dp->rx_packets++;
+	dp->rx_bytes += skb->len;
+	u64_stats_update_end(&dp->stats_rx_sync);
 
 	if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->skb_iif) {
 		dev_kfree_skb(skb);
-		stats->rx_dropped++;
+		dev->stats.rx_dropped++;
 		return NETDEV_TX_OK;
 	}
 



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 5/5] ifb: convert to 64 bit stats (v3)
  2011-06-20 21:42         ` [PATCH net-next 5/5] ifb: convert to 64 bit stats (v3) Stephen Hemminger
@ 2011-06-20 21:44           ` Eric Dumazet
  2011-06-21  0:04             ` jamal
  0 siblings, 1 reply; 28+ messages in thread
From: Eric Dumazet @ 2011-06-20 21:44 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, jamal, netdev

Le lundi 20 juin 2011 à 14:42 -0700, Stephen Hemminger a écrit :
> Subject: ifb: convert to 64 bit stats
> 
> Convert input functional block device to use 64 bit stats.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> ---
> v3 - split tx/rsync 

Seems good :)

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 2/5] niu: fix 64 bit statistics on 32 bit platform
  2011-06-20 20:35 ` [PATCH net-next 2/5] niu: fix 64 bit statistics on 32 bit platform Stephen Hemminger
@ 2011-06-20 21:45   ` Ben Hutchings
  2011-06-20 21:52     ` Stephen Hemminger
  0 siblings, 1 reply; 28+ messages in thread
From: Ben Hutchings @ 2011-06-20 21:45 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: davem, netdev

On Mon, 2011-06-20 at 13:35 -0700, Stephen Hemminger wrote:

> This resolves issues with NIU driver statistics wrapping on 32 bit SMP.
> Use stats_sync wrapper for bytes and packets, and change error counters
> to natural word size (unsigned long).
[...]
>  static void niu_get_tx_stats(struct niu *np,
>  			     struct rtnl_link_stats64 *stats)
>  {
> -	u64 pkts, errors, bytes;
>  	struct tx_ring_info *tx_rings;
>  	int i;
>  
> -	pkts = errors = bytes = 0;
> -
>  	tx_rings = ACCESS_ONCE(np->tx_rings);
>  	if (!tx_rings)
> -		goto no_rings;
> +		return;
>  
>  	for (i = 0; i < np->num_tx_rings; i++) {
>  		struct tx_ring_info *rp = &tx_rings[i];
> +		unsigned int start;
> +		u64 pkts, bytes;
>  
> -		pkts += rp->tx_packets;
> -		bytes += rp->tx_bytes;
> -		errors += rp->tx_errors;
> +		do {
> +			start = u64_stats_fetch_begin(&rp->syncp);
> +			pkts   = rp->tx_packets;
> +			bytes  = rp->tx_bytes;
> +		} while (u64_stats_fetch_retry(&rp->syncp, start));
> +
> +		stats->tx_packets += pkts;
> +		stats->tx_bytes   += bytes;
> +		stats->tx_errors  += rp->tx_errors;
>  	}
[...]

It looks like you also need to update release_tx_packet() where these
stats are written.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 3/5] netxen: make 64 bit stats safe on 32 bit platform
  2011-06-20 20:35 ` [PATCH net-next 3/5] netxen: make 64 bit stats safe " Stephen Hemminger
@ 2011-06-20 21:50   ` Eric Dumazet
  2011-06-20 21:52   ` Ben Hutchings
  1 sibling, 0 replies; 28+ messages in thread
From: Eric Dumazet @ 2011-06-20 21:50 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: davem, Amit Kumar Salecha, netdev

Le lundi 20 juin 2011 à 13:35 -0700, Stephen Hemminger a écrit :
> pièce jointe document texte brut (netxen-stats-sync.patch)
> Use stats_update wrapper to avoid problems where 64 bit statistic update
> is not atomic on 32 bit platform.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 

Same remark than ifb : You need to be careful not having two different
cpus doing an u64_stats_update_begin(one_syncp);

(Separate rx & tx)



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 2/5] niu: fix 64 bit statistics on 32 bit platform
  2011-06-20 21:45   ` Ben Hutchings
@ 2011-06-20 21:52     ` Stephen Hemminger
  2011-06-20 22:02       ` Eric Dumazet
  0 siblings, 1 reply; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-20 21:52 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: davem, netdev


> It looks like you also need to update release_tx_packet() where these
> stats are written.

Probably need to split tx/rx update as well.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 3/5] netxen: make 64 bit stats safe on 32 bit platform
  2011-06-20 20:35 ` [PATCH net-next 3/5] netxen: make 64 bit stats safe " Stephen Hemminger
  2011-06-20 21:50   ` Eric Dumazet
@ 2011-06-20 21:52   ` Ben Hutchings
  2011-06-20 22:18     ` Stephen Hemminger
  1 sibling, 1 reply; 28+ messages in thread
From: Ben Hutchings @ 2011-06-20 21:52 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: davem, Amit Kumar Salecha, netdev

On Mon, 2011-06-20 at 13:35 -0700, Stephen Hemminger wrote:

> Use stats_update wrapper to avoid problems where 64 bit statistic update
> is not atomic on 32 bit platform.
[...]
> @@ -2115,11 +2117,17 @@ static struct rtnl_link_stats64 *netxen_
>  						      struct rtnl_link_stats64 *stats)
>  {
>  	struct netxen_adapter *adapter = netdev_priv(netdev);
> +	unsigned int start;
> +
> +	do {
> +		start = u64_stats_fetch_begin(&adapter->stats.syncp);
> +
> +		stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
> +		stats->tx_packets = adapter->stats.xmitfinished;
> +		stats->rx_bytes = adapter->stats.rxbytes;
> +		stats->tx_bytes = adapter->stats.txbytes;
> +	} while (u64_stats_fetch_retry(&adapter->stats.syncp, start));
>  
> -	stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
> -	stats->tx_packets = adapter->stats.xmitfinished;
> -	stats->rx_bytes = adapter->stats.rxbytes;
> -	stats->tx_bytes = adapter->stats.txbytes;
>  	stats->rx_dropped = adapter->stats.rxdropped;
>  	stats->tx_dropped = adapter->stats.txdropped;

netxen_nic_get_ethtool_stats() should also be fixed.

The 'txdropped' and 'csummed' stats are also 64-bit and updated on the
data path.  ('rxdropped' isn't updated at all, AFAICS.)

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 2/5] niu: fix 64 bit statistics on 32 bit platform
  2011-06-20 21:52     ` Stephen Hemminger
@ 2011-06-20 22:02       ` Eric Dumazet
  0 siblings, 0 replies; 28+ messages in thread
From: Eric Dumazet @ 2011-06-20 22:02 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Ben Hutchings, davem, netdev

Le lundi 20 juin 2011 à 14:52 -0700, Stephen Hemminger a écrit :
> > It looks like you also need to update release_tx_packet() where these
> > stats are written.
> 
> Probably need to split tx/rx update as well.

Its already done in your patch ;)




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 3/5] netxen: make 64 bit stats safe on 32 bit platform
  2011-06-20 21:52   ` Ben Hutchings
@ 2011-06-20 22:18     ` Stephen Hemminger
  2011-06-20 22:27       ` Ben Hutchings
  0 siblings, 1 reply; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-20 22:18 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: davem, Amit Kumar Salecha, netdev


> On Mon, 2011-06-20 at 13:35 -0700, Stephen Hemminger wrote:
> 
> > Use stats_update wrapper to avoid problems where 64 bit statistic
> > update is not atomic on 32 bit platform.
> [...]
> > @@ -2115,11 +2117,17 @@ static struct rtnl_link_stats64 *netxen_
> >  						      struct rtnl_link_stats64 *stats)
> >  {
> >  	struct netxen_adapter *adapter = netdev_priv(netdev);
> > + unsigned int start;
> > + + do {
> > + start = u64_stats_fetch_begin(&adapter->stats.syncp);
> > + + stats->rx_packets = adapter->stats.rx_pkts +
> > adapter->stats.lro_pkts; + stats->tx_packets =
> > adapter->stats.xmitfinished; + stats->rx_bytes =
> > adapter->stats.rxbytes; + stats->tx_bytes = adapter->stats.txbytes;
> > + } while (u64_stats_fetch_retry(&adapter->stats.syncp, start));
> >
> > - stats->rx_packets = adapter->stats.rx_pkts +
> > adapter->stats.lro_pkts; - stats->tx_packets =
> > adapter->stats.xmitfinished; - stats->rx_bytes =
> > adapter->stats.rxbytes; - stats->tx_bytes = adapter->stats.txbytes;
> >  	stats->rx_dropped = adapter->stats.rxdropped;
> >  	stats->tx_dropped = adapter->stats.txdropped;
> 
> netxen_nic_get_ethtool_stats() should also be fixed.
> 
> The 'txdropped' and 'csummed' stats are also 64-bit and updated on the
> data path. ('rxdropped' isn't updated at all, AFAICS.)

Since they are error counters, just changing them to unsigned long is
easier.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 3/5] netxen: make 64 bit stats safe on 32 bit platform
  2011-06-20 22:18     ` Stephen Hemminger
@ 2011-06-20 22:27       ` Ben Hutchings
  0 siblings, 0 replies; 28+ messages in thread
From: Ben Hutchings @ 2011-06-20 22:27 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: davem, Amit Kumar Salecha, netdev

On Mon, 2011-06-20 at 15:18 -0700, Stephen Hemminger wrote:
> > On Mon, 2011-06-20 at 13:35 -0700, Stephen Hemminger wrote:
> > 
> > > Use stats_update wrapper to avoid problems where 64 bit statistic
> > > update is not atomic on 32 bit platform.
> > [...]
> > > @@ -2115,11 +2117,17 @@ static struct rtnl_link_stats64 *netxen_
> > >  						      struct rtnl_link_stats64 *stats)
> > >  {
> > >  	struct netxen_adapter *adapter = netdev_priv(netdev);
> > > + unsigned int start;
> > > + + do {
> > > + start = u64_stats_fetch_begin(&adapter->stats.syncp);
> > > + + stats->rx_packets = adapter->stats.rx_pkts +
> > > adapter->stats.lro_pkts; + stats->tx_packets =
> > > adapter->stats.xmitfinished; + stats->rx_bytes =
> > > adapter->stats.rxbytes; + stats->tx_bytes = adapter->stats.txbytes;
> > > + } while (u64_stats_fetch_retry(&adapter->stats.syncp, start));
> > >
> > > - stats->rx_packets = adapter->stats.rx_pkts +
> > > adapter->stats.lro_pkts; - stats->tx_packets =
> > > adapter->stats.xmitfinished; - stats->rx_bytes =
> > > adapter->stats.rxbytes; - stats->tx_bytes = adapter->stats.txbytes;
> > >  	stats->rx_dropped = adapter->stats.rxdropped;
> > >  	stats->tx_dropped = adapter->stats.txdropped;
> > 
> > netxen_nic_get_ethtool_stats() should also be fixed.
> > 
> > The 'txdropped' and 'csummed' stats are also 64-bit and updated on the
> > data path. ('rxdropped' isn't updated at all, AFAICS.)
> 
> Since they are error counters, just changing them to unsigned long is
> easier.

'csummed' is not.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 5/5] ifb: convert to 64 bit stats (v3)
  2011-06-20 21:44           ` Eric Dumazet
@ 2011-06-21  0:04             ` jamal
  2011-06-21 22:55               ` David Miller
  0 siblings, 1 reply; 28+ messages in thread
From: jamal @ 2011-06-21  0:04 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Stephen Hemminger, David Miller, netdev

On Mon, 2011-06-20 at 23:44 +0200, Eric Dumazet wrote:

> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Acked-by: Jamal Hadi Salim <hadi@cyberus.ca>

cheers,
jamal




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Xen-devel] [PATCH net-next 4/5] xen: convert to 64 bit stats interface
  2011-06-20 20:35 ` [PATCH net-next 4/5] xen: convert to 64 bit stats interface Stephen Hemminger
@ 2011-06-21 14:05   ` Ian Campbell
  2011-06-21 15:29     ` Stephen Hemminger
  2011-06-21 15:35     ` Stephen Hemminger
  0 siblings, 2 replies; 28+ messages in thread
From: Ian Campbell @ 2011-06-21 14:05 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: davem@davemloft.net, Jeremy Fitzhardinge, netdev@vger.kernel.org,
	xen-devel@lists.xensource.com

On Mon, 2011-06-20 at 21:35 +0100, Stephen Hemminger wrote:
> Convert xen driver to 64 bit statistics interface.
> Use stats_sync to ensure that 64 bit update is read atomically
> on 32 bit platform. Put hot statistics into per-cpu table.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

Thanks Stephen.

> @@ -867,12 +882,13 @@ static int handle_incoming_queue(struct
>  		if (checksum_setup(dev, skb)) {
>  			kfree_skb(skb);
>  			packets_dropped++;
> -			dev->stats.rx_errors++;

Why is this dropped? We should be counting these somehow, I think.

[...]

> >From shemminger@vyatta.com Mon Jun 20 13:36:03 2011
> Message-Id: <20110620203603.019928129@vyatta.com>
> User-Agent: quilt/0.48-1
> Date: Mon, 20 Jun 2011 13:35:11 -0700
> From: Stephen Hemminger <shemminger@vyatta.com>
> To: davem@davemloft.net
> Cc: netdev@vger.kernel.org
> Subject: [PATCH net-next 5/5] ifb: convert to 64 bit stats
> References: <20110620203506.363818794@vyatta.com>
> Content-Disposition: inline; filename=ifb-stats64.patch
> 
> Convert input functional block device to use 64 bit stats.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> ---
> v2 - add stats_sync
> 
> 
> --- a/drivers/net/ifb.c	2011-06-09 14:39:25.000000000 -0700
> +++ b/drivers/net/ifb.c	2011-06-20 13:30:30.135992612 -0700

This entire patch was appended in the mail I got -- something up with
your scripting?

Ian.



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Xen-devel] [PATCH net-next 4/5] xen: convert to 64 bit stats interface
  2011-06-21 14:05   ` [Xen-devel] " Ian Campbell
@ 2011-06-21 15:29     ` Stephen Hemminger
  2011-06-21 15:35     ` Stephen Hemminger
  1 sibling, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-21 15:29 UTC (permalink / raw)
  To: Ian Campbell
  Cc: davem@davemloft.net, Jeremy Fitzhardinge, netdev@vger.kernel.org,
	xen-devel@lists.xensource.com

On Tue, 21 Jun 2011 15:05:54 +0100
Ian Campbell <Ian.Campbell@citrix.com> wrote:

> On Mon, 2011-06-20 at 21:35 +0100, Stephen Hemminger wrote:
> > Convert xen driver to 64 bit statistics interface.
> > Use stats_sync to ensure that 64 bit update is read atomically
> > on 32 bit platform. Put hot statistics into per-cpu table.
> > 
> > Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> Thanks Stephen.
> 
> > @@ -867,12 +882,13 @@ static int handle_incoming_queue(struct
> >  		if (checksum_setup(dev, skb)) {
> >  			kfree_skb(skb);
> >  			packets_dropped++;
> > -			dev->stats.rx_errors++;
> 
> Why is this dropped? We should be counting these somehow, I think.
> 
> [...]
> 
> > >From shemminger@vyatta.com Mon Jun 20 13:36:03 2011
> > Message-Id: <20110620203603.019928129@vyatta.com>
> > User-Agent: quilt/0.48-1
> > Date: Mon, 20 Jun 2011 13:35:11 -0700
> > From: Stephen Hemminger <shemminger@vyatta.com>
> > To: davem@davemloft.net
> > Cc: netdev@vger.kernel.org
> > Subject: [PATCH net-next 5/5] ifb: convert to 64 bit stats
> > References: <20110620203506.363818794@vyatta.com>
> > Content-Disposition: inline; filename=ifb-stats64.patch
> > 
> > Convert input functional block device to use 64 bit stats.
> > 
> > Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> > 
> > ---
> > v2 - add stats_sync
> > 
> > 
> > --- a/drivers/net/ifb.c	2011-06-09 14:39:25.000000000 -0700
> > +++ b/drivers/net/ifb.c	2011-06-20 13:30:30.135992612 -0700
> 
> This entire patch was appended in the mail I got -- something up with
> your scripting?

Bad mbox file to quilt, merged two patches

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Xen-devel] [PATCH net-next 4/5] xen: convert to 64 bit stats interface
  2011-06-21 14:05   ` [Xen-devel] " Ian Campbell
  2011-06-21 15:29     ` Stephen Hemminger
@ 2011-06-21 15:35     ` Stephen Hemminger
  2011-06-21 15:38       ` Ian Campbell
  1 sibling, 1 reply; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-21 15:35 UTC (permalink / raw)
  To: Ian Campbell
  Cc: davem@davemloft.net, Jeremy Fitzhardinge, netdev@vger.kernel.org,
	xen-devel@lists.xensource.com

Convert xen driver to 64 bit statistics interface.
Use stats_sync to ensure that 64 bit update is read atomically on 32 bit platform.
Put hot statistics into per-cpu table.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
v2 - add stats_sync and per-cpu
v2.1 - keep rx_errors on checksum error

--- a/drivers/net/xen-netfront.c	2011-06-20 14:50:01.271989938 -0700
+++ b/drivers/net/xen-netfront.c	2011-06-21 08:33:12.851953760 -0700
@@ -70,6 +70,14 @@ struct netfront_cb {
 #define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
 #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
 
+struct netfront_stats {
+	u64			rx_packets;
+	u64			tx_packets;
+	u64			rx_bytes;
+	u64			tx_bytes;
+	struct u64_stats_sync	syncp;
+};
+
 struct netfront_info {
 	struct list_head list;
 	struct net_device *netdev;
@@ -122,6 +130,8 @@ struct netfront_info {
 	struct mmu_update rx_mmu[NET_RX_RING_SIZE];
 
 	/* Statistics */
+	struct netfront_stats __percpu *stats;
+
 	unsigned long rx_gso_checksum_fixup;
 };
 
@@ -468,6 +478,7 @@ static int xennet_start_xmit(struct sk_b
 {
 	unsigned short id;
 	struct netfront_info *np = netdev_priv(dev);
+	struct netfront_stats *stats = this_cpu_ptr(np->stats);
 	struct xen_netif_tx_request *tx;
 	struct xen_netif_extra_info *extra;
 	char *data = skb->data;
@@ -552,8 +563,10 @@ static int xennet_start_xmit(struct sk_b
 	if (notify)
 		notify_remote_via_irq(np->netdev->irq);
 
-	dev->stats.tx_bytes += skb->len;
-	dev->stats.tx_packets++;
+	u64_stats_update_begin(&stats->syncp);
+	stats->tx_bytes += skb->len;
+	stats->tx_packets++;
+	u64_stats_update_end(&stats->syncp);
 
 	/* Note: It is not safe to access skb after xennet_tx_buf_gc()! */
 	xennet_tx_buf_gc(dev);
@@ -847,6 +860,8 @@ out:
 static int handle_incoming_queue(struct net_device *dev,
 				 struct sk_buff_head *rxq)
 {
+	struct netfront_info *np = netdev_priv(dev);
+	struct netfront_stats *stats = this_cpu_ptr(np->stats);
 	int packets_dropped = 0;
 	struct sk_buff *skb;
 
@@ -871,8 +886,10 @@ static int handle_incoming_queue(struct
 			continue;
 		}
 
-		dev->stats.rx_packets++;
-		dev->stats.rx_bytes += skb->len;
+		u64_stats_update_begin(&stats->syncp);
+		stats->rx_packets++;
+		stats->rx_bytes += skb->len;
+		u64_stats_update_end(&stats->syncp);
 
 		/* Pass it up. */
 		netif_receive_skb(skb);
@@ -1034,6 +1051,38 @@ static int xennet_change_mtu(struct net_
 	return 0;
 }
 
+static struct rtnl_link_stats64 *xennet_get_stats64(struct net_device *dev,
+						    struct rtnl_link_stats64 *tot)
+{
+	struct netfront_info *np = netdev_priv(dev);
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		struct netfront_stats *stats = per_cpu_ptr(np->stats, cpu);
+		u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
+		unsigned int start;
+
+		do {
+			start = u64_stats_fetch_begin_bh(&stats->syncp);
+
+			rx_packets = stats->rx_packets;
+			tx_packets = stats->tx_packets;
+			rx_bytes = stats->rx_bytes;
+			tx_bytes = stats->tx_bytes;
+		} while (u64_stats_fetch_retry_bh(&stats->syncp, start));
+
+		tot->rx_packets += rx_packets;
+		tot->tx_packets += tx_packets;
+		tot->rx_bytes   += rx_bytes;
+		tot->tx_bytes   += tx_bytes;
+	}
+
+	tot->rx_errors  = dev->stats.rx_errors;
+	tot->tx_dropped = dev->stats.tx_dropped;
+
+	return tot;
+}
+
 static void xennet_release_tx_bufs(struct netfront_info *np)
 {
 	struct sk_buff *skb;
@@ -1182,6 +1231,7 @@ static const struct net_device_ops xenne
 	.ndo_stop            = xennet_close,
 	.ndo_start_xmit      = xennet_start_xmit,
 	.ndo_change_mtu	     = xennet_change_mtu,
+	.ndo_get_stats64     = xennet_get_stats64,
 	.ndo_set_mac_address = eth_mac_addr,
 	.ndo_validate_addr   = eth_validate_addr,
 	.ndo_fix_features    = xennet_fix_features,
@@ -1216,6 +1266,11 @@ static struct net_device * __devinit xen
 	np->rx_refill_timer.data = (unsigned long)netdev;
 	np->rx_refill_timer.function = rx_refill_timeout;
 
+	err = -ENOMEM;
+	np->stats = alloc_percpu(struct netfront_stats);
+	if (np->stats == NULL)
+		goto exit;
+
 	/* Initialise tx_skbs as a free chain containing every entry. */
 	np->tx_skb_freelist = 0;
 	for (i = 0; i < NET_TX_RING_SIZE; i++) {
@@ -1234,7 +1289,7 @@ static struct net_device * __devinit xen
 					  &np->gref_tx_head) < 0) {
 		printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
 		err = -ENOMEM;
-		goto exit;
+		goto exit_free_stats;
 	}
 	/* A grant for every rx ring slot */
 	if (gnttab_alloc_grant_references(RX_MAX_TARGET,
@@ -1270,6 +1325,8 @@ static struct net_device * __devinit xen
 
  exit_free_tx:
 	gnttab_free_grant_references(np->gref_tx_head);
+ exit_free_stats:
+	free_percpu(np->stats);
  exit:
 	free_netdev(netdev);
 	return ERR_PTR(err);
@@ -1869,6 +1926,8 @@ static int __devexit xennet_remove(struc
 
 	xennet_sysfs_delif(info->netdev);
 
+	free_percpu(info->stats);
+
 	free_netdev(info->netdev);
 
 	return 0;


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Xen-devel] [PATCH net-next 4/5] xen: convert to 64 bit stats interface
  2011-06-21 15:35     ` Stephen Hemminger
@ 2011-06-21 15:38       ` Ian Campbell
  2011-06-21 22:57         ` David Miller
  0 siblings, 1 reply; 28+ messages in thread
From: Ian Campbell @ 2011-06-21 15:38 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: davem@davemloft.net, Jeremy Fitzhardinge, netdev@vger.kernel.org,
	xen-devel@lists.xensource.com

On Tue, 2011-06-21 at 16:35 +0100, Stephen Hemminger wrote:
> Convert xen driver to 64 bit statistics interface.
> Use stats_sync to ensure that 64 bit update is read atomically on 32 bit platform.
> Put hot statistics into per-cpu table.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> ---
> v2 - add stats_sync and per-cpu
> v2.1 - keep rx_errors on checksum error

Thanks. Looks good to me from the Xen side.

Acked-by: Ian Campbell <ian.campbell@citrix.com>

> 
> --- a/drivers/net/xen-netfront.c	2011-06-20 14:50:01.271989938 -0700
> +++ b/drivers/net/xen-netfront.c	2011-06-21 08:33:12.851953760 -0700
> @@ -70,6 +70,14 @@ struct netfront_cb {
>  #define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
>  #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
>  
> +struct netfront_stats {
> +	u64			rx_packets;
> +	u64			tx_packets;
> +	u64			rx_bytes;
> +	u64			tx_bytes;
> +	struct u64_stats_sync	syncp;
> +};
> +
>  struct netfront_info {
>  	struct list_head list;
>  	struct net_device *netdev;
> @@ -122,6 +130,8 @@ struct netfront_info {
>  	struct mmu_update rx_mmu[NET_RX_RING_SIZE];
>  
>  	/* Statistics */
> +	struct netfront_stats __percpu *stats;
> +
>  	unsigned long rx_gso_checksum_fixup;
>  };
>  
> @@ -468,6 +478,7 @@ static int xennet_start_xmit(struct sk_b
>  {
>  	unsigned short id;
>  	struct netfront_info *np = netdev_priv(dev);
> +	struct netfront_stats *stats = this_cpu_ptr(np->stats);
>  	struct xen_netif_tx_request *tx;
>  	struct xen_netif_extra_info *extra;
>  	char *data = skb->data;
> @@ -552,8 +563,10 @@ static int xennet_start_xmit(struct sk_b
>  	if (notify)
>  		notify_remote_via_irq(np->netdev->irq);
>  
> -	dev->stats.tx_bytes += skb->len;
> -	dev->stats.tx_packets++;
> +	u64_stats_update_begin(&stats->syncp);
> +	stats->tx_bytes += skb->len;
> +	stats->tx_packets++;
> +	u64_stats_update_end(&stats->syncp);
>  
>  	/* Note: It is not safe to access skb after xennet_tx_buf_gc()! */
>  	xennet_tx_buf_gc(dev);
> @@ -847,6 +860,8 @@ out:
>  static int handle_incoming_queue(struct net_device *dev,
>  				 struct sk_buff_head *rxq)
>  {
> +	struct netfront_info *np = netdev_priv(dev);
> +	struct netfront_stats *stats = this_cpu_ptr(np->stats);
>  	int packets_dropped = 0;
>  	struct sk_buff *skb;
>  
> @@ -871,8 +886,10 @@ static int handle_incoming_queue(struct
>  			continue;
>  		}
>  
> -		dev->stats.rx_packets++;
> -		dev->stats.rx_bytes += skb->len;
> +		u64_stats_update_begin(&stats->syncp);
> +		stats->rx_packets++;
> +		stats->rx_bytes += skb->len;
> +		u64_stats_update_end(&stats->syncp);
>  
>  		/* Pass it up. */
>  		netif_receive_skb(skb);
> @@ -1034,6 +1051,38 @@ static int xennet_change_mtu(struct net_
>  	return 0;
>  }
>  
> +static struct rtnl_link_stats64 *xennet_get_stats64(struct net_device *dev,
> +						    struct rtnl_link_stats64 *tot)
> +{
> +	struct netfront_info *np = netdev_priv(dev);
> +	int cpu;
> +
> +	for_each_possible_cpu(cpu) {
> +		struct netfront_stats *stats = per_cpu_ptr(np->stats, cpu);
> +		u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
> +		unsigned int start;
> +
> +		do {
> +			start = u64_stats_fetch_begin_bh(&stats->syncp);
> +
> +			rx_packets = stats->rx_packets;
> +			tx_packets = stats->tx_packets;
> +			rx_bytes = stats->rx_bytes;
> +			tx_bytes = stats->tx_bytes;
> +		} while (u64_stats_fetch_retry_bh(&stats->syncp, start));
> +
> +		tot->rx_packets += rx_packets;
> +		tot->tx_packets += tx_packets;
> +		tot->rx_bytes   += rx_bytes;
> +		tot->tx_bytes   += tx_bytes;
> +	}
> +
> +	tot->rx_errors  = dev->stats.rx_errors;
> +	tot->tx_dropped = dev->stats.tx_dropped;
> +
> +	return tot;
> +}
> +
>  static void xennet_release_tx_bufs(struct netfront_info *np)
>  {
>  	struct sk_buff *skb;
> @@ -1182,6 +1231,7 @@ static const struct net_device_ops xenne
>  	.ndo_stop            = xennet_close,
>  	.ndo_start_xmit      = xennet_start_xmit,
>  	.ndo_change_mtu	     = xennet_change_mtu,
> +	.ndo_get_stats64     = xennet_get_stats64,
>  	.ndo_set_mac_address = eth_mac_addr,
>  	.ndo_validate_addr   = eth_validate_addr,
>  	.ndo_fix_features    = xennet_fix_features,
> @@ -1216,6 +1266,11 @@ static struct net_device * __devinit xen
>  	np->rx_refill_timer.data = (unsigned long)netdev;
>  	np->rx_refill_timer.function = rx_refill_timeout;
>  
> +	err = -ENOMEM;
> +	np->stats = alloc_percpu(struct netfront_stats);
> +	if (np->stats == NULL)
> +		goto exit;
> +
>  	/* Initialise tx_skbs as a free chain containing every entry. */
>  	np->tx_skb_freelist = 0;
>  	for (i = 0; i < NET_TX_RING_SIZE; i++) {
> @@ -1234,7 +1289,7 @@ static struct net_device * __devinit xen
>  					  &np->gref_tx_head) < 0) {
>  		printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
>  		err = -ENOMEM;
> -		goto exit;
> +		goto exit_free_stats;
>  	}
>  	/* A grant for every rx ring slot */
>  	if (gnttab_alloc_grant_references(RX_MAX_TARGET,
> @@ -1270,6 +1325,8 @@ static struct net_device * __devinit xen
>  
>   exit_free_tx:
>  	gnttab_free_grant_references(np->gref_tx_head);
> + exit_free_stats:
> +	free_percpu(np->stats);
>   exit:
>  	free_netdev(netdev);
>  	return ERR_PTR(err);
> @@ -1869,6 +1926,8 @@ static int __devexit xennet_remove(struc
>  
>  	xennet_sysfs_delif(info->netdev);
>  
> +	free_percpu(info->stats);
> +
>  	free_netdev(info->netdev);
>  
>  	return 0;
> 



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 5/5] ifb: convert to 64 bit stats (v3)
  2011-06-21  0:04             ` jamal
@ 2011-06-21 22:55               ` David Miller
  0 siblings, 0 replies; 28+ messages in thread
From: David Miller @ 2011-06-21 22:55 UTC (permalink / raw)
  To: hadi; +Cc: eric.dumazet, shemminger, netdev

From: jamal <hadi@cyberus.ca>
Date: Mon, 20 Jun 2011 20:04:41 -0400

> On Mon, 2011-06-20 at 23:44 +0200, Eric Dumazet wrote:
> 
>> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> 
> Acked-by: Jamal Hadi Salim <hadi@cyberus.ca>

Applied.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next 1/5] vxge: fix 64 bit access on 32 bit platforms
  2011-06-20 20:35 ` [PATCH net-next 1/5] vxge: fix 64 bit access on 32 bit platforms Stephen Hemminger
@ 2011-06-21 22:56   ` David Miller
  0 siblings, 0 replies; 28+ messages in thread
From: David Miller @ 2011-06-21 22:56 UTC (permalink / raw)
  To: shemminger; +Cc: jdmason, netdev

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Mon, 20 Jun 2011 13:35:07 -0700

> Need to add stat_sync wrapper around 64 bit statistic values.
> Fix wraparound bug in lockup detector where it is unsafely comparing
> 64 bit value that is not atomic. Since only care about detecting activity
> just looking at current low order bits will work.
> 
> Remove unused entries in old vxge_sw_stats structure.
> Change the error counters to unsigned long since they won't grow so large
> as to have to be 64 bits.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

Applied.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Xen-devel] [PATCH net-next 4/5] xen: convert to 64 bit stats interface
  2011-06-21 15:38       ` Ian Campbell
@ 2011-06-21 22:57         ` David Miller
  0 siblings, 0 replies; 28+ messages in thread
From: David Miller @ 2011-06-21 22:57 UTC (permalink / raw)
  To: Ian.Campbell; +Cc: shemminger, Jeremy.Fitzhardinge, netdev, xen-devel

From: Ian Campbell <Ian.Campbell@eu.citrix.com>
Date: Tue, 21 Jun 2011 16:38:48 +0100

> On Tue, 2011-06-21 at 16:35 +0100, Stephen Hemminger wrote:
>> Convert xen driver to 64 bit statistics interface.
>> Use stats_sync to ensure that 64 bit update is read atomically on 32 bit platform.
>> Put hot statistics into per-cpu table.
>> 
>> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>> 
>> ---
>> v2 - add stats_sync and per-cpu
>> v2.1 - keep rx_errors on checksum error
> 
> Thanks. Looks good to me from the Xen side.
> 
> Acked-by: Ian Campbell <ian.campbell@citrix.com>

Applied.

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2011-06-21 22:57 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-20 20:35 [PATCH net-next 0/5] more statistics updates Stephen Hemminger
2011-06-20 20:35 ` [PATCH net-next 1/5] vxge: fix 64 bit access on 32 bit platforms Stephen Hemminger
2011-06-21 22:56   ` David Miller
2011-06-20 20:35 ` [PATCH net-next 2/5] niu: fix 64 bit statistics on 32 bit platform Stephen Hemminger
2011-06-20 21:45   ` Ben Hutchings
2011-06-20 21:52     ` Stephen Hemminger
2011-06-20 22:02       ` Eric Dumazet
2011-06-20 20:35 ` [PATCH net-next 3/5] netxen: make 64 bit stats safe " Stephen Hemminger
2011-06-20 21:50   ` Eric Dumazet
2011-06-20 21:52   ` Ben Hutchings
2011-06-20 22:18     ` Stephen Hemminger
2011-06-20 22:27       ` Ben Hutchings
2011-06-20 20:35 ` [PATCH net-next 4/5] xen: convert to 64 bit stats interface Stephen Hemminger
2011-06-21 14:05   ` [Xen-devel] " Ian Campbell
2011-06-21 15:29     ` Stephen Hemminger
2011-06-21 15:35     ` Stephen Hemminger
2011-06-21 15:38       ` Ian Campbell
2011-06-21 22:57         ` David Miller
2011-06-20 20:56 ` [PATCH net-next 0/5] more statistics updates David Miller
2011-06-20 21:12   ` [PATCH net-next 5/5] ifb: convert to 64 bit stats Stephen Hemminger
2011-06-20 21:23     ` Eric Dumazet
2011-06-20 21:27       ` Eric Dumazet
2011-06-20 21:38         ` Stephen Hemminger
2011-06-20 21:42           ` Eric Dumazet
2011-06-20 21:42         ` [PATCH net-next 5/5] ifb: convert to 64 bit stats (v3) Stephen Hemminger
2011-06-20 21:44           ` Eric Dumazet
2011-06-21  0:04             ` jamal
2011-06-21 22:55               ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).