Commit de7d5084 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

net: provide dev_lstats_read() helper



Many network drivers use hand-coded implementation of the same thing,
let's factorize things so that u64_stats_t adoption is done once.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0f030bdb
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -99,13 +99,13 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,
	return NETDEV_TX_OK;
}

static void loopback_get_stats64(struct net_device *dev,
				 struct rtnl_link_stats64 *stats)
void dev_lstats_read(struct net_device *dev, u64 *packets, u64 *bytes)
{
	u64 bytes = 0;
	u64 packets = 0;
	int i;

	*packets = 0;
	*bytes = 0;

	for_each_possible_cpu(i) {
		const struct pcpu_lstats *lb_stats;
		u64 tbytes, tpackets;
@@ -114,12 +114,22 @@ static void loopback_get_stats64(struct net_device *dev,
		lb_stats = per_cpu_ptr(dev->lstats, i);
		do {
			start = u64_stats_fetch_begin_irq(&lb_stats->syncp);
			tbytes = lb_stats->bytes;
			tpackets = lb_stats->packets;
			tbytes = lb_stats->bytes;
		} while (u64_stats_fetch_retry_irq(&lb_stats->syncp, start));
		bytes   += tbytes;
		packets += tpackets;
		*bytes   += tbytes;
		*packets += tpackets;
	}
}
EXPORT_SYMBOL(dev_lstats_read);

static void loopback_get_stats64(struct net_device *dev,
				 struct rtnl_link_stats64 *stats)
{
	u64 packets, bytes;

	dev_lstats_read(dev, &packets, &bytes);

	stats->rx_packets = packets;
	stats->tx_packets = packets;
	stats->rx_bytes   = bytes;
+2 −0
Original line number Diff line number Diff line
@@ -2401,6 +2401,8 @@ struct pcpu_lstats {
	struct u64_stats_sync syncp;
} __aligned(2 * sizeof(u64));

void dev_lstats_read(struct net_device *dev, u64 *packets, u64 *bytes);

#define __netdev_alloc_pcpu_stats(type, gfp)				\
({									\
	typeof(type) __percpu *pcpu_stats = alloc_percpu_gfp(type, gfp);\