Linux RDMA and InfiniBand development
 help / color / mirror / Atom feed
From: Zhu Yanjun <yanjun.zhu@linux.dev>
To: Purushothaman Ramalingam <purush.ramalingam@gmail.com>,
	Zhu Yanjun <zyjzyj2000@gmail.com>,
	"yanjun.zhu@linux.dev" <yanjun.zhu@linux.dev>
Cc: Jason Gunthorpe <jgg@ziepe.ca>, Leon Romanovsky <leon@kernel.org>,
	linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] RDMA/rxe: fix UDP tunnel socket leak on rxe_newlink failure
Date: Fri, 29 May 2026 21:37:31 -0700	[thread overview]
Message-ID: <a671f568-30d3-4565-b951-efdd640ef891@linux.dev> (raw)
In-Reply-To: <20260530001251.11136-1-purush.ramalingam@gmail.com>

在 2026/5/29 17:12, Purushothaman Ramalingam 写道:
> rxe_newlink() calls rxe_net_init() to set up the per-net-namespace UDP
> tunnel sockets before calling rxe_net_add() to create and register the
> rxe device. rxe_net_init() takes a reference on the IPv4 and IPv6 tunnel
> sockets, creating them if they do not already exist.
> 
> If rxe_net_add() subsequently fails, rxe_newlink() returns the error
> without releasing those socket references. The normal teardown path,
> rxe_net_del(), is never reached because rxe_net_add() has already
> deallocated the rxe device on failure. As a result the tunnel socket
> references are leaked and the per-net sockets bound to UDP port 4791 can
> never be released.
> 
> Release the references on the error path by adding rxe_net_uninit(),
> which performs the same socket teardown as rxe_net_del(). The shared
> release logic is factored into a helper to avoid duplication.
> 
> Fixes: f1327abd6abe ("RDMA/rxe: Support RDMA link creation and destruction per net namespace")
> Signed-off-by: Purushothaman Ramalingam <purush.ramalingam@gmail.com>
> ---
>   drivers/infiniband/sw/rxe/rxe.c     |  1 +
>   drivers/infiniband/sw/rxe/rxe_net.c | 32 ++++++++++++++++++++---------
>   drivers/infiniband/sw/rxe/rxe_net.h |  1 +
>   3 files changed, 24 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c
> index af39209d0fcf..bcc72b96ee00 100644
> --- a/drivers/infiniband/sw/rxe/rxe.c
> +++ b/drivers/infiniband/sw/rxe/rxe.c
> @@ -243,6 +243,7 @@ static int rxe_newlink(const char *ibdev_name, struct net_device *ndev)
>   	err = rxe_net_add(ibdev_name, ndev);
>   	if (err) {
>   		rxe_err("failed to add %s\n", ndev->name);
> +		rxe_net_uninit(ndev);
>   		goto err;

To avoid introducing an unnecessary single-line wrapper helper 
(rxe_net_uninit), we have refactored the cleanup logic by directly 
exporting the core rxe_release_sockets(struct net *net) function. Since 
the tunnel sockets are managed per network namespace, passing struct net 
* aligns perfectly with the network subsystem's conventions.

Additionally, we have removed the now-redundant err: label from 
rxe_newlink() to keep the error path clean and idiomatic.

Here is the updated patch:
"
diff --git a/drivers/infiniband/sw/rxe/rxe.c 
b/drivers/infiniband/sw/rxe/rxe.c
index b0714f9abe3d..a83512afd388 100644
--- a/drivers/infiniband/sw/rxe/rxe.c
+++ b/drivers/infiniband/sw/rxe/rxe.c
@@ -243,7 +243,7 @@ static int rxe_newlink(const char *ibdev_name, 
struct net_device *ndev)
         err = rxe_net_add(ibdev_name, ndev);
         if (err) {
                 rxe_err("failed to add %s\n", ndev->name);
-               goto err;
+               rxe_release_sockets(dev_net(ndev));
         }
  err:
         return err;
diff --git a/drivers/infiniband/sw/rxe/rxe_net.c 
b/drivers/infiniband/sw/rxe/rxe_net.c
index 50a2cb5405e2..f540a9b8a094 100644
--- a/drivers/infiniband/sw/rxe/rxe_net.c
+++ b/drivers/infiniband/sw/rxe/rxe_net.c
@@ -642,18 +642,10 @@ static void rxe_sock_put(struct sock *sk,
         }
  }

