Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netdevice: convert private flags > BIT(31) to bitfields

Make dev->priv_flags `u32` back and define bits higher than 31 as
bitfield booleans as per Jakub's suggestion. This simplifies code
which accesses these bits with no optimization loss (testb both
before/after), allows to not extend &netdev_priv_flags each time,
but also scales better as bits > 63 in the future would only add
a new u64 to the structure with no complications, comparing to
that extending ::priv_flags would require converting it to a bitmap.
Note that I picked `unsigned long :1` to not lose any potential
optimizations comparing to `bool :1` etc.

Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Alexander Lobakin and committed by
Paolo Abeni
beb5a9be 075e3d30

+35 -24
+3 -1
Documentation/networking/net_cachelines/net_device.rst
··· 7 7 8 8 Type Name fastpath_tx_access fastpath_rx_access Comments 9 9 ..struct ..net_device 10 + unsigned_long:32 priv_flags read_mostly - __dev_queue_xmit(tx) 10 11 char name[16] - - 11 12 struct_netdev_name_node* name_node 12 13 struct_dev_ifalias* ifalias ··· 24 23 struct adj_list 25 24 unsigned_int flags read_mostly read_mostly __dev_queue_xmit,__dev_xmit_skb,ip6_output,__ip6_finish_output(tx);ip6_rcv_core(rx) 26 25 xdp_features_t xdp_features 27 - unsigned_long_long priv_flags read_mostly - __dev_queue_xmit(tx) 28 26 struct_net_device_ops* netdev_ops read_mostly - netdev_core_pick_tx,netdev_start_xmit(tx) 29 27 struct_xdp_metadata_ops* xdp_metadata_ops 30 28 int ifindex - read_mostly ip6_rcv_core ··· 163 163 bool proto_down 164 164 unsigned:1 wol_enabled 165 165 unsigned:1 threaded - - napi_poll(napi_enable,dev_set_threaded) 166 + unsigned_long:1 see_all_hwtstamp_requests 167 + unsigned_long:1 change_proto_down 166 168 struct_list_head net_notifier_list 167 169 struct_macsec_ops* macsec_ops 168 170 struct_udp_tunnel_nic_info* udp_tunnel_nic_info
+1 -1
drivers/net/ethernet/microchip/lan966x/lan966x_main.c
··· 816 816 NETIF_F_HW_VLAN_STAG_TX | 817 817 NETIF_F_HW_TC; 818 818 dev->hw_features |= NETIF_F_HW_TC; 819 - dev->priv_flags |= IFF_SEE_ALL_HWTSTAMP_REQUESTS; 819 + dev->see_all_hwtstamp_requests = true; 820 820 dev->needed_headroom = IFH_LEN_BYTES; 821 821 822 822 eth_hw_addr_gen(dev, lan966x->base_mac, p + 1);
+2 -1
drivers/net/macvlan.c
··· 1213 1213 dev->max_mtu = ETH_MAX_MTU; 1214 1214 dev->priv_flags &= ~IFF_TX_SKB_SHARING; 1215 1215 netif_keep_dst(dev); 1216 - dev->priv_flags |= IFF_UNICAST_FLT | IFF_CHANGE_PROTO_DOWN; 1216 + dev->priv_flags |= IFF_UNICAST_FLT; 1217 + dev->change_proto_down = true; 1217 1218 dev->netdev_ops = &macvlan_netdev_ops; 1218 1219 dev->needs_free_netdev = true; 1219 1220 dev->priv_destructor = macvlan_dev_free;
+2 -1
drivers/net/vxlan/vxlan_core.c
··· 3331 3331 dev->hw_features |= NETIF_F_RXCSUM; 3332 3332 dev->hw_features |= NETIF_F_GSO_SOFTWARE; 3333 3333 netif_keep_dst(dev); 3334 - dev->priv_flags |= IFF_NO_QUEUE | IFF_CHANGE_PROTO_DOWN; 3334 + dev->priv_flags |= IFF_NO_QUEUE; 3335 + dev->change_proto_down = true; 3335 3336 3336 3337 /* MTU range: 68 - 65535 */ 3337 3338 dev->min_mtu = ETH_MIN_MTU;
+18 -10
include/linux/netdevice.h
··· 1613 1613 * userspace; this means that the order of these flags can change 1614 1614 * during any kernel release. 1615 1615 * 1616 - * You should have a pretty good reason to be extending these flags. 1616 + * You should add bitfield booleans after either net_device::priv_flags 1617 + * (hotpath) or ::threaded (slowpath) instead of extending these flags. 1617 1618 * 1618 1619 * @IFF_802_1Q_VLAN: 802.1Q VLAN device 1619 1620 * @IFF_EBRIDGE: Ethernet bridging device ··· 1653 1652 * @IFF_NO_ADDRCONF: prevent ipv6 addrconf 1654 1653 * @IFF_TX_SKB_NO_LINEAR: device/driver is capable of xmitting frames with 1655 1654 * skb_headlen(skb) == 0 (data starts from frag0) 1656 - * @IFF_CHANGE_PROTO_DOWN: device supports setting carrier via IFLA_PROTO_DOWN 1657 - * @IFF_SEE_ALL_HWTSTAMP_REQUESTS: device wants to see calls to 1658 - * ndo_hwtstamp_set() for all timestamp requests regardless of source, 1659 - * even if those aren't HWTSTAMP_SOURCE_NETDEV. 1660 1655 */ 1661 1656 enum netdev_priv_flags { 1662 1657 IFF_802_1Q_VLAN = 1<<0, ··· 1687 1690 IFF_L3MDEV_RX_HANDLER = 1<<29, 1688 1691 IFF_NO_ADDRCONF = BIT_ULL(30), 1689 1692 IFF_TX_SKB_NO_LINEAR = BIT_ULL(31), 1690 - IFF_CHANGE_PROTO_DOWN = BIT_ULL(32), 1691 - IFF_SEE_ALL_HWTSTAMP_REQUESTS = BIT_ULL(33), 1692 1693 }; 1693 1694 1694 1695 /* Specifies the type of the struct net_device::ml_priv pointer */ ··· 1717 1722 * Actually, this whole structure is a big mistake. It mixes I/O 1718 1723 * data with strictly "high-level" data, and it has to know about 1719 1724 * almost every data structure used in the INET module. 1725 + * 1726 + * @priv_flags: flags invisible to userspace defined as bits, see 1727 + * enum netdev_priv_flags for the definitions 1720 1728 * 1721 1729 * @name: This is the first field of the "visible" part of this structure 1722 1730 * (i.e. as seen by users in the "Space.c" file). It is the name ··· 1787 1789 * 1788 1790 * @flags: Interface flags (a la BSD) 1789 1791 * @xdp_features: XDP capability supported by the device 1790 - * @priv_flags: Like 'flags' but invisible to userspace, 1791 - * see if.h for the definitions 1792 1792 * @gflags: Global flags ( kept as legacy ) 1793 1793 * @priv_len: Size of the ->priv flexible array 1794 1794 * @priv: Flexible array containing private data ··· 1960 1964 * 1961 1965 * @threaded: napi threaded mode is enabled 1962 1966 * 1967 + * @see_all_hwtstamp_requests: device wants to see calls to 1968 + * ndo_hwtstamp_set() for all timestamp requests 1969 + * regardless of source, even if those aren't 1970 + * HWTSTAMP_SOURCE_NETDEV 1971 + * @change_proto_down: device supports setting carrier via IFLA_PROTO_DOWN 1972 + * 1963 1973 * @net_notifier_list: List of per-net netdev notifier block 1964 1974 * that follow this device when it is moved 1965 1975 * to another network namespace. ··· 2016 2014 2017 2015 /* TX read-mostly hotpath */ 2018 2016 __cacheline_group_begin(net_device_read_tx); 2019 - unsigned long long priv_flags; 2017 + struct_group(priv_flags_fast, 2018 + unsigned long priv_flags:32; 2019 + ); 2020 2020 const struct net_device_ops *netdev_ops; 2021 2021 const struct header_ops *header_ops; 2022 2022 struct netdev_queue *_tx; ··· 2353 2349 struct lock_class_key *qdisc_tx_busylock; 2354 2350 bool proto_down; 2355 2351 bool threaded; 2352 + 2353 + /* priv_flags_slow, ungrouped to save space */ 2354 + unsigned long see_all_hwtstamp_requests:1; 2355 + unsigned long change_proto_down:1; 2356 2356 2357 2357 struct list_head net_notifier_list; 2358 2358
+2 -2
net/8021q/vlanproc.c
··· 238 238 239 239 stats = dev_get_stats(vlandev, &temp); 240 240 seq_printf(seq, 241 - "%s VID: %d REORDER_HDR: %i dev->priv_flags: %llx\n", 241 + "%s VID: %d REORDER_HDR: %i dev->priv_flags: %x\n", 242 242 vlandev->name, vlan->vlan_id, 243 - (int)(vlan->flags & 1), vlandev->priv_flags); 243 + (int)(vlan->flags & 1), (u32)vlandev->priv_flags); 244 244 245 245 seq_printf(seq, fmt64, "total frames received", stats->rx_packets); 246 246 seq_printf(seq, fmt64, "total bytes received", stats->rx_bytes);
+2 -2
net/core/dev.c
··· 9274 9274 */ 9275 9275 int dev_change_proto_down(struct net_device *dev, bool proto_down) 9276 9276 { 9277 - if (!(dev->priv_flags & IFF_CHANGE_PROTO_DOWN)) 9277 + if (!dev->change_proto_down) 9278 9278 return -EOPNOTSUPP; 9279 9279 if (!netif_device_present(dev)) 9280 9280 return -ENODEV; ··· 11930 11930 static void __init net_dev_struct_check(void) 11931 11931 { 11932 11932 /* TX read-mostly hotpath */ 11933 - CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_tx, priv_flags); 11933 + CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_tx, priv_flags_fast); 11934 11934 CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_tx, netdev_ops); 11935 11935 CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_tx, header_ops); 11936 11936 CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_tx, _tx);
+4 -5
net/core/dev_ioctl.c
··· 317 317 * should take precedence in front of hardware timestamping provided by the 318 318 * netdev. If the netdev driver needs to perform specific actions even for PHY 319 319 * timestamping to work properly (a switch port must trap the timestamped 320 - * frames and not forward them), it must set IFF_SEE_ALL_HWTSTAMP_REQUESTS in 321 - * dev->priv_flags. 320 + * frames and not forward them), it must set dev->see_all_hwtstamp_requests. 322 321 */ 323 322 int dev_set_hwtstamp_phylib(struct net_device *dev, 324 323 struct kernel_hwtstamp_config *cfg, ··· 331 332 332 333 cfg->source = phy_ts ? HWTSTAMP_SOURCE_PHYLIB : HWTSTAMP_SOURCE_NETDEV; 333 334 334 - if (phy_ts && (dev->priv_flags & IFF_SEE_ALL_HWTSTAMP_REQUESTS)) { 335 + if (phy_ts && dev->see_all_hwtstamp_requests) { 335 336 err = ops->ndo_hwtstamp_get(dev, &old_cfg); 336 337 if (err) 337 338 return err; 338 339 } 339 340 340 - if (!phy_ts || (dev->priv_flags & IFF_SEE_ALL_HWTSTAMP_REQUESTS)) { 341 + if (!phy_ts || dev->see_all_hwtstamp_requests) { 341 342 err = ops->ndo_hwtstamp_set(dev, cfg, extack); 342 343 if (err) { 343 344 if (extack->_msg) ··· 346 347 } 347 348 } 348 349 349 - if (phy_ts && (dev->priv_flags & IFF_SEE_ALL_HWTSTAMP_REQUESTS)) 350 + if (phy_ts && dev->see_all_hwtstamp_requests) 350 351 changed = kernel_hwtstamp_config_changed(&old_cfg, cfg); 351 352 352 353 if (phy_ts) {
+1 -1
net/core/rtnetlink.c
··· 2724 2724 bool proto_down; 2725 2725 int err; 2726 2726 2727 - if (!(dev->priv_flags & IFF_CHANGE_PROTO_DOWN)) { 2727 + if (!dev->change_proto_down) { 2728 2728 NL_SET_ERR_MSG(extack, "Protodown not supported by device"); 2729 2729 return -EOPNOTSUPP; 2730 2730 }