diff mbox

[net-next,5/5] ifb: convert to 64 bit stats

Message ID 20110620141253.00249218@nehalam.ftrdhcpuser.net
State Superseded, archived
Delegated to: David Miller
Headers show

Commit Message

stephen hemminger June 20, 2011, 9:12 p.m. UTC
Convert input functional block device to use 64 bit stats.

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

---
v2 - add stats_sync


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Eric Dumazet June 20, 2011, 9:23 p.m. UTC | #1
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>


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Eric Dumazet June 20, 2011, 9:27 p.m. UTC | #2
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.



--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
stephen hemminger June 20, 2011, 9:38 p.m. UTC | #3
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?
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

--- 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;
 	}