-void rxe_net_del(struct ib_device *dev)
+/* release the per-net-namespace tunnel socket references held for @net */
+void rxe_release_sockets(struct net *net)
  {
-       struct rxe_dev *rxe = container_of(dev, struct rxe_dev, ib_dev);
-       struct net_device *ndev;
         struct sock *sk;
-       struct net *net;
-
-       ndev = rxe_ib_device_get_netdev(&rxe->ib_dev);
-       if (!ndev)
-               return;
-
-       net = dev_net(ndev);

         sk = rxe_ns_pernet_sk4(net);
         if (sk)
@@ -662,6 +654,18 @@ void rxe_net_del(struct ib_device *dev)
         sk = rxe_ns_pernet_sk6(net);
         if (sk)
                 rxe_sock_put(sk, rxe_ns_pernet_set_sk6, net);
+}
+
+void rxe_net_del(struct ib_device *dev)
+{
+       struct rxe_dev *rxe = container_of(dev, struct rxe_dev, ib_dev);
+       struct net_device *ndev;
+
+       ndev = rxe_ib_device_get_netdev(&rxe->ib_dev);
+       if (!ndev)
+               return;
+
+       rxe_release_sockets(dev_net(ndev));

         dev_put(ndev);
  }
diff --git a/drivers/infiniband/sw/rxe/rxe_net.h 
b/drivers/infiniband/sw/rxe/rxe_net.h
index 56249677d692..c8605de62bbd 100644
--- a/drivers/infiniband/sw/rxe/rxe_net.h
+++ b/drivers/infiniband/sw/rxe/rxe_net.h
@@ -16,6 +16,7 @@ void rxe_net_del(struct ib_device *dev);

  int rxe_register_notifier(void);
  int rxe_net_init(struct net_device *ndev);
+void rxe_release_sockets(struct net *net);
  void rxe_net_exit(void);

  #endif /* RXE_NET_H */
"

Another commit is related to this issue and is currently on the waiting 
list:

https://patchwork.kernel.org/project/linux-rdma/patch/20260519023541.8594-1-yanjun.zhu@linux.dev/

The two commits conflict with each other. Once one of them is merged, 
the other will need to be updated accordingly.

Let's keep an eye on both commits and make any necessary changes after 
the merge decision is made.

Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>

Zhu Yanjun


>   	}
>   err:
> diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c
> index 50a2cb5405e2..b98f66099dea 100644
> --- a/drivers/infiniband/sw/rxe/rxe_net.c
> +++ b/drivers/infiniband/sw/rxe/rxe_net.c
> @@ -642,18 +642,10 @@ static void rxe_sock_put(struct sock *sk,
>   	}
>   }
>   
> -void rxe_net_del(struct ib_device *dev)
> +/* release the per-net-namespace tunnel socket references held for @net */
> +static void rxe_release_sockets(struct net *net)
>   {
> -	struct rxe_dev *rxe = container_of(dev, struct rxe_dev, ib_dev);
> -	struct net_device *ndev;
>   	struct sock *sk;
> -	struct net *net;
> -
> -	ndev = rxe_ib_device_get_netdev(&rxe->ib_dev);
> -	if (!ndev)
> -		return;
> -
> -	net = dev_net(ndev);
>   
>   	sk = rxe_ns_pernet_sk4(net);
>   	if (sk)
> @@ -662,6 +654,26 @@ void rxe_net_del(struct ib_device *dev)
>   	sk = rxe_ns_pernet_sk6(net);
>   	if (sk)
>   		rxe_sock_put(sk, rxe_ns_pernet_set_sk6, net);
> +}
> +
> +/* release the socket references taken by a successful rxe_net_init() when a
> + * later step of device creation fails and rxe_net_del() will not be called
> + */
> +void rxe_net_uninit(struct net_device *ndev)
> +{
> +	rxe_release_sockets(dev_net(ndev));
> +}
> +
> +void rxe_net_del(struct ib_device *dev)
> +{
> +	struct rxe_dev *rxe = container_of(dev, struct rxe_dev, ib_dev);
> +	struct net_device *ndev;
> +
> +	ndev = rxe_ib_device_get_netdev(&rxe->ib_dev);
> +	if (!ndev)
> +		return;
> +
> +	rxe_release_sockets(dev_net(ndev));
>   
>   	dev_put(ndev);
>   }
> diff --git a/drivers/infiniband/sw/rxe/rxe_net.h b/drivers/infiniband/sw/rxe/rxe_net.h
> index 56249677d692..d55aacce2905 100644
> --- a/drivers/infiniband/sw/rxe/rxe_net.h
> +++ b/drivers/infiniband/sw/rxe/rxe_net.h
> @@ -16,6 +16,7 @@ void rxe_net_del(struct ib_device *dev);
>   
>   int rxe_register_notifier(void);
>   int rxe_net_init(struct net_device *ndev);
> +void rxe_net_uninit(struct net_device *ndev);
>   void rxe_net_exit(void);
>   
>   #endif /* RXE_NET_H */


      reply	other threads:[~2026-05-30  4:37 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-30  0:12 [PATCH] RDMA/rxe: fix UDP tunnel socket leak on rxe_newlink failure Purushothaman Ramalingam
2026-05-30  4:37 ` Zhu Yanjun [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a671f568-30d3-4565-b951-efdd640ef891@linux.dev \
    --to=yanjun.zhu@linux.dev \
    --cc=jgg@ziepe.ca \
    --cc=leon@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=purush.ramalingam@gmail.com \
    --cc=zyjzyj2000@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox