From b59a4bd0ccd4df327fff1612ec8c99b9487c5fc5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 3 Jan 2025 08:31:02 +0000 Subject: [PATCH] Revert "net: Move {l,t,d}stats allocation to core and convert veth & vrf" This reverts commit 877c81faf00548720a7f436538865070a5d63c96 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 --- drivers/net/veth.c | 16 ++++++++++-- drivers/net/vrf.c | 24 ++++++++++++------ include/linux/netdevice.h | 30 +++------------------- net/core/dev.c | 53 +++------------------------------------ 4 files changed, 38 insertions(+), 85 deletions(-) diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 0a8154611d7f..8dcd3b6e143b 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -1381,12 +1381,25 @@ static void veth_free_queues(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) { veth_free_queues(dev); + free_percpu(dev->lstats); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -1612,7 +1625,6 @@ static void veth_setup(struct net_device *dev) NETIF_F_HW_VLAN_STAG_RX); dev->needs_free_netdev = true; dev->priv_destructor = veth_dev_free; - dev->pcpu_stat_type = NETDEV_PCPU_STAT_LSTATS; dev->max_mtu = ETH_MAX_MTU; dev->hw_features = VETH_FEATURES; diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index c8a1009d659e..208df4d41939 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -121,12 +121,22 @@ struct net_vrf { 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) { struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); u64_stats_update_begin(&dstats->syncp); - dstats->rx_packets++; + dstats->rx_pkts++; dstats->rx_bytes += len; u64_stats_update_end(&dstats->syncp); } @@ -151,10 +161,10 @@ static void vrf_get_stats64(struct net_device *dev, do { start = u64_stats_fetch_begin_irq(&dstats->syncp); tbytes = dstats->tx_bytes; - tpkts = dstats->tx_packets; - tdrops = dstats->tx_drops; + tpkts = dstats->tx_pkts; + tdrops = dstats->tx_drps; rbytes = dstats->rx_bytes; - rpkts = dstats->rx_packets; + rpkts = dstats->rx_pkts; } while (u64_stats_fetch_retry_irq(&dstats->syncp, start)); stats->tx_bytes += tbytes; 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)) vrf_rx_stats(dev, len); else - this_cpu_inc(dev->dstats->rx_drops); + this_cpu_inc(dev->dstats->rx_drps); 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); u64_stats_update_begin(&dstats->syncp); - dstats->tx_packets++; + dstats->tx_pkts++; dstats->tx_bytes += len; u64_stats_update_end(&dstats->syncp); } else { - this_cpu_inc(dev->dstats->tx_drops); + this_cpu_inc(dev->dstats->tx_drps); } return ret; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index de47887d6f7f..e7ce7eab7e58 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1780,13 +1780,6 @@ enum netdev_ml_priv_type { 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. * @@ -1981,14 +1974,10 @@ enum netdev_stat_type { * * @ml_priv: Mid-layer private * @ml_priv_type: Mid-layer private type - * - * @pcpu_stat_type: Type of device statistics which the core should - * allocate/free: none, lstats, tstats, dstats. none - * means the driver is handling statistics allocation/ - * 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 + * @lstats: Loopback statistics + * @tstats: Tunnel statistics + * @dstats: Dummy statistics + * @vstats: Virtual ethernet statistics * * @garp_port: GARP * @mrp_port: MRP @@ -2339,7 +2328,6 @@ struct net_device { void *ml_priv; enum netdev_ml_priv_type ml_priv_type; - enum netdev_stat_type pcpu_stat_type:8; union { struct pcpu_lstats __percpu *lstats; struct pcpu_sw_netstats __percpu *tstats; @@ -2737,16 +2725,6 @@ struct pcpu_sw_netstats { struct u64_stats_sync syncp; } __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 { u64_stats_t packets; u64_stats_t bytes; diff --git a/net/core/dev.c b/net/core/dev.c index 2ff2af24cadb..a986f083c166 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -10007,46 +10007,6 @@ 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 @@ -10107,15 +10067,11 @@ int register_netdevice(struct net_device *dev) goto err_uninit; } - ret = netdev_do_alloc_pcpu_stats(dev); - if (ret) - goto err_uninit; - ret = -EBUSY; if (!dev->ifindex) dev->ifindex = dev_new_index(net); else if (__dev_get_by_index(net, dev->ifindex)) - goto err_free_pcpu; + goto err_uninit; /* Transfer changeable features to wanted_features and enable * 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 = notifier_to_errno(ret); if (ret) - goto err_free_pcpu; + goto err_uninit; ret = netdev_register_kobject(dev); write_lock(&dev_base_lock); dev->reg_state = ret ? NETREG_UNREGISTERED : NETREG_REGISTERED; write_unlock(&dev_base_lock); if (ret) - goto err_free_pcpu; + goto err_uninit; __netdev_update_features(dev); @@ -10216,8 +10172,6 @@ int register_netdevice(struct net_device *dev) out: return ret; -err_free_pcpu: - netdev_do_free_pcpu_stats(dev); err_uninit: if (dev->netdev_ops->ndo_uninit) 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->ip6_ptr)); - netdev_do_free_pcpu_stats(dev); if (dev->priv_destructor) dev->priv_destructor(dev); if (dev->needs_free_netdev)