Commit aa603467 authored by Hangbin Liu's avatar Hangbin Liu Committed by David S. Miller

bonding: use rcu_dereference_rtnl when get bonding active slave

bond_option_active_slave_get_rcu() should not be used in rtnl_mutex as it
use rcu_dereference(). Replace to rcu_dereference_rtnl() so we also can use
this function in rtnl protected context.

With this update, we can rmeove the rcu_read_lock/unlock in
bonding .ndo_eth_ioctl and .get_ts_info.
Reported-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Fixes: 94dd016a ("bond: pass get_ts_info and SIOC[SG]HWTSTAMP ioctl to active device")
Signed-off-by: default avatarHangbin Liu <liuhangbin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2148927e
...@@ -4133,9 +4133,7 @@ static int bond_eth_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cm ...@@ -4133,9 +4133,7 @@ static int bond_eth_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cm
fallthrough; fallthrough;
case SIOCGHWTSTAMP: case SIOCGHWTSTAMP:
rcu_read_lock();
real_dev = bond_option_active_slave_get_rcu(bond); real_dev = bond_option_active_slave_get_rcu(bond);
rcu_read_unlock();
if (!real_dev) if (!real_dev)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -5382,9 +5380,7 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev, ...@@ -5382,9 +5380,7 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
struct net_device *real_dev; struct net_device *real_dev;
struct phy_device *phydev; struct phy_device *phydev;
rcu_read_lock();
real_dev = bond_option_active_slave_get_rcu(bond); real_dev = bond_option_active_slave_get_rcu(bond);
rcu_read_unlock();
if (real_dev) { if (real_dev) {
ops = real_dev->ethtool_ops; ops = real_dev->ethtool_ops;
phydev = real_dev->phydev; phydev = real_dev->phydev;
......
...@@ -346,7 +346,7 @@ static inline bool bond_uses_primary(struct bonding *bond) ...@@ -346,7 +346,7 @@ static inline bool bond_uses_primary(struct bonding *bond)
static inline struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond) static inline struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond)
{ {
struct slave *slave = rcu_dereference(bond->curr_active_slave); struct slave *slave = rcu_dereference_rtnl(bond->curr_active_slave);
return bond_uses_primary(bond) && slave ? slave->dev : NULL; return bond_uses_primary(bond) && slave ? slave->dev : NULL;
} }
......
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