net: convert dev->reg_state to u8
authorEric Dumazet <edumazet@google.com>
Tue, 13 Feb 2024 06:32:36 +0000 (06:32 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 14 Feb 2024 11:20:13 +0000 (11:20 +0000)
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>
include/linux/netdevice.h
net/core/dev.c

index a3f9c95da51eec9a02d01ba2e1d7dc380eb08ffe..6311246551072ba08f1f7f2f5afd79d34d3d7b8e 100644 (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)";
 }
 
index 720bd68382129140c8257795e4d14503990edffe..9c95cae9d6ab966c3ad8474921f7acb148a90866 100644 (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();