]> www.infradead.org Git - users/hch/misc.git/commitdiff
net: hold netdev instance lock during sysfs operations
authorStanislav Fomichev <sdf@fomichev.me>
Wed, 5 Mar 2025 16:37:26 +0000 (08:37 -0800)
committerJakub Kicinski <kuba@kernel.org>
Thu, 6 Mar 2025 20:59:44 +0000 (12:59 -0800)
Most of them are already covered by the converted dev_xxx APIs.
Add the locking wrappers for the remaining ones.

Cc: Saeed Mahameed <saeed@kernel.org>
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250305163732.2766420-9-sdf@fomichev.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/bonding/bond_main.c
include/linux/netdevice.h
net/core/dev.c
net/core/dev_api.c
net/core/net-sysfs.c

index cd4afeb9ad42e4c2da28a3e36c4b0bcd2378eaa6..cf0b02720dd82e9ea4f7fbdeff44b5a450f6128c 100644 (file)
@@ -2644,10 +2644,13 @@ static int __bond_release_one(struct net_device *bond_dev,
                dev_set_mac_address(slave_dev, (struct sockaddr *)&ss, NULL);
        }
 
-       if (unregister)
+       if (unregister) {
+               netdev_lock_ops(slave_dev);
                __dev_set_mtu(slave_dev, slave->original_mtu);
-       else
+               netdev_unlock_ops(slave_dev);
+       } else {
                dev_set_mtu(slave_dev, slave->original_mtu);
+       }
 
        if (!netif_is_bond_master(slave_dev))
                slave_dev->priv_flags &= ~IFF_BONDING;
index 8d243c0ec39d15ec4450f57b1cb2f6bf61580055..c61b128095881aaac4b657dd097930f9dd3adff5 100644 (file)
@@ -3382,6 +3382,7 @@ void dev_close(struct net_device *dev);
 void dev_close_many(struct list_head *head, bool unlink);
 int dev_setup_tc(struct net_device *dev, enum tc_setup_type type,
                 void *type_data);
+void netif_disable_lro(struct net_device *dev);
 void dev_disable_lro(struct net_device *dev);
 int dev_loopback_xmit(struct net *net, struct sock *sk, struct sk_buff *newskb);
 u16 dev_pick_tx_zero(struct net_device *dev, struct sk_buff *skb,
@@ -4257,6 +4258,8 @@ int netif_set_mtu(struct net_device *dev, int new_mtu);
 int dev_set_mtu(struct net_device *, int);
 int dev_pre_changeaddr_notify(struct net_device *dev, const char *addr,
                              struct netlink_ext_ack *extack);
+int netif_set_mac_address(struct net_device *dev, struct sockaddr *sa,
+                         struct netlink_ext_ack *extack);
 int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
                        struct netlink_ext_ack *extack);
 int netif_set_mac_address_user(struct net_device *dev, struct sockaddr *sa,
@@ -5016,6 +5019,7 @@ static inline void __dev_mc_unsync(struct net_device *dev,
 /* Functions used for secondary unicast and multicast support */
 void dev_set_rx_mode(struct net_device *dev);
 int dev_set_promiscuity(struct net_device *dev, int inc);
+int netif_set_allmulti(struct net_device *dev, int inc, bool notify);
 int dev_set_allmulti(struct net_device *dev, int inc);
 void netdev_state_change(struct net_device *dev);
 void __netdev_notify_peers(struct net_device *dev);
index 97a4fc0889d344999bca67ca61a0912e0338f663..121c0449f87f71509714b7cee0da80afeea0afe9 100644 (file)
@@ -1757,15 +1757,7 @@ int dev_setup_tc(struct net_device *dev, enum tc_setup_type type,
 }
 EXPORT_SYMBOL(dev_setup_tc);
 
-/**
- *     dev_disable_lro - disable Large Receive Offload on a device
- *     @dev: device
- *
- *     Disable Large Receive Offload (LRO) on a net device.  Must be
- *     called under RTNL.  This is needed if received packets may be
- *     forwarded to another interface.
- */
-void dev_disable_lro(struct net_device *dev)
+void netif_disable_lro(struct net_device *dev)
 {
        struct net_device *lower_dev;
        struct list_head *iter;
@@ -1776,10 +1768,12 @@ void dev_disable_lro(struct net_device *dev)
        if (unlikely(dev->features & NETIF_F_LRO))
                netdev_WARN(dev, "failed to disable LRO!\n");
 
-       netdev_for_each_lower_dev(dev, lower_dev, iter)
-               dev_disable_lro(lower_dev);
+       netdev_for_each_lower_dev(dev, lower_dev, iter) {
+               netdev_lock_ops(lower_dev);
+               netif_disable_lro(lower_dev);
+               netdev_unlock_ops(lower_dev);
+       }
 }
-EXPORT_SYMBOL(dev_disable_lro);
 
 /**
  *     dev_disable_gro_hw - disable HW Generic Receive Offload on a device
@@ -6038,7 +6032,7 @@ static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp)
                        static_branch_dec(&generic_xdp_needed_key);
                } else if (new && !old) {
                        static_branch_inc(&generic_xdp_needed_key);
-                       dev_disable_lro(dev);
+                       netif_disable_lro(dev);
                        dev_disable_gro_hw(dev);
                }
                break;
@@ -9210,7 +9204,7 @@ int dev_set_promiscuity(struct net_device *dev, int inc)
 }
 EXPORT_SYMBOL(dev_set_promiscuity);
 
-static int __dev_set_allmulti(struct net_device *dev, int inc, bool notify)
+int netif_set_allmulti(struct net_device *dev, int inc, bool notify)
 {
        unsigned int old_flags = dev->flags, old_gflags = dev->gflags;
        unsigned int allmulti, flags;
@@ -9245,25 +9239,6 @@ static int __dev_set_allmulti(struct net_device *dev, int inc, bool notify)
        return 0;
 }
 
-/**
- *     dev_set_allmulti        - update allmulti count on a device
- *     @dev: device
- *     @inc: modifier
- *
- *     Add or remove reception of all multicast frames to a device. While the
- *     count in the device remains above zero the interface remains listening
- *     to all interfaces. Once it hits zero the device reverts back to normal
- *     filtering operation. A negative @inc value is used to drop the counter
- *     when releasing a resource needing all multicasts.
- *     Return 0 if successful or a negative errno code on error.
- */
-
-int dev_set_allmulti(struct net_device *dev, int inc)
-{
-       return __dev_set_allmulti(dev, inc, true);
-}
-EXPORT_SYMBOL(dev_set_allmulti);
-
 /*
  *     Upload unicast and multicast address lists to device and
  *     configure RX filtering. When the device doesn't support unicast
@@ -9396,7 +9371,7 @@ int __dev_change_flags(struct net_device *dev, unsigned int flags,
                int inc = (flags & IFF_ALLMULTI) ? 1 : -1;
 
                dev->gflags ^= IFF_ALLMULTI;
-               __dev_set_allmulti(dev, inc, false);
+               netif_set_allmulti(dev, inc, false);
        }
 
        return ret;
@@ -9588,16 +9563,8 @@ int dev_pre_changeaddr_notify(struct net_device *dev, const char *addr,
 }
 EXPORT_SYMBOL(dev_pre_changeaddr_notify);
 
-/**
- *     dev_set_mac_address - Change Media Access Control Address
- *     @dev: device
- *     @sa: new address
- *     @extack: netlink extended ack
- *
- *     Change the hardware (MAC) address of the device
- */
-int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
-                       struct netlink_ext_ack *extack)
+int netif_set_mac_address(struct net_device *dev, struct sockaddr *sa,
+                         struct netlink_ext_ack *extack)
 {
        const struct net_device_ops *ops = dev->netdev_ops;
        int err;
@@ -9621,7 +9588,6 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
        add_device_randomness(dev->dev_addr, dev->addr_len);
        return 0;
 }
-EXPORT_SYMBOL(dev_set_mac_address);
 
 DECLARE_RWSEM(dev_addr_sem);
 
@@ -9631,7 +9597,7 @@ int netif_set_mac_address_user(struct net_device *dev, struct sockaddr *sa,
        int ret;
 
        down_write(&dev_addr_sem);
-       ret = dev_set_mac_address(dev, sa, extack);
+       ret = netif_set_mac_address(dev, sa, extack);
        up_write(&dev_addr_sem);
        return ret;
 }
index 059413d9ef9d8e019c648c3e209c21419e5704df..7bd667b34b808886c4bd2ddc70008ef8bfa7f3da 100644 (file)
@@ -252,3 +252,68 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
        return ret;
 }
 EXPORT_SYMBOL(dev_set_mtu);
