summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorStanislav Fomichev <sdf@fomichev.me>2025-03-12 12:05:12 -0700
committerPaolo Abeni <pabeni@redhat.com>2025-03-19 18:52:00 +0100
commit8033d2aef51722fe74068b52553625ed91ea256c (patch)
tree6910b7f09c5c94632c251b1564cb17f9330682a9 /net
parent756f88ff9c6ae3d059180813102610c39ea99c27 (diff)
Revert "net: replace dev_addr_sem with netdev instance lock"
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>
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c52
-rw-r--r--net/core/dev.h3
-rw-r--r--net/core/dev_api.c17
-rw-r--r--net/core/dev_ioctl.c2
-rw-r--r--net/core/net-sysfs.c7
-rw-r--r--net/core/rtnetlink.c6
6 files changed, 49 insertions, 38 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 6fa6ed5b5798..977a9946d39c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -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);
diff --git a/net/core/dev.h b/net/core/dev.h
index 0ddd3631acb0..7ee203395d8e 100644
--- a/net/core/dev.h
+++ b/net/core/dev.h
@@ -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);
diff --git a/net/core/dev_api.c b/net/core/dev_api.c
index 1f0e24849bc6..2e17548af685 100644
--- a/net/core/dev_api.c
+++ b/net/core/dev_api.c
@@ -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;
}
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
index 5471cf4fc984..eb8b41ec5523 100644
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -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)
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 529a0f721268..abaa1c919b98 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -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);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 90597bf84e3d..9355058bf996 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -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;