Linux-RDMA Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v1 rdma-next] i40iw: Do an RCU lookup in i40iw_add_ipv4_addr
@ 2020-02-04 22:38 Shiraz Saleem
  2020-02-11 18:32 ` Jason Gunthorpe
  0 siblings, 1 reply; 2+ messages in thread
From: Shiraz Saleem @ 2020-02-04 22:38 UTC (permalink / raw)
  To: dledford, jgg; +Cc: linux-rdma, Shiraz Saleem

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.

Fixes: 8e06af711bf2 ("i40iw: add main, hdr, status")
Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
---
v0-->v1:
Annotate dev->flags with READ_ONCE

 drivers/infiniband/hw/i40iw/i40iw_main.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c
index 2386143..84e1b52 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_main.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_main.c
@@ -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();
 }
 
 /**
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH v1 rdma-next] i40iw: Do an RCU lookup in i40iw_add_ipv4_addr
  2020-02-04 22:38 [PATCH v1 rdma-next] i40iw: Do an RCU lookup in i40iw_add_ipv4_addr Shiraz Saleem
@ 2020-02-11 18:32 ` Jason Gunthorpe
  0 siblings, 0 replies; 2+ messages in thread
From: Jason Gunthorpe @ 2020-02-11 18:32 UTC (permalink / raw)
  To: Shiraz Saleem; +Cc: dledford, linux-rdma

On Tue, Feb 04, 2020 at 04:38:40PM -0600, Shiraz Saleem wrote:
> 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.
> 
> Fixes: 8e06af711bf2 ("i40iw: add main, hdr, status")
> Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
> ---
> v0-->v1:
> Annotate dev->flags with READ_ONCE

Applied to for-next, thanks

Jason

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, back to index

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-04 22:38 [PATCH v1 rdma-next] i40iw: Do an RCU lookup in i40iw_add_ipv4_addr Shiraz Saleem
2020-02-11 18:32 ` Jason Gunthorpe

Linux-RDMA Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-rdma/0 linux-rdma/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-rdma linux-rdma/ https://lore.kernel.org/linux-rdma \
		linux-rdma@vger.kernel.org
	public-inbox-index linux-rdma

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-rdma


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git