From c35badfe0d91b25312d195422c6525c89faf925e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 19 Jan 2023 11:36:11 +0000 Subject: [PATCH] Revert "net: add atomic_long_t to net_device_stats fields" This reverts commit 037db10e3f93f0d51ab3f52fbdaa7e67a7edd0b8 which is commit 6c1c5097781f563b70a81683ea6fdac21637573b upstream. It breaks the CRC checking for the Android KABI (doesn't really break any actual ABI, but it isn't nice.) As this isn't needed for Android systems at this point in time, just revert it to keep the CRC abi stable. If it is needed to come back, it can be reworked to be a CRC-abi neutral change if so desired. Bug: 161946584 Fixes: 037db10e3f93 ("net: add atomic_long_t to net_device_stats fields") Cc: Eric Dumazet Change-Id: I9d3d9fb55ab5482a4ea92fcc4a2fb70c4471edec Signed-off-by: Greg Kroah-Hartman --- include/linux/netdevice.h | 58 ++++++++++++++++----------------------- include/net/dst.h | 5 ++-- net/core/dev.c | 14 ++++++++-- 3 files changed, 37 insertions(+), 40 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 297a037a77f5..7e7a003dd25a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -167,38 +167,31 @@ static inline bool dev_xmit_complete(int rc) * (unsigned long) so they can be read and written atomically. */ -#define NET_DEV_STAT(FIELD) \ - union { \ - unsigned long FIELD; \ - atomic_long_t __##FIELD; \ - } - struct net_device_stats { - NET_DEV_STAT(rx_packets); - NET_DEV_STAT(tx_packets); - NET_DEV_STAT(rx_bytes); - NET_DEV_STAT(tx_bytes); - NET_DEV_STAT(rx_errors); - NET_DEV_STAT(tx_errors); - NET_DEV_STAT(rx_dropped); - NET_DEV_STAT(tx_dropped); - NET_DEV_STAT(multicast); - NET_DEV_STAT(collisions); - NET_DEV_STAT(rx_length_errors); - NET_DEV_STAT(rx_over_errors); - NET_DEV_STAT(rx_crc_errors); - NET_DEV_STAT(rx_frame_errors); - NET_DEV_STAT(rx_fifo_errors); - NET_DEV_STAT(rx_missed_errors); - NET_DEV_STAT(tx_aborted_errors); - NET_DEV_STAT(tx_carrier_errors); - NET_DEV_STAT(tx_fifo_errors); - NET_DEV_STAT(tx_heartbeat_errors); - NET_DEV_STAT(tx_window_errors); - NET_DEV_STAT(rx_compressed); - NET_DEV_STAT(tx_compressed); + unsigned long rx_packets; + unsigned long tx_packets; + unsigned long rx_bytes; + unsigned long tx_bytes; + unsigned long rx_errors; + unsigned long tx_errors; + unsigned long rx_dropped; + unsigned long tx_dropped; + unsigned long multicast; + unsigned long collisions; + unsigned long rx_length_errors; + unsigned long rx_over_errors; + unsigned long rx_crc_errors; + unsigned long rx_frame_errors; + unsigned long rx_fifo_errors; + unsigned long rx_missed_errors; + unsigned long tx_aborted_errors; + unsigned long tx_carrier_errors; + unsigned long tx_fifo_errors; + unsigned long tx_heartbeat_errors; + unsigned long tx_window_errors; + unsigned long rx_compressed; + unsigned long tx_compressed; }; -#undef NET_DEV_STAT #include @@ -5310,9 +5303,4 @@ do { \ extern struct net_device *blackhole_netdev; -/* Note: Avoid these macros in fast path, prefer per-cpu or per-queue counters. */ -#define DEV_STATS_INC(DEV, FIELD) atomic_long_inc(&(DEV)->stats.__##FIELD) -#define DEV_STATS_ADD(DEV, FIELD, VAL) \ - atomic_long_add((VAL), &(DEV)->stats.__##FIELD) - #endif /* _LINUX_NETDEVICE_H */ diff --git a/include/net/dst.h b/include/net/dst.h index ae2cf57d796b..acd15c544cf3 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -356,8 +356,9 @@ static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev, static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev, struct net *net) { - DEV_STATS_INC(dev, rx_packets); - DEV_STATS_ADD(dev, rx_bytes, skb->len); + /* TODO : stats should be SMP safe */ + dev->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; __skb_tunnel_rx(skb, dev, net); } diff --git a/net/core/dev.c b/net/core/dev.c index 5a31c6085a37..149504ef8f07 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -10325,16 +10325,24 @@ void netdev_run_todo(void) void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64, const struct net_device_stats *netdev_stats) { - size_t i, n = sizeof(*netdev_stats) / sizeof(atomic_long_t); - const atomic_long_t *src = (atomic_long_t *)netdev_stats; +#if BITS_PER_LONG == 64 + BUILD_BUG_ON(sizeof(*stats64) < sizeof(*netdev_stats)); + memcpy(stats64, netdev_stats, sizeof(*netdev_stats)); + /* zero out counters that only exist in rtnl_link_stats64 */ + memset((char *)stats64 + sizeof(*netdev_stats), 0, + sizeof(*stats64) - sizeof(*netdev_stats)); +#else + size_t i, n = sizeof(*netdev_stats) / sizeof(unsigned long); + const unsigned long *src = (const unsigned long *)netdev_stats; u64 *dst = (u64 *)stats64; BUILD_BUG_ON(n > sizeof(*stats64) / sizeof(u64)); for (i = 0; i < n; i++) - dst[i] = atomic_long_read(&src[i]); + dst[i] = src[i]; /* zero out counters that only exist in rtnl_link_stats64 */ memset((char *)stats64 + n * sizeof(u64), 0, sizeof(*stats64) - n * sizeof(u64)); +#endif } EXPORT_SYMBOL(netdev_stats_to_stats64);