mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	net: hold netdev instance lock during sysfs operations
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>
This commit is contained in:
		
							parent
							
								
									ffb7ed19ac
								
							
						
					
					
						commit
						ad7c7b2172
					
				
					 5 changed files with 88 additions and 48 deletions
				
			
		| 
						 | 
					@ -2644,10 +2644,13 @@ static int __bond_release_one(struct net_device *bond_dev,
 | 
				
			||||||
		dev_set_mac_address(slave_dev, (struct sockaddr *)&ss, NULL);
 | 
							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);
 | 
							__dev_set_mtu(slave_dev, slave->original_mtu);
 | 
				
			||||||
	else
 | 
							netdev_unlock_ops(slave_dev);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		dev_set_mtu(slave_dev, slave->original_mtu);
 | 
							dev_set_mtu(slave_dev, slave->original_mtu);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!netif_is_bond_master(slave_dev))
 | 
						if (!netif_is_bond_master(slave_dev))
 | 
				
			||||||
		slave_dev->priv_flags &= ~IFF_BONDING;
 | 
							slave_dev->priv_flags &= ~IFF_BONDING;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3382,6 +3382,7 @@ void dev_close(struct net_device *dev);
 | 
				
			||||||
void dev_close_many(struct list_head *head, bool unlink);
 | 
					void dev_close_many(struct list_head *head, bool unlink);
 | 
				
			||||||
int dev_setup_tc(struct net_device *dev, enum tc_setup_type type,
 | 
					int dev_setup_tc(struct net_device *dev, enum tc_setup_type type,
 | 
				
			||||||
		 void *type_data);
 | 
							 void *type_data);
 | 
				
			||||||
 | 
					void netif_disable_lro(struct net_device *dev);
 | 
				
			||||||
void dev_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);
 | 
					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,
 | 
					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_set_mtu(struct net_device *, int);
 | 
				
			||||||
int dev_pre_changeaddr_notify(struct net_device *dev, const char *addr,
 | 
					int dev_pre_changeaddr_notify(struct net_device *dev, const char *addr,
 | 
				
			||||||
			      struct netlink_ext_ack *extack);
 | 
								      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,
 | 
					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,
 | 
					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 */
 | 
					/* Functions used for secondary unicast and multicast support */
 | 
				
			||||||
void dev_set_rx_mode(struct net_device *dev);
 | 
					void dev_set_rx_mode(struct net_device *dev);
 | 
				
			||||||
int dev_set_promiscuity(struct net_device *dev, int inc);
 | 
					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);
 | 
					int dev_set_allmulti(struct net_device *dev, int inc);
 | 
				
			||||||
void netdev_state_change(struct net_device *dev);
 | 
					void netdev_state_change(struct net_device *dev);
 | 
				
			||||||
