Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b0c9cbb authored by stephen hemminger's avatar stephen hemminger Committed by David S. Miller
Browse files

ifb: convert to 64 bit stats



Convert input functional block device to use 64 bit stats.

Signed-off-by: default avatarStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Acked-by: default avatarJamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 43d620c8
Loading
Loading
Loading
Loading
+47 −9
Original line number Diff line number Diff line
@@ -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 *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->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 @@ static void ri_tasklet(unsigned long dev)

}

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