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:
Eric Dumazet 2024-02-13 06:32:36 +00:00 committed by David S. Miller
parent a6473fe9b6
commit 4d42b37def
2 changed files with 18 additions and 13 deletions

View File

@ -1815,6 +1815,15 @@ enum netdev_stat_type {
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.
*
@ -2372,13 +2381,7 @@ struct net_device {
struct list_head link_watch_list;
enum { 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 */
} reg_state:8;
u8 reg_state;
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)
{
switch (dev->reg_state) {
u8 reg_state = READ_ONCE(dev->reg_state);
switch (reg_state) {
case NETREG_UNINITIALIZED: return " (uninitialized)";
case NETREG_REGISTERED: return "";
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)";
}
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)";
}

View File

@ -10339,7 +10339,7 @@ int register_netdevice(struct net_device *dev)
ret = netdev_register_kobject(dev);
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);
if (ret)
goto err_uninit_notify;
@ -10630,7 +10630,7 @@ void netdev_run_todo(void)
}
write_lock(&dev_base_lock);
dev->reg_state = NETREG_UNREGISTERED;
WRITE_ONCE(dev->reg_state, NETREG_UNREGISTERED);
write_unlock(&dev_base_lock);
linkwatch_sync_dev(dev);
}
@ -11050,7 +11050,7 @@ void free_netdev(struct net_device *dev)
}
BUG_ON(dev->reg_state != NETREG_UNREGISTERED);
dev->reg_state = NETREG_RELEASED;
WRITE_ONCE(dev->reg_state, NETREG_RELEASED);
/* will free via device release */
put_device(&dev->dev);
@ -11140,7 +11140,7 @@ void unregister_netdevice_many_notify(struct list_head *head,
/* And unlink it from device chain. */
write_lock(&dev_base_lock);
unlist_netdevice(dev, false);
dev->reg_state = NETREG_UNREGISTERING;
WRITE_ONCE(dev->reg_state, NETREG_UNREGISTERING);
write_unlock(&dev_base_lock);
}
flush_all_backlogs();