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

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
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -455,7 +455,8 @@ static int br_fill_ifinfo(struct sk_buff *skb,
			  u32 filter_mask, const struct net_device *dev,
			  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 net_bridge *br;
	struct ifinfomsg *hdr;
+2 −2
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ static void rfc2863_policy(struct net_device *dev)
{
	unsigned char operstate = default_operstate(dev);

	if (operstate == dev->operstate)
	if (operstate == READ_ONCE(dev->operstate))
		return;

	write_lock(&dev_base_lock);
@@ -87,7 +87,7 @@ static void rfc2863_policy(struct net_device *dev)
		break;
	}

	dev->operstate = operstate;
	WRITE_ONCE(dev->operstate, operstate);

	write_unlock(&dev_base_lock);
}
+1 −3
Original line number Diff line number Diff line
@@ -325,11 +325,9 @@ static ssize_t operstate_show(struct device *dev,
	const struct net_device *netdev = to_net_dev(dev);
	unsigned char operstate;

	read_lock(&dev_base_lock);
	operstate = netdev->operstate;
	operstate = READ_ONCE(netdev->operstate);
	if (!netif_running(netdev))
		operstate = IF_OPER_DOWN;
	read_unlock(&dev_base_lock);

	if (operstate >= ARRAY_SIZE(operstates))
		return -EINVAL; /* should not happen */
+2 −2
Original line number Diff line number Diff line
@@ -866,9 +866,9 @@ static void set_operstate(struct net_device *dev, unsigned char transition)
		break;
	}

	if (dev->operstate != operstate) {
	if (READ_ONCE(dev->operstate) != operstate) {
		write_lock(&dev_base_lock);
		dev->operstate = operstate;
		WRITE_ONCE(dev->operstate, operstate);
		write_unlock(&dev_base_lock);
		netdev_state_change(dev);
	}
+5 −5
Original line number Diff line number Diff line
@@ -31,8 +31,8 @@ static bool is_slave_up(struct net_device *dev)
static void __hsr_set_operstate(struct net_device *dev, int transition)
{
	write_lock(&dev_base_lock);
	if (dev->operstate != transition) {
		dev->operstate = transition;
	if (READ_ONCE(dev->operstate) != transition) {
		WRITE_ONCE(dev->operstate, transition);
		write_unlock(&dev_base_lock);
		netdev_state_change(dev);
	} else {
@@ -78,14 +78,14 @@ static void hsr_check_announce(struct net_device *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 */
		hsr->announce_count = 0;
		mod_timer(&hsr->announce_timer,
			  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 */
		del_timer(&hsr->announce_timer);
}
@@ -100,7 +100,7 @@ void hsr_check_carrier_and_operstate(struct hsr_priv *hsr)
	/* netif_stacked_transfer_operstate() cannot be used here since
	 * 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);
	hsr_set_operstate(master, has_carrier);
	hsr_check_announce(master->dev, old_operstate);
Loading