+
+/**
+ * dev_disable_lro() - disable Large Receive Offload on a device
+ * @dev: device
+ *
+ * Disable Large Receive Offload (LRO) on a net device.  Must be
+ * called under RTNL.  This is needed if received packets may be
+ * forwarded to another interface.
+ */
+void dev_disable_lro(struct net_device *dev)
+{
+       netdev_lock_ops(dev);
+       netif_disable_lro(dev);
+       netdev_unlock_ops(dev);
+}
+EXPORT_SYMBOL(dev_disable_lro);
+
+/**
+ * dev_set_allmulti() - update allmulti count on a device
+ * @dev: device
+ * @inc: modifier
+ *
+ * Add or remove reception of all multicast frames to a device. While the
+ * count in the device remains above zero the interface remains listening
+ * to all interfaces. Once it hits zero the device reverts back to normal
+ * filtering operation. A negative @inc value is used to drop the counter
+ * when releasing a resource needing all multicasts.
+ *
+ * Return: 0 on success, -errno on failure.
+ */
+
+int dev_set_allmulti(struct net_device *dev, int inc)
+{
+       int ret;
+
+       netdev_lock_ops(dev);
+       ret = netif_set_allmulti(dev, inc, true);
+       netdev_unlock_ops(dev);
+
+       return ret;
+}
+EXPORT_SYMBOL(dev_set_allmulti);
+
+/**
+ * dev_set_mac_address() - change Media Access Control Address
+ * @dev: device
+ * @sa: new address
+ * @extack: netlink extended ack
+ *
+ * Change the hardware (MAC) address of the device
+ *
+ * Return: 0 on success, -errno on failure.
+ */
+int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
+                       struct netlink_ext_ack *extack)
+{
+       int ret;
+
+       netdev_lock_ops(dev);
+       ret = netif_set_mac_address(dev, sa, extack);
+       netdev_unlock_ops(dev);
+
+       return ret;
+}
+EXPORT_SYMBOL(dev_set_mac_address);
index 8d9dc048a548b0eeabc62e2a437fdca32a048469..27eea34d1b4162dd40265d8faa44ac023a41d674 100644 (file)
@@ -1483,8 +1483,10 @@ static ssize_t tx_maxrate_store(struct kobject *kobj, struct attribute *attr,
                return err;
 
        err = -EOPNOTSUPP;
+       netdev_lock_ops(dev);
        if (dev->netdev_ops->ndo_set_tx_maxrate)
                err = dev->netdev_ops->ndo_set_tx_maxrate(dev, index, rate);
+       netdev_unlock_ops(dev);
 
        if (!err) {
                queue->tx_maxrate = rate;