summaryrefslogtreecommitdiff
path: root/net/core/rtnetlink.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2024-02-13 09:32:42 +0300
committerDavid S. Miller <davem@davemloft.net>2024-02-14 14:20:13 +0300
commit6a2968ee1ee2cc6fce30f6f5724442b34b1483b3 (patch)
tree0a41642980c841e40bbcd58ce7b4b1612362aeac /net/core/rtnetlink.c
parent328771deab16fcac55763309bb59e28b1c050853 (diff)
downloadlinux-6a2968ee1ee2cc6fce30f6f5724442b34b1483b3.tar.xz
net: add netdev_set_operstate() helper
dev_base_lock is going away, add netdev_set_operstate() helper so that hsr does not have to know core internals. Remove dev_base_lock acquisition from rfc2863_policy() v3: use an "unsigned int" for dev->operstate, so that try_cmpxchg() can work on all arches. ( https://lore.kernel.org/oe-kbuild-all/202402081918.OLyGaea3-lkp@intel.com/ ) Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r--net/core/rtnetlink.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 43d92de8601c..e484ba44f23b 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -842,9 +842,22 @@ int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id,
}
EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo);
+void netdev_set_operstate(struct net_device *dev, int newstate)
+{
+ unsigned int old = READ_ONCE(dev->operstate);
+
+ do {
+ if (old == newstate)
+ return;
+ } while (!try_cmpxchg(&dev->operstate, &old, newstate));
+
+ netdev_state_change(dev);
+}
+EXPORT_SYMBOL(netdev_set_operstate);
+
static void set_operstate(struct net_device *dev, unsigned char transition)
{
- unsigned char operstate = dev->operstate;
+ unsigned char operstate = READ_ONCE(dev->operstate);
switch (transition) {
case IF_OPER_UP:
@@ -866,12 +879,7 @@ static void set_operstate(struct net_device *dev, unsigned char transition)
break;
}
- if (READ_ONCE(dev->operstate) != operstate) {
- write_lock(&dev_base_lock);
- WRITE_ONCE(dev->operstate, operstate);
- write_unlock(&dev_base_lock);
- netdev_state_change(dev);
- }
+ netdev_set_operstate(dev, operstate);
}
static unsigned int rtnl_dev_get_flags(const struct net_device *dev)