Commit 18eabadd authored by Guillaume Nault's avatar Guillaume Nault Committed by Jakub Kicinski
Browse files

vrf: Make pcpu_dstats update functions available to other modules.



Currently vrf is the only module that uses NETDEV_PCPU_STAT_DSTATS.
In order to make this kind of statistics available to other modules,
we need to define the update functions in netdevice.h.

Therefore, let's define dev_dstats_*() functions for RX and TX packet
updates (packets, bytes and drops). Use these new functions in vrf.c
instead of vrf_rx_stats() and the other manual counter updates.

While there, update the type of the "len" variables to "unsigned int",
so that there're aligned with both skb->len and the new dstats update
functions.

Signed-off-by: default avatarGuillaume Nault <gnault@redhat.com>
Link: https://patch.msgid.link/d7a552ee382c79f4854e7fcc224cf176cd21150d.1733313925.git.gnault@redhat.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 9ec780b2
Loading
Loading
Loading
Loading
+14 −35
Original line number Diff line number Diff line
@@ -122,16 +122,6 @@ struct net_vrf {
	int			ifindex;
};

static void vrf_rx_stats(struct net_device *dev, int len)
{
	struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);

	u64_stats_update_begin(&dstats->syncp);
	u64_stats_inc(&dstats->rx_packets);
	u64_stats_add(&dstats->rx_bytes, len);
	u64_stats_update_end(&dstats->syncp);
}

static void vrf_tx_error(struct net_device *vrf_dev, struct sk_buff *skb)
{
	vrf_dev->stats.tx_errors++;
@@ -369,7 +359,7 @@ static bool qdisc_tx_is_default(const struct net_device *dev)
static int vrf_local_xmit(struct sk_buff *skb, struct net_device *dev,
			  struct dst_entry *dst)
{
	int len = skb->len;
	unsigned int len = skb->len;

	skb_orphan(skb);

@@ -382,15 +372,10 @@ static int vrf_local_xmit(struct sk_buff *skb, struct net_device *dev,

	skb->protocol = eth_type_trans(skb, dev);

	if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) {
		vrf_rx_stats(dev, len);
	} else {
		struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);

		u64_stats_update_begin(&dstats->syncp);
		u64_stats_inc(&dstats->rx_drops);
		u64_stats_update_end(&dstats->syncp);
	}
	if (likely(__netif_rx(skb) == NET_RX_SUCCESS))
		dev_dstats_rx_add(dev, len);
	else
		dev_dstats_rx_dropped(dev);

	return NETDEV_TX_OK;
}
@@ -578,20 +563,14 @@ static netdev_tx_t is_ip_tx_frame(struct sk_buff *skb, struct net_device *dev)

static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);

	int len = skb->len;
	netdev_tx_t ret = is_ip_tx_frame(skb, dev);

	u64_stats_update_begin(&dstats->syncp);
	if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
	unsigned int len = skb->len;
	netdev_tx_t ret;

		u64_stats_inc(&dstats->tx_packets);
		u64_stats_add(&dstats->tx_bytes, len);
	} else {
		u64_stats_inc(&dstats->tx_drops);
	}
	u64_stats_update_end(&dstats->syncp);
	ret = is_ip_tx_frame(skb, dev);
	if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN))
		dev_dstats_tx_add(dev, len);
	else
		dev_dstats_tx_dropped(dev);

	return ret;
}
@@ -1364,7 +1343,7 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
	if (!is_ndisc) {
		struct net_device *orig_dev = skb->dev;

		vrf_rx_stats(vrf_dev, skb->len);
		dev_dstats_rx_add(vrf_dev, skb->len);
		skb->dev = vrf_dev;
		skb->skb_iif = vrf_dev->ifindex;

@@ -1420,7 +1399,7 @@ static struct sk_buff *vrf_ip_rcv(struct net_device *vrf_dev,
		goto out;
	}

	vrf_rx_stats(vrf_dev, skb->len);
	dev_dstats_rx_add(vrf_dev, skb->len);

	if (!list_empty(&vrf_dev->ptype_all)) {
		int err;
+40 −0
Original line number Diff line number Diff line
@@ -2854,6 +2854,46 @@ static inline void dev_lstats_add(struct net_device *dev, unsigned int len)
	u64_stats_update_end(&lstats->syncp);
}

static inline void dev_dstats_rx_add(struct net_device *dev,
				     unsigned int len)
{
	struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);

	u64_stats_update_begin(&dstats->syncp);
	u64_stats_inc(&dstats->rx_packets);
	u64_stats_add(&dstats->rx_bytes, len);
	u64_stats_update_end(&dstats->syncp);
}

static inline void dev_dstats_rx_dropped(struct net_device *dev)
{
	struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);

	u64_stats_update_begin(&dstats->syncp);
	u64_stats_inc(&dstats->rx_drops);
	u64_stats_update_end(&dstats->syncp);
}

static inline void dev_dstats_tx_add(struct net_device *dev,
				     unsigned int len)
{
	struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);

	u64_stats_update_begin(&dstats->syncp);
	u64_stats_inc(&dstats->tx_packets);
	u64_stats_add(&dstats->tx_bytes, len);
	u64_stats_update_end(&dstats->syncp);
}

static inline void dev_dstats_tx_dropped(struct net_device *dev)
{
	struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);

	u64_stats_update_begin(&dstats->syncp);
	u64_stats_inc(&dstats->tx_drops);
	u64_stats_update_end(&dstats->syncp);
}

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