Revert "net: replace dev_addr_sem with netdev instance lock"

This reverts commit df43d8bf10.

Cc: Kohei Enju <enjuk@amazon.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Fixes: df43d8bf10 ("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>
This commit is contained in:
Stanislav Fomichev
2025-03-12 12:05:12 -07:00
committed by Paolo Abeni
parent 756f88ff9c
commit 8033d2aef5
9 changed files with 56 additions and 41 deletions

View File

@@ -1017,7 +1017,7 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
rtnl_unlock(); rtnl_unlock();
return -ENOLINK; 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); tap_put_tap_dev(tap);
rtnl_unlock(); rtnl_unlock();
return ret; return ret;

View File

@@ -3193,7 +3193,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
case SIOCSIFHWADDR: case SIOCSIFHWADDR:
/* Set hw address */ /* 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; break;
case TUNGETSNDBUF: case TUNGETSNDBUF:

View File

@@ -2498,7 +2498,7 @@ struct net_device {
* *
* Protects: * Protects:
* @gro_flush_timeout, @napi_defer_hard_irqs, @napi_list, * @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): * Partially protects (writers must hold both @lock and rtnl_lock):
* @up * @up
@@ -4196,6 +4196,10 @@ int netif_set_mac_address(struct net_device *dev, struct sockaddr *sa,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa, int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
struct netlink_ext_ack *extack); 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_mac_address(struct sockaddr *sa, struct net *net, char *dev_name);
int dev_get_port_parent_id(struct net_device *dev, int dev_get_port_parent_id(struct net_device *dev,
struct netdev_phys_item_id *ppid, bool recurse); struct netdev_phys_item_id *ppid, bool recurse);

View File

@@ -1059,28 +1059,6 @@ struct net_device *netdev_get_by_index_lock(struct net *net, int ifindex)
return __netdev_put_lock(dev); 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 * struct net_device *
netdev_xa_find_lock(struct net *net, struct net_device *dev, netdev_xa_find_lock(struct net *net, struct net_device *dev,
unsigned long *index) unsigned long *index)
@@ -9597,24 +9575,44 @@ int netif_set_mac_address(struct net_device *dev, struct sockaddr *sa,
return 0; 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) int dev_get_mac_address(struct sockaddr *sa, struct net *net, char *dev_name)
{ {
size_t size = sizeof(sa->sa_data_min); size_t size = sizeof(sa->sa_data_min);
struct net_device *dev; struct net_device *dev;
int ret = 0;
dev = netdev_get_by_name_lock(net, dev_name); down_read(&dev_addr_sem);
if (!dev) rcu_read_lock();
return -ENODEV;
dev = dev_get_by_name_rcu(net, dev_name);
if (!dev) {
ret = -ENODEV;
goto unlock;
}
if (!dev->addr_len) if (!dev->addr_len)
memset(sa->sa_data, 0, size); memset(sa->sa_data, 0, size);
else else
memcpy(sa->sa_data, dev->dev_addr, memcpy(sa->sa_data, dev->dev_addr,
min_t(size_t, size, dev->addr_len)); min_t(size_t, size, dev->addr_len));
sa->sa_family = dev->type; 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); EXPORT_SYMBOL(dev_get_mac_address);

View 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 *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_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_put_lock(struct net_device *dev);
struct net_device * struct net_device *
netdev_xa_find_lock(struct net *net, struct net_device *dev, 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_rx_bias;
extern int dev_weight_tx_bias; extern int dev_weight_tx_bias;
extern struct rw_semaphore dev_addr_sem;
/* rtnl helpers */ /* rtnl helpers */
extern struct list_head net_todo_list; extern struct list_head net_todo_list;
void netdev_run_todo(void); void netdev_run_todo(void);

View File

@@ -84,6 +84,19 @@ void dev_set_group(struct net_device *dev, int new_group)
netdev_unlock_ops(dev); 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_change_net_namespace() - move device to different nethost namespace
* @dev: device * @dev: device
@@ -299,9 +312,9 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa,
{ {
int ret; int ret;
netdev_lock(dev); netdev_lock_ops(dev);
ret = netif_set_mac_address(dev, sa, extack); ret = netif_set_mac_address(dev, sa, extack);
netdev_unlock(dev); netdev_unlock_ops(dev);
return ret; return ret;
} }

View File

@@ -575,7 +575,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data,
case SIOCSIFHWADDR: case SIOCSIFHWADDR:
if (dev->addr_len > sizeof(struct sockaddr)) if (dev->addr_len > sizeof(struct sockaddr))
return -EINVAL; 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: case SIOCSIFHWBROADCAST:
if (ifr->ifr_hwaddr.sa_family != dev->type) if (ifr->ifr_hwaddr.sa_family != dev->type)

View 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); struct net_device *ndev = to_net_dev(dev);
ssize_t ret = -EINVAL; ssize_t ret = -EINVAL;
netdev_lock(ndev); down_read(&dev_addr_sem);
rcu_read_lock();
if (dev_isalive(ndev)) if (dev_isalive(ndev))
ret = sysfs_format_mac(buf, ndev->dev_addr, ndev->addr_len); ret = sysfs_format_mac(buf, ndev->dev_addr, ndev->addr_len);
netdev_unlock(ndev); rcu_read_unlock();
up_read(&dev_addr_sem);
return ret; return ret;
} }
static DEVICE_ATTR_RO(address); static DEVICE_ATTR_RO(address);

View File

@@ -3090,11 +3090,7 @@ static int do_setlink(const struct sk_buff *skb, struct net_device *dev,
sa->sa_family = dev->type; sa->sa_family = dev->type;
memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]), memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
dev->addr_len); dev->addr_len);
if (!netdev_need_ops_lock(dev)) err = netif_set_mac_address_user(dev, sa, extack);
netdev_lock(dev);
err = netif_set_mac_address(dev, sa, extack);
if (!netdev_need_ops_lock(dev))
netdev_unlock(dev);
kfree(sa); kfree(sa);
if (err) if (err)
goto errout; goto errout;