]> www.infradead.org Git - users/hch/misc.git/commitdiff
Revert "net: replace dev_addr_sem with netdev instance lock"
authorStanislav Fomichev <sdf@fomichev.me>
Wed, 12 Mar 2025 19:05:12 +0000 (12:05 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Wed, 19 Mar 2025 17:52:00 +0000 (18:52 +0100)
This reverts commit df43d8bf10316a7c3b1e47e3cc0057a54df4a5b8.

Cc: Kohei Enju <enjuk@amazon.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Fixes: df43d8bf1031 ("net: replace dev_addr_sem with netdev instance lock")
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250312190513.1252045-2-sdf@fomichev.me
Tested-by: Lei Yang <leiyang@redhat.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/tap.c
drivers/net/tun.c
include/linux/netdevice.h
net/core/dev.c
net/core/dev.h
net/core/dev_api.c
net/core/dev_ioctl.c
net/core/net-sysfs.c
net/core/rtnetlink.c

index 4382f5e323b065f239227926e2aa66237d793ddf..d4ece538f1b23789ca60caa6232690e4d0a4d14a 100644 (file)
@@ -1017,7 +1017,7 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
                        rtnl_unlock();
                        return -ENOLINK;
                }
-               ret = dev_set_mac_address(tap->dev, &sa, NULL);
+               ret = dev_set_mac_address_user(tap->dev, &sa, NULL);
                tap_put_tap_dev(tap);
                rtnl_unlock();
                return ret;
index 55b60cb68d00f1d12f683829c862d3bdbbd2341d..f75f912a0225ffd559a7a7ebb6a8fcc1cc1f81fa 100644 (file)
@@ -3193,7 +3193,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 
        case SIOCSIFHWADDR:
                /* Set hw address */
-               ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr, NULL);
+               ret = dev_set_mac_address_user(tun->dev, &ifr.ifr_hwaddr, NULL);
                break;
 
        case TUNGETSNDBUF:
index 67527243459b358ef16610c597bf3606af2ca020..0db9fc0afe3605a0b7e92cef2b5330615ee1e7fd 100644 (file)
@@ -2498,7 +2498,7 @@ struct net_device {
         *
         * Protects:
         *      @gro_flush_timeout, @napi_defer_hard_irqs, @napi_list,
-        *      @net_shaper_hierarchy, @reg_state, @threaded, @dev_addr
+        *      @net_shaper_hierarchy, @reg_state, @threaded
         *
         * Partially protects (writers must hold both @lock and rtnl_lock):
         *      @up
@@ -4196,6 +4196,10 @@ 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,
+                              struct netlink_ext_ack *extack);
+int dev_set_mac_address_user(struct net_device *dev, struct sockaddr *sa,
+                            struct netlink_ext_ack *extack);
 int dev_get_mac_address(struct sockaddr *sa, struct net *net, char *dev_name);
 int dev_get_port_parent_id(struct net_device *dev,
                           struct netdev_phys_item_id *ppid, bool recurse);
index 6fa6ed5b57987f1c3e02c7fa128755cca5eed566..977a9946d39c5af5617b7adb1c9551fd5dd051ed 100644 (file)
@@ -1059,28 +1059,6 @@ struct net_device *netdev_get_by_index_lock(struct net *net, int ifindex)
        return __netdev_put_lock(dev);
 }
 
-/**
- * netdev_get_by_name_lock() - find a device by its name
- * @net: the applicable net namespace
- * @name: name of device
- *
- * Search for an interface by name. If a valid device
- * with @name is found it will be returned with netdev->lock held.
- * netdev_unlock() must be called to release it.
- *
- * Return: pointer to a device with lock held, NULL if not found.
- */
-struct net_device *netdev_get_by_name_lock(struct net *net, const char *name)
-{
-       struct net_device *dev;
-
-       dev = dev_get_by_name(net, name);
-       if (!dev)
-               return NULL;
-
-       return __netdev_put_lock(dev);
-}
-
 struct net_device *
 netdev_xa_find_lock(struct net *net, struct net_device *dev,
                    unsigned long *index)
@@ -9597,24 +9575,44 @@ int netif_set_mac_address(struct net_device *dev, struct sockaddr *sa,
        return 0;
 }
 
+DECLARE_RWSEM(dev_addr_sem);
+
+int netif_set_mac_address_user(struct net_device *dev, struct sockaddr *sa,
+                              struct netlink_ext_ack *extack)
+{
+       int ret;
+
+       down_write(&dev_addr_sem);
+       ret = netif_set_mac_address(dev, sa, extack);
+       up_write(&dev_addr_sem);
+       return ret;
+}
+
 int dev_get_mac_address(struct sockaddr *sa, struct net *net, char *dev_name)
 {
        size_t size = sizeof(sa->sa_data_min);
        struct net_device *dev;
+       int ret = 0;
 
-       dev = netdev_get_by_name_lock(net, dev_name);
-       if (!dev)
-               return -ENODEV;
+       down_read(&dev_addr_sem);
+       rcu_read_lock();
 
+       dev = dev_get_by_name_rcu(net, dev_name);
+       if (!dev) {
+               ret = -ENODEV;
+               goto unlock;
+       }
        if (!dev->addr_len)
                memset(sa->sa_data, 0, size);
        else
                memcpy(sa->sa_data, dev->dev_addr,
                       min_t(size_t, size, dev->addr_len));
        sa->sa_family = dev->type;
-       netdev_unlock(dev);
 
-       return 0;
+unlock:
+       rcu_read_unlock();
+       up_read(&dev_addr_sem);
+       return ret;
 }
 EXPORT_SYMBOL(dev_get_mac_address);
 