void __netdev_notify_peers(struct net_device *dev);
 | 
					void __netdev_notify_peers(struct net_device *dev);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1757,15 +1757,7 @@ int dev_setup_tc(struct net_device *dev, enum tc_setup_type type,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(dev_setup_tc);
 | 
					EXPORT_SYMBOL(dev_setup_tc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					void netif_disable_lro(struct net_device *dev)
 | 
				
			||||||
 *	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)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_device *lower_dev;
 | 
						struct net_device *lower_dev;
 | 
				
			||||||
	struct list_head *iter;
 | 
						struct list_head *iter;
 | 
				
			||||||
| 
						 | 
					@ -1776,10 +1768,12 @@ void dev_disable_lro(struct net_device *dev)
 | 
				
			||||||
	if (unlikely(dev->features & NETIF_F_LRO))
 | 
						if (unlikely(dev->features & NETIF_F_LRO))
 | 
				
			||||||
		netdev_WARN(dev, "failed to disable LRO!\n");
 | 
							netdev_WARN(dev, "failed to disable LRO!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netdev_for_each_lower_dev(dev, lower_dev, iter)
 | 
						netdev_for_each_lower_dev(dev, lower_dev, iter) {
 | 
				
			||||||
		dev_disable_lro(lower_dev);
 | 
							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
 | 
					 *	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);
 | 
								static_branch_dec(&generic_xdp_needed_key);
 | 
				
			||||||
		} else if (new && !old) {
 | 
							} else if (new && !old) {
 | 
				
			||||||
			static_branch_inc(&generic_xdp_needed_key);
 | 
								static_branch_inc(&generic_xdp_needed_key);
 | 
				
			||||||
			dev_disable_lro(dev);
 | 
								netif_disable_lro(dev);
 | 
				
			||||||
			dev_disable_gro_hw(dev);
 | 
								dev_disable_gro_hw(dev);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -9210,7 +9204,7 @@ int dev_set_promiscuity(struct net_device *dev, int inc)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(dev_set_promiscuity);
 | 
					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 old_flags = dev->flags, old_gflags = dev->gflags;
 | 
				
			||||||
	unsigned int allmulti, flags;
 | 
						unsigned int allmulti, flags;
 | 
				
			||||||
| 
						 | 
					@ -9245,25 +9239,6 @@ static int __dev_set_allmulti(struct net_device *dev, int inc, bool notify)
 | 
				
			||||||
	return 0;
 | 
						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
 | 
					 *	Upload unicast and multicast address lists to device and
 | 
				
			||||||
 *	configure RX filtering. When the device doesn't support unicast
 | 
					 *	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;
 | 
							int inc = (flags & IFF_ALLMULTI) ? 1 : -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dev->gflags ^= IFF_ALLMULTI;
 | 
							dev->gflags ^= IFF_ALLMULTI;
 | 
				
			||||||
		__dev_set_allmulti(dev, inc, false);
 | 
							netif_set_allmulti(dev, inc, false);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
| 
						 | 
					@ -9588,15 +9563,7 @@ int dev_pre_changeaddr_notify(struct net_device *dev, const char *addr,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(dev_pre_changeaddr_notify);
 | 
					EXPORT_SYMBOL(dev_pre_changeaddr_notify);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					int netif_set_mac_address(struct net_device *dev, struct sockaddr *sa,
 | 
				
			||||||
 *	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)
 | 
								  struct netlink_ext_ack *extack)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct net_device_ops *ops = dev->netdev_ops;
 | 
						const struct net_device_ops *ops = dev->netdev_ops;
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
						add_device_randomness(dev->dev_addr, dev->addr_len);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(dev_set_mac_address);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
DECLARE_RWSEM(dev_addr_sem);
 | 
					DECLARE_RWSEM(dev_addr_sem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9631,7 +9597,7 @@ int netif_set_mac_address_user(struct net_device *dev, struct sockaddr *sa,
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	down_write(&dev_addr_sem);
 | 
						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);
 | 
						up_write(&dev_addr_sem);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -252,3 +252,68 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(dev_set_mtu);
 | 
					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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1483,8 +1483,10 @@ static ssize_t tx_maxrate_store(struct kobject *kobj, struct attribute *attr,
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = -EOPNOTSUPP;
 | 
						err = -EOPNOTSUPP;
 | 
				
			||||||
 | 
						netdev_lock_ops(dev);
 | 
				
			||||||
	if (dev->netdev_ops->ndo_set_tx_maxrate)
 | 
						if (dev->netdev_ops->ndo_set_tx_maxrate)
 | 
				
			||||||
		err = dev->netdev_ops->ndo_set_tx_maxrate(dev, index, rate);
 | 
							err = dev->netdev_ops->ndo_set_tx_maxrate(dev, index, rate);
 | 
				
			||||||
 | 
						netdev_unlock_ops(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!err) {
 | 
						if (!err) {
 | 
				
			||||||
		queue->tx_maxrate = rate;
 | 
							queue->tx_maxrate = rate;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue