Revert "net: Move {l,t,d}stats allocation to core and convert veth & vrf"

This reverts commit 877c81faf0 which is
commit 34d21de99cea9cb17967874313e5b0262527833c upstream.

It breaks the Android kernel abi and can be brought back in the future
in an abi-safe way if it is really needed.

Bug: 161946584
Change-Id: I9a8aac914cc10fb293d8ff1fcaedf88122f907a8
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2025-01-03 08:31:02 +00:00
parent 0b4ff5581f
commit b59a4bd0cc
4 changed files with 38 additions and 85 deletions

View File

@@ -1381,12 +1381,25 @@ static void veth_free_queues(struct net_device *dev)
static int veth_dev_init(struct net_device *dev) static int veth_dev_init(struct net_device *dev)
{ {
return veth_alloc_queues(dev); int err;
dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats);
if (!dev->lstats)
return -ENOMEM;
err = veth_alloc_queues(dev);
if (err) {
free_percpu(dev->lstats);
return err;
}
return 0;
} }
static void veth_dev_free(struct net_device *dev) static void veth_dev_free(struct net_device *dev)
{ {
veth_free_queues(dev); veth_free_queues(dev);
free_percpu(dev->lstats);
} }
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1612,7 +1625,6 @@ static void veth_setup(struct net_device *dev)
NETIF_F_HW_VLAN_STAG_RX); NETIF_F_HW_VLAN_STAG_RX);
dev->needs_free_netdev = true; dev->needs_free_netdev = true;
dev->priv_destructor = veth_dev_free; dev->priv_destructor = veth_dev_free;
dev->pcpu_stat_type = NETDEV_PCPU_STAT_LSTATS;
dev->max_mtu = ETH_MAX_MTU; dev->max_mtu = ETH_MAX_MTU;
dev->hw_features = VETH_FEATURES; dev->hw_features = VETH_FEATURES;

View File

@@ -121,12 +121,22 @@ struct net_vrf {
int ifindex; int ifindex;
}; };
struct pcpu_dstats {
u64 tx_pkts;
u64 tx_bytes;
u64 tx_drps;
u64 rx_pkts;
u64 rx_bytes;
u64 rx_drps;
struct u64_stats_sync syncp;
};
static void vrf_rx_stats(struct net_device *dev, int len) static void vrf_rx_stats(struct net_device *dev, int len)
{ {
struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
u64_stats_update_begin(&dstats->syncp); u64_stats_update_begin(&dstats->syncp);
dstats->rx_packets++; dstats->rx_pkts++;
dstats->rx_bytes += len; dstats->rx_bytes += len;
u64_stats_update_end(&dstats->syncp); u64_stats_update_end(&dstats->syncp);
} }
@@ -151,10 +161,10 @@ static void vrf_get_stats64(struct net_device *dev,
do { do {
start = u64_stats_fetch_begin_irq(&dstats->syncp); start = u64_stats_fetch_begin_irq(&dstats->syncp);
tbytes = dstats->tx_bytes; tbytes = dstats->tx_bytes;
tpkts = dstats->tx_packets; tpkts = dstats->tx_pkts;
tdrops = dstats->tx_drops; tdrops = dstats->tx_drps;
rbytes = dstats->rx_bytes; rbytes = dstats->rx_bytes;
rpkts = dstats->rx_packets; rpkts = dstats->rx_pkts;
} while (u64_stats_fetch_retry_irq(&dstats->syncp, start)); } while (u64_stats_fetch_retry_irq(&dstats->syncp, start));
stats->tx_bytes += tbytes; stats->tx_bytes += tbytes;
stats->tx_packets += tpkts; stats->tx_packets += tpkts;
@@ -411,7 +421,7 @@ static int vrf_local_xmit(struct sk_buff *skb, struct net_device *dev,
if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) if (likely(__netif_rx(skb) == NET_RX_SUCCESS))
vrf_rx_stats(dev, len); vrf_rx_stats(dev, len);
else else
this_cpu_inc(dev->dstats->rx_drops); this_cpu_inc(dev->dstats->rx_drps);
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
@@ -606,11 +616,11 @@ static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev)
struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
u64_stats_update_begin(&dstats->syncp); u64_stats_update_begin(&dstats->syncp);
dstats->tx_packets++; dstats->tx_pkts++;
dstats->tx_bytes += len; dstats->tx_bytes += len;
u64_stats_update_end(&dstats->syncp); u64_stats_update_end(&dstats->syncp);
} else { } else {
this_cpu_inc(dev->dstats->tx_drops); this_cpu_inc(dev->dstats->tx_drps);
} }
return ret; return ret;

View File

