forked from mirrors/linux
		
	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,16 +9563,8 @@ 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 | 			  struct netlink_ext_ack *extack) | ||||||
|  *	@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) |  | ||||||
| { | { | ||||||
| 	const struct net_device_ops *ops = dev->netdev_ops; | 	const struct net_device_ops *ops = dev->netdev_ops; | ||||||
| 	int err; | 	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); | 	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
	
	 Stanislav Fomichev
						Stanislav Fomichev