mirror of
https://github.com/torvalds/linux
synced 2024-10-07 20:05:15 +00:00
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: 8e06af711b
("i40iw: add main, hdr, status")
Link: https://lore.kernel.org/r/20200204223840.2151-1-shiraz.saleem@intel.com
Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
d7e2d3432a
commit
9a4b24108d
|
@ -1212,22 +1212,19 @@ static void i40iw_add_ipv4_addr(struct i40iw_device *iwdev)
|
|||
{
|
||||
struct net_device *dev;
|
||||
struct in_device *idev;
|
||||
bool got_lock = true;
|
||||
u32 ip_addr;
|
||||
|
||||
if (!rtnl_trylock())
|
||||
got_lock = false;
|
||||
|
||||
for_each_netdev(&init_net, dev) {
|
||||
rcu_read_lock();
|
||||
for_each_netdev_rcu(&init_net, dev) {
|
||||
if ((((rdma_vlan_dev_vlan_id(dev) < 0xFFFF) &&
|
||||
(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;
|
||||
|
||||
idev = in_dev_get(dev);
|
||||
idev = __in_dev_get_rcu(dev);
|
||||
if (!idev)
|
||||
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,
|
||||
"IP=%pI4, vlan_id=%d, MAC=%pM\n", &ifa->ifa_address,
|
||||
rdma_vlan_dev_vlan_id(dev), dev->dev_addr);
|
||||
|
@ -1239,12 +1236,9 @@ static void i40iw_add_ipv4_addr(struct i40iw_device *iwdev)
|
|||
true,
|
||||
I40IW_ARP_ADD);
|
||||
}
|
||||
|
||||
in_dev_put(idev);
|
||||
}
|
||||
}
|
||||
if (got_lock)
|
||||
rtnl_unlock();
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue