mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-09 03:20:05 +00:00
net: Move {l,t,d}stats allocation to core and convert veth & vrf
Move {l,t,d}stats allocation to the core and let netdevs pick the stats
type they need. That way the driver doesn't have to bother with error
handling (allocation failure checking, making sure free happens in the
right spot, etc) - all happening in the core.
Co-developed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Cc: David Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20231114004220.6495-3-daniel@iogearbox.net
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
This commit is contained in:
committed by
Martin KaFai Lau
parent
79e0c5be8c
commit
34d21de99c
@@ -10051,6 +10051,46 @@ void netif_tx_stop_all_queues(struct net_device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL(netif_tx_stop_all_queues);
|
||||
|
||||
static int netdev_do_alloc_pcpu_stats(struct net_device *dev)
|
||||
{
|
||||
void __percpu *v;
|
||||
|
||||
switch (dev->pcpu_stat_type) {
|
||||
case NETDEV_PCPU_STAT_NONE:
|
||||
return 0;
|
||||
case NETDEV_PCPU_STAT_LSTATS:
|
||||
v = dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats);
|
||||
break;
|
||||
case NETDEV_PCPU_STAT_TSTATS:
|
||||
v = dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
|
||||
break;
|
||||
case NETDEV_PCPU_STAT_DSTATS:
|
||||
v = dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return v ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
static void netdev_do_free_pcpu_stats(struct net_device *dev)
|
||||
{
|
||||
switch (dev->pcpu_stat_type) {
|
||||
case NETDEV_PCPU_STAT_NONE:
|
||||
return;
|
||||
case NETDEV_PCPU_STAT_LSTATS:
|
||||
free_percpu(dev->lstats);
|
||||
break;
|
||||
case NETDEV_PCPU_STAT_TSTATS:
|
||||
free_percpu(dev->tstats);
|
||||
break;
|
||||
case NETDEV_PCPU_STAT_DSTATS:
|
||||
free_percpu(dev->dstats);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* register_netdevice() - register a network device
|
||||
* @dev: device to register
|
||||
@@ -10111,9 +10151,13 @@ int register_netdevice(struct net_device *dev)
|
||||
goto err_uninit;
|
||||
}
|
||||
|
||||
ret = netdev_do_alloc_pcpu_stats(dev);
|
||||
if (ret)
|
||||
goto err_uninit;
|
||||
|
||||
ret = dev_index_reserve(net, dev->ifindex);
|
||||
if (ret < 0)
|
||||
goto err_uninit;
|
||||
goto err_free_pcpu;
|
||||
dev->ifindex = ret;
|
||||
|
||||
/* Transfer changeable features to wanted_features and enable
|
||||
@@ -10219,6 +10263,8 @@ err_uninit_notify:
|
||||
call_netdevice_notifiers(NETDEV_PRE_UNINIT, dev);
|
||||
err_ifindex_release:
|
||||
dev_index_release(net, dev->ifindex);
|
||||
err_free_pcpu:
|
||||
netdev_do_free_pcpu_stats(dev);
|
||||
err_uninit:
|
||||
if (dev->netdev_ops->ndo_uninit)
|
||||
dev->netdev_ops->ndo_uninit(dev);
|
||||
@@ -10471,6 +10517,7 @@ void netdev_run_todo(void)
|
||||
WARN_ON(rcu_access_pointer(dev->ip_ptr));
|
||||
WARN_ON(rcu_access_pointer(dev->ip6_ptr));
|
||||
|
||||
netdev_do_free_pcpu_stats(dev);
|
||||
if (dev->priv_destructor)
|
||||
dev->priv_destructor(dev);
|
||||
if (dev->needs_free_netdev)
|
||||
|
||||
Reference in New Issue
Block a user