forked from mirrors/linux
		
	net: convert dev->reg_state to u8
Prepares things so that dev->reg_state reads can be lockless, by adding WRITE_ONCE() on write side. READ_ONCE()/WRITE_ONCE() do not support bitfields. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									a6473fe9b6
								
							
						
					
					
						commit
						4d42b37def
					
				
					 2 changed files with 18 additions and 13 deletions
				
			
		|  | @ -1815,6 +1815,15 @@ enum netdev_stat_type { | ||||||
| 	NETDEV_PCPU_STAT_DSTATS, /* struct pcpu_dstats */ | 	NETDEV_PCPU_STAT_DSTATS, /* struct pcpu_dstats */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | enum netdev_reg_state { | ||||||
|  | 	NETREG_UNINITIALIZED = 0, | ||||||
|  | 	NETREG_REGISTERED,	/* completed register_netdevice */ | ||||||
|  | 	NETREG_UNREGISTERING,	/* called unregister_netdevice */ | ||||||
|  | 	NETREG_UNREGISTERED,	/* completed unregister todo */ | ||||||
|  | 	NETREG_RELEASED,	/* called free_netdev */ | ||||||
|  | 	NETREG_DUMMY,		/* dummy device for NAPI poll */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  *	struct net_device - The DEVICE structure. |  *	struct net_device - The DEVICE structure. | ||||||
|  * |  * | ||||||
|  | @ -2372,13 +2381,7 @@ struct net_device { | ||||||
| 
 | 
 | ||||||
| 	struct list_head	link_watch_list; | 	struct list_head	link_watch_list; | ||||||
| 
 | 
 | ||||||
| 	enum { NETREG_UNINITIALIZED=0, | 	u8 reg_state; | ||||||
| 	       NETREG_REGISTERED,	/* completed register_netdevice */ |  | ||||||
| 	       NETREG_UNREGISTERING,	/* called unregister_netdevice */ |  | ||||||
| 	       NETREG_UNREGISTERED,	/* completed unregister todo */ |  | ||||||
| 	       NETREG_RELEASED,		/* called free_netdev */ |  | ||||||
| 	       NETREG_DUMMY,		/* dummy device for NAPI poll */ |  | ||||||
| 	} reg_state:8; |  | ||||||
| 
 | 
 | ||||||
| 	bool dismantle; | 	bool dismantle; | ||||||
| 
 | 
 | ||||||
|  | @ -5254,7 +5257,9 @@ static inline const char *netdev_name(const struct net_device *dev) | ||||||
| 
 | 
 | ||||||
| static inline const char *netdev_reg_state(const struct net_device *dev) | static inline const char *netdev_reg_state(const struct net_device *dev) | ||||||
| { | { | ||||||
| 	switch (dev->reg_state) { | 	u8 reg_state = READ_ONCE(dev->reg_state); | ||||||
|  | 
 | ||||||
|  | 	switch (reg_state) { | ||||||
| 	case NETREG_UNINITIALIZED: return " (uninitialized)"; | 	case NETREG_UNINITIALIZED: return " (uninitialized)"; | ||||||
| 	case NETREG_REGISTERED: return ""; | 	case NETREG_REGISTERED: return ""; | ||||||
| 	case NETREG_UNREGISTERING: return " (unregistering)"; | 	case NETREG_UNREGISTERING: return " (unregistering)"; | ||||||
|  | @ -5263,7 +5268,7 @@ static inline const char *netdev_reg_state(const struct net_device *dev) | ||||||
| 	case NETREG_DUMMY: return " (dummy)"; | 	case NETREG_DUMMY: return " (dummy)"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	WARN_ONCE(1, "%s: unknown reg_state %d\n", dev->name, dev->reg_state); | 	WARN_ONCE(1, "%s: unknown reg_state %d\n", dev->name, reg_state); | ||||||
| 	return " (unknown)"; | 	return " (unknown)"; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10339,7 +10339,7 @@ int register_netdevice(struct net_device *dev) | ||||||
| 
 | 
 | ||||||
| 	ret = netdev_register_kobject(dev); | 	ret = netdev_register_kobject(dev); | ||||||
| 	write_lock(&dev_base_lock); | 	write_lock(&dev_base_lock); | ||||||
| 	dev->reg_state = ret ? NETREG_UNREGISTERED : NETREG_REGISTERED; | 	WRITE_ONCE(dev->reg_state, ret ? NETREG_UNREGISTERED : NETREG_REGISTERED); | ||||||
| 	write_unlock(&dev_base_lock); | 	write_unlock(&dev_base_lock); | ||||||
| 	if (ret) | 	if (ret) | ||||||
| 		goto err_uninit_notify; | 		goto err_uninit_notify; | ||||||
|  | @ -10630,7 +10630,7 @@ void netdev_run_todo(void) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		write_lock(&dev_base_lock); | 		write_lock(&dev_base_lock); | ||||||
| 		dev->reg_state = NETREG_UNREGISTERED; | 		WRITE_ONCE(dev->reg_state, NETREG_UNREGISTERED); | ||||||
| 		write_unlock(&dev_base_lock); | 		write_unlock(&dev_base_lock); | ||||||
| 		linkwatch_sync_dev(dev); | 		linkwatch_sync_dev(dev); | ||||||
| 	} | 	} | ||||||
|  | @ -11050,7 +11050,7 @@ void free_netdev(struct net_device *dev) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	BUG_ON(dev->reg_state != NETREG_UNREGISTERED); | 	BUG_ON(dev->reg_state != NETREG_UNREGISTERED); | ||||||
| 	dev->reg_state = NETREG_RELEASED; | 	WRITE_ONCE(dev->reg_state, NETREG_RELEASED); | ||||||
| 
 | 
 | ||||||
| 	/* will free via device release */ | 	/* will free via device release */ | ||||||
| 	put_device(&dev->dev); | 	put_device(&dev->dev); | ||||||
|  | @ -11140,7 +11140,7 @@ void unregister_netdevice_many_notify(struct list_head *head, | ||||||
| 		/* And unlink it from device chain. */ | 		/* And unlink it from device chain. */ | ||||||
| 		write_lock(&dev_base_lock); | 		write_lock(&dev_base_lock); | ||||||
| 		unlist_netdevice(dev, false); | 		unlist_netdevice(dev, false); | ||||||
| 		dev->reg_state = NETREG_UNREGISTERING; | 		WRITE_ONCE(dev->reg_state, NETREG_UNREGISTERING); | ||||||
| 		write_unlock(&dev_base_lock); | 		write_unlock(&dev_base_lock); | ||||||
| 	} | 	} | ||||||
| 	flush_all_backlogs(); | 	flush_all_backlogs(); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Eric Dumazet
						Eric Dumazet