summaryrefslogtreecommitdiff
path: root/drivers/infiniband/core/addr.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2011-11-29 22:31:23 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2011-12-09 08:55:21 -0800
commitde5f8dc38303f9a1fc58349f0d1c6f46a8034a00 (patch)
tree2530f980d5062f29ec7b2d78e2a83aa7c7a9e25e /drivers/infiniband/core/addr.c
parent829d5a92cbfe6e906bbe24a5bb1675a6d27a5db2 (diff)
IB: Fix RCU lockdep splats
commit 580da35a31f91a594f3090b7a2c39b85cb051a12 upstream. Commit f2c31e32b37 ("net: fix NULL dereferences in check_peer_redir()") forgot to take care of infiniband uses of dst neighbours. Many thanks to Marc Aurele who provided a nice bug report and feedback. Reported-by: Marc Aurele La France <tsi@ualberta.ca> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Cc: David Miller <davem@davemloft.net> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/core/addr.c')
-rw-r--r--drivers/infiniband/core/addr.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 236ad9a89c0a..f2a84c6f8543 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -215,7 +215,9 @@ static int addr4_resolve(struct sockaddr_in *src_in,
neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev);
if (!neigh || !(neigh->nud_state & NUD_VALID)) {
+ rcu_read_lock();
neigh_event_send(dst_get_neighbour(&rt->dst), NULL);
+ rcu_read_unlock();
ret = -ENODATA;
if (neigh)
goto release;
@@ -273,15 +275,16 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
goto put;
}
+ rcu_read_lock();
neigh = dst_get_neighbour(dst);
if (!neigh || !(neigh->nud_state & NUD_VALID)) {
if (neigh)
neigh_event_send(neigh, NULL);
ret = -ENODATA;
- goto put;
+ } else {
+ ret = rdma_copy_addr(addr, dst->dev, neigh->ha);
}
-
- ret = rdma_copy_addr(addr, dst->dev, neigh->ha);
+ rcu_read_unlock();
put:
dst_release(dst);
return ret;