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: Guillaume Nault <gnault@redhat.com>
Link: https://patch.msgid.link/d7a552ee382c79f4854e7fcc224cf176cd21150d.1733313925.git.gnault@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Guillaume Nault 2024-12-04 13:11:21 +01:00 committed by Jakub Kicinski
parent 9ec780b269
commit 18eabadd73
2 changed files with 54 additions and 35 deletions

View File

@ -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);
unsigned int len = skb->len;
netdev_tx_t ret;
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)) {
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;

View File

@ -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);\