index 0ddd3631acb01667831042c86e736d826264ccf4..7ee203395d8e267b0542532b63243e6d3dda6a66 100644 (file)
@@ -29,7 +29,6 @@ netdev_napi_by_id_lock(struct net *net, unsigned int napi_id);
 struct net_device *dev_get_by_napi_id(unsigned int napi_id);
 
 struct net_device *netdev_get_by_index_lock(struct net *net, int ifindex);
-struct net_device *netdev_get_by_name_lock(struct net *net, const char *name);
 struct net_device *__netdev_put_lock(struct net_device *dev);
 struct net_device *
 netdev_xa_find_lock(struct net *net, struct net_device *dev,
@@ -71,6 +70,8 @@ extern int            weight_p;
 extern int             dev_weight_rx_bias;
 extern int             dev_weight_tx_bias;
 
+extern struct rw_semaphore dev_addr_sem;
+
 /* rtnl helpers */
 extern struct list_head net_todo_list;
 void netdev_run_todo(void);
index 1f0e24849bc65f253c389ff4e553b01d235d4267..2e17548af685a48f81f79e8357a9dd17a86d8f25 100644 (file)
@@ -84,6 +84,19 @@ void dev_set_group(struct net_device *dev, int new_group)
        netdev_unlock_ops(dev);
 }
 
+int dev_set_mac_address_user(struct net_device *dev, struct sockaddr *sa,
+                            struct netlink_ext_ack *extack)
+{
+       int ret;
+
+       netdev_lock_ops(dev);
+       ret = netif_set_mac_address_user(dev, sa, extack);
+       netdev_unlock_ops(dev);
+
+       return ret;
+}
+EXPORT_SYMBOL(dev_set_mac_address_user);
+
 /**
  * dev_change_net_namespace() - move device to different nethost namespace
  * @dev: device
@@ -299,9 +312,9 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
 {
        int ret;
 
-       netdev_lock(dev);
+       netdev_lock_ops(dev);
        ret = netif_set_mac_address(dev, sa, extack);
-       netdev_unlock(dev);
+       netdev_unlock_ops(dev);
 
        return ret;
 }
index 5471cf4fc98493923df56b2f5c579c79d9ccd7bc..eb8b41ec5523cb487a7df89f4e560915f2342983 100644 (file)
@@ -575,7 +575,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data,
        case SIOCSIFHWADDR:
                if (dev->addr_len > sizeof(struct sockaddr))
                        return -EINVAL;
-               return dev_set_mac_address(dev, &ifr->ifr_hwaddr, NULL);
+               return dev_set_mac_address_user(dev, &ifr->ifr_hwaddr, NULL);
 
        case SIOCSIFHWBROADCAST:
                if (ifr->ifr_hwaddr.sa_family != dev->type)
index 529a0f721268209c8d8740af2c2607321e6ff7af..abaa1c919b984cb3340e99bf1af26864a0cc3405 100644 (file)
@@ -263,11 +263,14 @@ static ssize_t address_show(struct device *dev, struct device_attribute *attr,
        struct net_device *ndev = to_net_dev(dev);
        ssize_t ret = -EINVAL;
 
-       netdev_lock(ndev);
+       down_read(&dev_addr_sem);
+
+       rcu_read_lock();
        if (dev_isalive(ndev))
                ret = sysfs_format_mac(buf, ndev->dev_addr, ndev->addr_len);
-       netdev_unlock(ndev);
+       rcu_read_unlock();
 
+       up_read(&dev_addr_sem);
        return ret;
 }
 static DEVICE_ATTR_RO(address);
index 90597bf84e3d395bed3bea5778b68ede017e3dff..9355058bf996978b17a6c81eff1d9f47f1a8b368 100644 (file)
@@ -3090,11 +3090,7 @@ static int do_setlink(const struct sk_buff *skb, struct net_device *dev,
                sa->sa_family = dev->type;
                memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
                       dev->addr_len);
-               if (!netdev_need_ops_lock(dev))
-                       netdev_lock(dev);
-               err = netif_set_mac_address(dev, sa, extack);
-               if (!netdev_need_ops_lock(dev))
-                       netdev_unlock(dev);
+               err = netif_set_mac_address_user(dev, sa, extack);
                kfree(sa);
                if (err)
                        goto errout;