@@ -1780,13 +1780,6 @@ enum netdev_ml_priv_type {
ML_PRIV_CAN, ML_PRIV_CAN,
}; };
enum netdev_stat_type {
NETDEV_PCPU_STAT_NONE,
NETDEV_PCPU_STAT_LSTATS, /* struct pcpu_lstats */
NETDEV_PCPU_STAT_TSTATS, /* struct pcpu_sw_netstats */
NETDEV_PCPU_STAT_DSTATS, /* struct pcpu_dstats */
};
/** /**
* struct net_device - The DEVICE structure. * struct net_device - The DEVICE structure.
* *
@@ -1981,14 +1974,10 @@ enum netdev_stat_type {
* *
* @ml_priv: Mid-layer private * @ml_priv: Mid-layer private
* @ml_priv_type: Mid-layer private type * @ml_priv_type: Mid-layer private type
* * @lstats: Loopback statistics
* @pcpu_stat_type: Type of device statistics which the core should * @tstats: Tunnel statistics
* allocate/free: none, lstats, tstats, dstats. none * @dstats: Dummy statistics
* means the driver is handling statistics allocation/ * @vstats: Virtual ethernet statistics
* freeing internally.
* @lstats: Loopback statistics: packets, bytes
* @tstats: Tunnel statistics: RX/TX packets, RX/TX bytes
* @dstats: Dummy statistics: RX/TX/drop packets, RX/TX bytes
* *
* @garp_port: GARP * @garp_port: GARP
* @mrp_port: MRP * @mrp_port: MRP
@@ -2339,7 +2328,6 @@ struct net_device {
void *ml_priv; void *ml_priv;
enum netdev_ml_priv_type ml_priv_type; enum netdev_ml_priv_type ml_priv_type;
enum netdev_stat_type pcpu_stat_type:8;
union { union {
struct pcpu_lstats __percpu *lstats; struct pcpu_lstats __percpu *lstats;
struct pcpu_sw_netstats __percpu *tstats; struct pcpu_sw_netstats __percpu *tstats;
@@ -2737,16 +2725,6 @@ struct pcpu_sw_netstats {
struct u64_stats_sync syncp; struct u64_stats_sync syncp;
} __aligned(4 * sizeof(u64)); } __aligned(4 * sizeof(u64));
struct pcpu_dstats {
u64 rx_packets;
u64 rx_bytes;
u64 rx_drops;
u64 tx_packets;
u64 tx_bytes;
u64 tx_drops;
struct u64_stats_sync syncp;
} __aligned(8 * sizeof(u64));
struct pcpu_lstats { struct pcpu_lstats {
u64_stats_t packets; u64_stats_t packets;
u64_stats_t bytes; u64_stats_t bytes;

View File

@@ -10007,46 +10007,6 @@ void netif_tx_stop_all_queues(struct net_device *dev)
} }
EXPORT_SYMBOL(netif_tx_stop_all_queues); 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 * register_netdevice() - register a network device
* @dev: device to register * @dev: device to register
@@ -10107,15 +10067,11 @@ int register_netdevice(struct net_device *dev)
goto err_uninit; goto err_uninit;
} }
ret = netdev_do_alloc_pcpu_stats(dev);
if (ret)
goto err_uninit;
ret = -EBUSY; ret = -EBUSY;
if (!dev->ifindex) if (!dev->ifindex)
dev->ifindex = dev_new_index(net); dev->ifindex = dev_new_index(net);
else if (__dev_get_by_index(net, dev->ifindex)) else if (__dev_get_by_index(net, dev->ifindex))
goto err_free_pcpu; goto err_uninit;
/* Transfer changeable features to wanted_features and enable /* Transfer changeable features to wanted_features and enable
* software offloads (GSO and GRO). * software offloads (GSO and GRO).
@@ -10162,14 +10118,14 @@ int register_netdevice(struct net_device *dev)
ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev); ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev);
ret = notifier_to_errno(ret); ret = notifier_to_errno(ret);
if (ret) if (ret)
goto err_free_pcpu; goto err_uninit;
ret = netdev_register_kobject(dev); ret = netdev_register_kobject(dev);
write_lock(&dev_base_lock); write_lock(&dev_base_lock);
dev->reg_state = ret ? NETREG_UNREGISTERED : NETREG_REGISTERED; dev->reg_state = ret ? NETREG_UNREGISTERED : NETREG_REGISTERED;
write_unlock(&dev_base_lock); write_unlock(&dev_base_lock);
if (ret) if (ret)
goto err_free_pcpu; goto err_uninit;
__netdev_update_features(dev); __netdev_update_features(dev);
@@ -10216,8 +10172,6 @@ int register_netdevice(struct net_device *dev)
out: out:
return ret; return ret;
err_free_pcpu:
netdev_do_free_pcpu_stats(dev);
err_uninit: err_uninit:
if (dev->netdev_ops->ndo_uninit) if (dev->netdev_ops->ndo_uninit)
dev->netdev_ops->ndo_uninit(dev); dev->netdev_ops->ndo_uninit(dev);
@@ -10471,7 +10425,6 @@ void netdev_run_todo(void)
WARN_ON(rcu_access_pointer(dev->ip_ptr)); WARN_ON(rcu_access_pointer(dev->ip_ptr));
WARN_ON(rcu_access_pointer(dev->ip6_ptr)); WARN_ON(rcu_access_pointer(dev->ip6_ptr));
netdev_do_free_pcpu_stats(dev);
if (dev->priv_destructor) if (dev->priv_destructor)
dev->priv_destructor(dev); dev->priv_destructor(dev);
if (dev->needs_free_netdev) if (dev->needs_free_netdev)