Commit 9a4b2410 authored by Shiraz Saleem's avatar Shiraz Saleem Committed by Jason Gunthorpe

i40iw: Do an RCU lookup in i40iw_add_ipv4_addr

The in_dev_for_each_ifa_rtnl() iterator in i40iw_add_ipv4_addr requires
that the rtnl lock be held. But the rtnl_trylock/unlock scheme in this
function does not guarantee it.

Replace the rtnl locking with an RCU lookup using
in_dev_for_each_ifa_rcu()

Fixes: 8e06af71 ("i40iw: add main, hdr, status")
Link: https://lore.kernel.org/r/20200204223840.2151-1-shiraz.saleem@intel.comSigned-off-by: default avatarShiraz Saleem <shiraz.saleem@intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent d7e2d343
...@@ -1212,22 +1212,19 @@ static void i40iw_add_ipv4_addr(struct i40iw_device *iwdev) ...@@ -1212,22 +1212,19 @@ static void i40iw_add_ipv4_addr(struct i40iw_device *iwdev)
{ {
struct net_device *dev; struct net_device *dev;
struct in_device *idev; struct in_device *idev;
bool got_lock = true;
u32 ip_addr; u32 ip_addr;
if (!rtnl_trylock()) rcu_read_lock();
got_lock = false; for_each_netdev_rcu(&init_net, dev) {
for_each_netdev(&init_net, dev) {
if ((((rdma_vlan_dev_vlan_id(dev) < 0xFFFF) && if ((((rdma_vlan_dev_vlan_id(dev) < 0xFFFF) &&
(rdma_vlan_dev_real_dev(dev) == iwdev->netdev)) || (rdma_vlan_dev_real_dev(dev) == iwdev->netdev)) ||
(dev == iwdev->netdev)) && (dev->flags & IFF_UP)) { (dev == iwdev->netdev)) && (READ_ONCE(dev->flags) & IFF_UP)) {
const struct in_ifaddr *ifa; const struct in_ifaddr *ifa;
idev = in_dev_get(dev); idev = __in_dev_get_rcu(dev);
if (!idev) if (!idev)
continue; continue;
in_dev_for_each_ifa_rtnl(ifa, idev) { in_dev_for_each_ifa_rcu(ifa, idev) {
i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_CM, i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_CM,
"IP=%pI4, vlan_id=%d, MAC=%pM\n", &ifa->ifa_address, "IP=%pI4, vlan_id=%d, MAC=%pM\n", &ifa->ifa_address,
rdma_vlan_dev_vlan_id(dev), dev->dev_addr); rdma_vlan_dev_vlan_id(dev), dev->dev_addr);
...@@ -1239,12 +1236,9 @@ static void i40iw_add_ipv4_addr(struct i40iw_device *iwdev) ...@@ -1239,12 +1236,9 @@ static void i40iw_add_ipv4_addr(struct i40iw_device *iwdev)
true, true,
I40IW_ARP_ADD); I40IW_ARP_ADD);
} }
in_dev_put(idev);
} }
} }
if (got_lock) rcu_read_unlock();
rtnl_unlock();
} }
/** /**
......
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