From: Allison Henderson <achender@kernel.org>
To: netdev@vger.kernel.org, linux-rdma@vger.kernel.org,
pabeni@redhat.com, edumazet@google.com, kuba@kernel.org,
horms@kernel.org
Cc: achender@kernel.org, oleg@redhat.com, joel.granados@kernel.org
Subject: [PATCH net 2/2] net/rds: do not initialize transports after rds_init() failed
Date: Wed, 21 Oct 2026 12:58:37 -0700 [thread overview]
Message-ID: <20261021195837.142802-3-achender@kernel.org> (raw)
In-Reply-To: <20261021195837.142802-1-achender@kernel.org>
rds, rds_rdma and rds_tcp each have their own module_init(). When they
are built in, those run in link order, so rds_init() goes first, but
do_initcalls() does not stop when it fails. The transports then
initialize against a core that has already been torn down: rds_wq has
been destroyed, yet rds_ib_dev_put(), rds_ib_unregister_client() and
rds_tcp_accept_work() still queue onto or flush it, and
rds_trans_register() hands the transports to a core whose socket
family may never have been registered.
This was seen with CONFIG_SYSCTL=n, where rds_sysctl_init() failed and
rds_ib_init()'s error path then flushed the freed rds_wq [1], but any
rds_init() failure after rds_threads_init() has the same effect.
Record whether rds_init() succeeded and have rds_rdma_init() and
rds_tcp_init() bail out with -ENODEV otherwise. Modular builds are
unaffected: the transports need symbols exported by rds.ko, so they
cannot be loaded unless rds_init() succeeded.
[1] https://lore.kernel.org/oe-lkp/202610190310.9737b2e3-lkp@intel.com
Fixes: 55b7ed0b582f ("RDS: Common RDMA transport code")
Fixes: 70041088e3b9 ("RDS: Add TCP transport to RDS")
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Assisted-by: LLM
Signed-off-by: Allison Henderson <achender@kernel.org>
---
net/rds/af_rds.c | 14 ++++++++++++++
net/rds/rdma_transport.c | 3 +++
net/rds/rds.h | 1 +
net/rds/tcp.c | 3 +++
4 files changed, 21 insertions(+)
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index d5defe9172e3..840587c05178 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -922,8 +922,11 @@ static void rds6_sock_info(struct socket *sock, unsigned int len,
}
#endif
+static bool rds_initialized;
+
static void rds_exit(void)
{
+ rds_initialized = false;
sock_unregister(rds_family_ops.family);
proto_unregister(&rds_proto);
rds_conn_exit();
@@ -944,6 +947,16 @@ module_exit(rds_exit);
u32 rds_gen_num;
+/* When RDS is built in, a failed rds_init() does not stop the rds_rdma
+ * and rds_tcp initcalls from running against a core that has already
+ * been torn down (rds_wq in particular). Let them bail out early.
+ */
+bool rds_is_initialized(void)
+{
+ return rds_initialized;
+}
+EXPORT_SYMBOL_GPL(rds_is_initialized);
+
static int __init rds_init(void)
{
int ret;
@@ -980,6 +993,7 @@ static int __init rds_init(void)
rds_info_register_func(RDS6_INFO_SOCKETS, rds6_sock_info);
rds_info_register_func(RDS6_INFO_RECV_MESSAGES, rds6_sock_inc_info);
#endif
+ rds_initialized = true;
goto out;
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c
index 7be38be1228e..cc6a7d29791a 100644
--- a/net/rds/rdma_transport.c
+++ b/net/rds/rdma_transport.c
@@ -325,6 +325,9 @@ static int __init rds_rdma_init(void)
{
int ret;
+ if (!rds_is_initialized())
+ return -ENODEV;
+
ret = rds_ib_init();
if (ret)
goto out;
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 2db49573dacd..b7ef7c8b1e03 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -1040,6 +1040,7 @@ extern unsigned int rds_sysctl_trace_level;
int rds_threads_init(void);
void rds_threads_exit(void);
extern struct workqueue_struct *rds_wq;
+bool rds_is_initialized(void);
void rds_queue_reconnect(struct rds_conn_path *cp);
void rds_connect_worker(struct work_struct *);
void rds_shutdown_worker(struct work_struct *);
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index 34815b4f658b..c1ad37505417 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -815,6 +815,9 @@ static int __init rds_tcp_init(void)
{
int ret;
+ if (!rds_is_initialized())
+ return -ENODEV;
+
rds_tcp_conn_slab = KMEM_CACHE(rds_tcp_connection, 0);
if (!rds_tcp_conn_slab) {
ret = -ENOMEM;
--
2.50.1
next prev parent reply other threads:[~2026-10-21 19:58 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 19:58 [PATCH net 0/2] net/rds: fix init failures leaving built-in transports on a dead core Allison Henderson
2026-10-21 19:58 ` [PATCH net 1/2] net/rds: do not fail init when CONFIG_SYSCTL=n Allison Henderson
2026-10-21 20:03 ` sashiko-bot
2026-10-22 7:22 ` Joel Granados
2026-10-22 12:33 ` Oleg Nesterov
2026-10-21 19:58 ` Allison Henderson [this message]
2026-10-21 20:03 ` [PATCH net 2/2] net/rds: do not initialize transports after rds_init() failed sashiko-bot
2026-10-27 10:40 ` [PATCH net 0/2] net/rds: fix init failures leaving built-in transports on a dead core patchwork-bot+netdevbpf
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=20261021195837.142802-3-achender@kernel.org \
--to=achender@kernel.org \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=joel.granados@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=oleg@redhat.com \
--cc=pabeni@redhat.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.