-----"Jason Gunthorpe" <jgg@xxxxxxxx> wrote: ----- >To: "Bernard Metzler" <bmt@xxxxxxxxxxxxxx> >From: "Jason Gunthorpe" <jgg@xxxxxxxx> >Date: 08/27/2019 07:28PM >Cc: linux-rdma@xxxxxxxxxxxxxxx, bvanassche@xxxxxxx, >dledford@xxxxxxxxxx >Subject: [EXTERNAL] Re: [PATCH v2] RDMA/siw: Fix IPv6 addr_list >locking > >On Tue, Aug 27, 2019 at 06:49:55PM +0200, Bernard Metzler wrote: >> Walking the address list of an inet6_dev requires >> appropriate locking. Since the called function >> siw_listen_address() may sleep, we have to use >> rtnl_lock() instead of read_lock_bh(). >> >> Also introduces: >> - sanity checks if we got a device from >> in_dev_get() or in6_dev_get(). >> - skipping IPv6 addresses flagged IFA_F_TENTATIVE >> or IFA_F_DEPRECATED >> >> Reported-by: Bart Van Assche <bvanassche@xxxxxxx> >> Fixes: 6c52fdc244b5 ("rdma/siw: connection management") >> Signed-off-by: Bernard Metzler <bmt@xxxxxxxxxxxxxx> >> drivers/infiniband/sw/siw/siw_cm.c | 33 >+++++++++++++++++++----------- >> 1 file changed, 21 insertions(+), 12 deletions(-) >> >> diff --git a/drivers/infiniband/sw/siw/siw_cm.c >b/drivers/infiniband/sw/siw/siw_cm.c >> index 1db5ad3d9580..c145b4ff4556 100644 >> +++ b/drivers/infiniband/sw/siw/siw_cm.c >> @@ -1962,6 +1962,10 @@ int siw_create_listen(struct iw_cm_id *id, >int backlog) >> struct sockaddr_in s_laddr, *s_raddr; >> const struct in_ifaddr *ifa; >> >> + if (!in_dev) { >> + rv = -ENODEV; >> + goto out; >> + } >> memcpy(&s_laddr, &id->local_addr, sizeof(s_laddr)); >> s_raddr = (struct sockaddr_in *)&id->remote_addr; >> >> @@ -1991,22 +1995,27 @@ int siw_create_listen(struct iw_cm_id *id, >int backlog) >> struct sockaddr_in6 *s_laddr = &to_sockaddr_in6(id->local_addr), >> *s_raddr = &to_sockaddr_in6(id->remote_addr); >> >> + if (!in6_dev) { >> + rv = -ENODEV; >> + goto out; >> + } >> siw_dbg(id->device, >> "laddr %pI6:%d, raddr %pI6:%d\n", >> &s_laddr->sin6_addr, ntohs(s_laddr->sin6_port), >> &s_raddr->sin6_addr, ntohs(s_raddr->sin6_port)); >> >> - read_lock_bh(&in6_dev->lock); >> - list_for_each_entry(ifp, &in6_dev->addr_list, if_list) { >> - struct sockaddr_in6 bind_addr; >> - >> + rtnl_lock(); >> + list_for_each_entry_rcu(ifp, &in6_dev->addr_list, if_list) { > >If not holding RCU then don't use the rcu list iterator.. > absolutely!