Commit 004d1383 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

net-sysfs: convert dev->operstate reads to lockless ones

operstate_show() can omit dev_base_lock acquisition only
to read dev->operstate.

Annotate accesses to dev->operstate.

Writers still acquire dev_base_lock for mutual exclusion.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c7d52737
...@@ -455,7 +455,8 @@ static int br_fill_ifinfo(struct sk_buff *skb, ...@@ -455,7 +455,8 @@ static int br_fill_ifinfo(struct sk_buff *skb,
u32 filter_mask, const struct net_device *dev, u32 filter_mask, const struct net_device *dev,
bool getlink) bool getlink)
{ {
u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN; u8 operstate = netif_running(dev) ? READ_ONCE(dev->operstate) :
IF_OPER_DOWN;
struct nlattr *af = NULL; struct nlattr *af = NULL;
struct net_bridge *br; struct net_bridge *br;
struct ifinfomsg *hdr; struct ifinfomsg *hdr;
......
...@@ -67,7 +67,7 @@ static void rfc2863_policy(struct net_device *dev) ...@@ -67,7 +67,7 @@ static void rfc2863_policy(struct net_device *dev)
{ {
unsigned char operstate = default_operstate(dev); unsigned char operstate = default_operstate(dev);
if (operstate == dev->operstate) if (operstate == READ_ONCE(dev->operstate))
return; return;
write_lock(&dev_base_lock); write_lock(&dev_base_lock);
...@@ -87,7 +87,7 @@ static void rfc2863_policy(struct net_device *dev) ...@@ -87,7 +87,7 @@ static void rfc2863_policy(struct net_device *dev)
break; break;
} }
dev->operstate = operstate; WRITE_ONCE(dev->operstate, operstate);
write_unlock(&dev_base_lock); write_unlock(&dev_base_lock);
} }
......
...@@ -325,11 +325,9 @@ static ssize_t operstate_show(struct device *dev, ...@@ -325,11 +325,9 @@ static ssize_t operstate_show(struct device *dev,
const struct net_device *netdev = to_net_dev(dev); const struct net_device *netdev = to_net_dev(dev);
unsigned char operstate; unsigned char operstate;
read_lock(&dev_base_lock); operstate = READ_ONCE(netdev->operstate);
operstate = netdev->operstate;
if (!netif_running(netdev)) if (!netif_running(netdev))
operstate = IF_OPER_DOWN; operstate = IF_OPER_DOWN;
read_unlock(&dev_base_lock);
if (operstate >= ARRAY_SIZE(operstates)) if (operstate >= ARRAY_SIZE(operstates))
return -EINVAL; /* should not happen */ return -EINVAL; /* should not happen */
......
...@@ -866,9 +866,9 @@ static void set_operstate(struct net_device *dev, unsigned char transition) ...@@ -866,9 +866,9 @@ static void set_operstate(struct net_device *dev, unsigned char transition)
break; break;
} }
if (dev->operstate != operstate) { if (READ_ONCE(dev->operstate) != operstate) {
write_lock(&dev_base_lock); write_lock(&dev_base_lock);
dev->operstate = operstate; WRITE_ONCE(dev->operstate, operstate);
write_unlock(&dev_base_lock); write_unlock(&dev_base_lock);
netdev_state_change(dev); netdev_state_change(dev);
} }
......
...@@ -31,8 +31,8 @@ static bool is_slave_up(struct net_device *dev) ...@@ -31,8 +31,8 @@ static bool is_slave_up(struct net_device *dev)
static void __hsr_set_operstate(struct net_device *dev, int transition) static void __hsr_set_operstate(struct net_device *dev, int transition)
{ {
write_lock(&dev_base_lock); write_lock(&dev_base_lock);
if (dev->operstate != transition) { if (READ_ONCE(dev->operstate) != transition) {
dev->operstate = transition; WRITE_ONCE(dev->operstate, transition);
write_unlock(&dev_base_lock); write_unlock(&dev_base_lock);
netdev_state_change(dev); netdev_state_change(dev);
} else { } else {
...@@ -78,14 +78,14 @@ static void hsr_check_announce(struct net_device *hsr_dev, ...@@ -78,14 +78,14 @@ static void hsr_check_announce(struct net_device *hsr_dev,
hsr = netdev_priv(hsr_dev); hsr = netdev_priv(hsr_dev);
if (hsr_dev->operstate == IF_OPER_UP && old_operstate != IF_OPER_UP) { if (READ_ONCE(hsr_dev->operstate) == IF_OPER_UP && old_operstate != IF_OPER_UP) {
/* Went up */ /* Went up */
hsr->announce_count = 0; hsr->announce_count = 0;
mod_timer(&hsr->announce_timer, mod_timer(&hsr->announce_timer,
jiffies + msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL)); jiffies + msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL));
} }
if (hsr_dev->operstate != IF_OPER_UP && old_operstate == IF_OPER_UP) if (READ_ONCE(hsr_dev->operstate) != IF_OPER_UP && old_operstate == IF_OPER_UP)
/* Went down */ /* Went down */
del_timer(&hsr->announce_timer); del_timer(&hsr->announce_timer);
} }
...@@ -100,7 +100,7 @@ void hsr_check_carrier_and_operstate(struct hsr_priv *hsr) ...@@ -100,7 +100,7 @@ void hsr_check_carrier_and_operstate(struct hsr_priv *hsr)
/* netif_stacked_transfer_operstate() cannot be used here since /* netif_stacked_transfer_operstate() cannot be used here since
* it doesn't set IF_OPER_LOWERLAYERDOWN (?) * it doesn't set IF_OPER_LOWERLAYERDOWN (?)
*/ */
old_operstate = master->dev->operstate; old_operstate = READ_ONCE(master->dev->operstate);
has_carrier = hsr_check_carrier(master); has_carrier = hsr_check_carrier(master);
hsr_set_operstate(master, has_carrier); hsr_set_operstate(master, has_carrier);
hsr_check_announce(master->dev, old_operstate); hsr_check_announce(master->dev, old_operstate);
......
...@@ -6025,7 +6025,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, ...@@ -6025,7 +6025,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
(dev->ifindex != dev_get_iflink(dev) && (dev->ifindex != dev_get_iflink(dev) &&
nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev))) || nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev))) ||
nla_put_u8(skb, IFLA_OPERSTATE, nla_put_u8(skb, IFLA_OPERSTATE,
netif_running(dev) ? dev->operstate : IF_OPER_DOWN)) netif_running(dev) ? READ_ONCE(dev->operstate) : IF_OPER_DOWN))
goto nla_put_failure; goto nla_put_failure;
protoinfo = nla_nest_start_noflag(skb, IFLA_PROTINFO); protoinfo = nla_nest_start_noflag(skb, IFLA_PROTINFO);
if (!protoinfo) if (!protoinfo)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment