On Tue, Jul 09, 2019 at 09:43:46AM +0300, Leon Romanovsky wrote:
> On Tue, Jul 09, 2019 at 01:56:36PM +1000, Stephen Rothwell wrote:
> > Hi all,
> >
> > After merging the net-next tree, today's linux-next build (x86_64
> > allmodconfig) failed like this:
> >
> > drivers/infiniband/sw/siw/siw_cm.c: In function 'siw_create_listen':
> > drivers/infiniband/sw/siw/siw_cm.c:1978:3: error: implicit declaration of 
> > function 'for_ifa'; did you mean 'fork_idle'? 
> > [-Werror=implicit-function-declaration]
> >    for_ifa(in_dev)
> >    ^~~~~~~
> >    fork_idle
> > drivers/infiniband/sw/siw/siw_cm.c:1978:18: error: expected ';' before '{' 
> > token
> >    for_ifa(in_dev)
> >                   ^
> >                   ;
> >    {
> >    ~
> >
> > Caused by commit
> >
> >   6c52fdc244b5 ("rdma/siw: connection management")
> >
> > from the rdma tree.  I don't know why this didn't fail after I mereged
> > that tree.
> 
> I had the same question, because I have this fix for a couple of days already.
> 
> From 56c9e15ec670af580daa8c3ffde9503af3042d67 Mon Sep 17 00:00:00 2001
> From: Leon Romanovsky <leo...@mellanox.com>
> Date: Sun, 7 Jul 2019 10:43:42 +0300
> Subject: [PATCH] Fixup to build SIW issue
> 
> Signed-off-by: Leon Romanovsky <leo...@mellanox.com>
>  drivers/infiniband/sw/siw/siw_cm.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/infiniband/sw/siw/siw_cm.c 
> b/drivers/infiniband/sw/siw/siw_cm.c
> index 8e618cb7261f..c883bf514341 100644
> +++ b/drivers/infiniband/sw/siw/siw_cm.c
> @@ -1954,6 +1954,7 @@ static void siw_drop_listeners(struct iw_cm_id *id)
>  int siw_create_listen(struct iw_cm_id *id, int backlog)
>  {
>       struct net_device *dev = to_siw_dev(id->device)->netdev;
> +     const struct in_ifaddr *ifa;
>       int rv = 0, listeners = 0;
> 
>       siw_dbg(id->device, "id 0x%p: backlog %d\n", id, backlog);
> @@ -1975,8 +1976,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
>                       id, &s_laddr.sin_addr, ntohs(s_laddr.sin_port),
>                       &s_raddr->sin_addr, ntohs(s_raddr->sin_port));
> 
> -             for_ifa(in_dev)
> -             {
> +             in_dev_for_each_ifa_rcu(ifa, in_dev) {
>                       if (ipv4_is_zeronet(s_laddr.sin_addr.s_addr) ||

Hum. There is no rcu lock held here and we can't use RCU anyhow as
siw_listen_address will sleep.

I think this needs to use rtnl, as below. Bernard, please urgently
confirm. Thanks

diff --git a/drivers/infiniband/sw/siw/siw_cm.c 
b/drivers/infiniband/sw/siw/siw_cm.c
index 8e618cb7261f62..ee98e96a5bfaba 100644
--- a/drivers/infiniband/sw/siw/siw_cm.c
+++ b/drivers/infiniband/sw/siw/siw_cm.c
@@ -1965,6 +1965,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
         */
        if (id->local_addr.ss_family == AF_INET) {
                struct in_device *in_dev = in_dev_get(dev);
+               const struct in_ifaddr *ifa;
                struct sockaddr_in s_laddr, *s_raddr;
 
                memcpy(&s_laddr, &id->local_addr, sizeof(s_laddr));
@@ -1975,8 +1976,8 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
                        id, &s_laddr.sin_addr, ntohs(s_laddr.sin_port),
                        &s_raddr->sin_addr, ntohs(s_raddr->sin_port));
 
-               for_ifa(in_dev)
-               {
+               rtnl_lock();
+               in_dev_for_each_ifa_rtnl(ifa, in_dev) {
                        if (ipv4_is_zeronet(s_laddr.sin_addr.s_addr) ||
                            s_laddr.sin_addr.s_addr == ifa->ifa_address) {
                                s_laddr.sin_addr.s_addr = ifa->ifa_address;
@@ -1988,7 +1989,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
                                        listeners++;
                        }
                }
-               endfor_ifa(in_dev);
+               rtnl_unlock();
                in_dev_put(in_dev);
        } else if (id->local_addr.ss_family == AF_INET6) {
                struct inet6_dev *in6_dev = in6_dev_get(dev);

Reply via email to