Skip to content

Commit be4c05d

Browse files
Md Haris Iqbalgregkh
authored andcommitted
RDMA/rtrs-srv: Incorporate ib_register_client into rtrs server init
[ Upstream commit 558d52b ] The rnbd_server module's communication manager (cm) initialization depends on the registration of the "network namespace subsystem" of the RDMA CM agent module. As such, when the kernel is configured to load the rnbd_server and the RDMA cma module during initialization; and if the rnbd_server module is initialized before RDMA cma module, a null ptr dereference occurs during the RDMA bind operation. Call trace: Call Trace: ? xas_load+0xd/0x80 xa_load+0x47/0x80 cma_ps_find+0x44/0x70 rdma_bind_addr+0x782/0x8b0 ? get_random_bytes+0x35/0x40 rtrs_srv_cm_init+0x50/0x80 rtrs_srv_open+0x102/0x180 ? rnbd_client_init+0x6e/0x6e rnbd_srv_init_module+0x34/0x84 ? rnbd_client_init+0x6e/0x6e do_one_initcall+0x4a/0x200 kernel_init_freeable+0x1f1/0x26e ? rest_init+0xb0/0xb0 kernel_init+0xe/0x100 ret_from_fork+0x22/0x30 Modules linked in: CR2: 0000000000000015 All this happens cause the cm init is in the call chain of the module init, which is not a preferred practice. So remove the call to rdma_create_id() from the module init call chain. Instead register rtrs-srv as an ib client, which makes sure that the rdma_create_id() is called only when an ib device is added. Fixes: 9cb8374 ("RDMA/rtrs: server: main functionality") Link: https://lore.kernel.org/r/20200907103106.104530-1-haris.iqbal@cloud.ionos.com Reported-by: kernel test robot <rong.a.chen@intel.com> Signed-off-by: Md Haris Iqbal <haris.iqbal@cloud.ionos.com> Reviewed-by: Jack Wang <jinpu.wang@cloud.ionos.com> Reviewed-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 24b2c89 commit be4c05d

2 files changed

Lines changed: 80 additions & 3 deletions

File tree

drivers/infiniband/ulp/rtrs/rtrs-srv.c

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "rtrs-srv.h"
1717
#include "rtrs-log.h"
1818
#include <rdma/ib_cm.h>
19+
#include <rdma/ib_verbs.h>
1920

2021
MODULE_DESCRIPTION("RDMA Transport Server");
2122
MODULE_LICENSE("GPL");
@@ -31,6 +32,7 @@ MODULE_LICENSE("GPL");
3132
static struct rtrs_rdma_dev_pd dev_pd;
3233
static mempool_t *chunk_pool;
3334
struct class *rtrs_dev_class;
35+
static struct rtrs_srv_ib_ctx ib_ctx;
3436

3537
static int __read_mostly max_chunk_size = DEFAULT_MAX_CHUNK_SIZE;
3638
static int __read_mostly sess_queue_depth = DEFAULT_SESS_QUEUE_DEPTH;
@@ -2042,6 +2044,70 @@ static void free_srv_ctx(struct rtrs_srv_ctx *ctx)
20422044
kfree(ctx);
20432045
}
20442046

2047+
static int rtrs_srv_add_one(struct ib_device *device)
2048+
{
2049+
struct rtrs_srv_ctx *ctx;
2050+
int ret = 0;
2051+
2052+
mutex_lock(&ib_ctx.ib_dev_mutex);
2053+
if (ib_ctx.ib_dev_count)
2054+
goto out;
2055+
2056+
/*
2057+
* Since our CM IDs are NOT bound to any ib device we will create them
2058+
* only once
2059+
*/
2060+
ctx = ib_ctx.srv_ctx;
2061+
ret = rtrs_srv_rdma_init(ctx, ib_ctx.port);
2062+
if (ret) {
2063+
/*
2064+
* We errored out here.
2065+
* According to the ib code, if we encounter an error here then the
2066+
* error code is ignored, and no more calls to our ops are made.
2067+
*/
2068+
pr_err("Failed to initialize RDMA connection");
2069+
goto err_out;
2070+
}
2071+
2072+
out:
2073+
/*
2074+
* Keep a track on the number of ib devices added
2075+
*/
2076+
ib_ctx.ib_dev_count++;
2077+
2078+
err_out:
2079+
mutex_unlock(&ib_ctx.ib_dev_mutex);
2080+
return ret;
2081+
}
2082+
2083+
static void rtrs_srv_remove_one(struct ib_device *device, void *client_data)
2084+
{
2085+
struct rtrs_srv_ctx *ctx;
2086+
2087+
mutex_lock(&ib_ctx.ib_dev_mutex);
2088+
ib_ctx.ib_dev_count--;
2089+
2090+
if (ib_ctx.ib_dev_count)
2091+
goto out;
2092+
2093+
/*
2094+
* Since our CM IDs are NOT bound to any ib device we will remove them
2095+
* only once, when the last device is removed
2096+
*/
2097+
ctx = ib_ctx.srv_ctx;
2098+
rdma_destroy_id(ctx->cm_id_ip);
2099+
rdma_destroy_id(ctx->cm_id_ib);
2100+
2101+
out:
2102+
mutex_unlock(&ib_ctx.ib_dev_mutex);
2103+
}
2104+
2105+
static struct ib_client rtrs_srv_client = {
2106+
.name = "rtrs_server",
2107+
.add = rtrs_srv_add_one,
2108+
.remove = rtrs_srv_remove_one
2109+
};
2110+
20452111
/**
20462112
* rtrs_srv_open() - open RTRS server context
20472113
* @ops: callback functions
@@ -2060,7 +2126,11 @@ struct rtrs_srv_ctx *rtrs_srv_open(struct rtrs_srv_ops *ops, u16 port)
20602126
if (!ctx)
20612127
return ERR_PTR(-ENOMEM);
20622128

2063-
err = rtrs_srv_rdma_init(ctx, port);
2129+
mutex_init(&ib_ctx.ib_dev_mutex);
2130+
ib_ctx.srv_ctx = ctx;
2131+
ib_ctx.port = port;
2132+
2133+
err = ib_register_client(&rtrs_srv_client);
20642134
if (err) {
20652135
free_srv_ctx(ctx);
20662136
return ERR_PTR(err);
@@ -2099,8 +2169,8 @@ static void close_ctx(struct rtrs_srv_ctx *ctx)
20992169
*/
21002170
void rtrs_srv_close(struct rtrs_srv_ctx *ctx)
21012171
{
2102-
rdma_destroy_id(ctx->cm_id_ip);
2103-
rdma_destroy_id(ctx->cm_id_ib);
2172+
ib_unregister_client(&rtrs_srv_client);
2173+
mutex_destroy(&ib_ctx.ib_dev_mutex);
21042174
close_ctx(ctx);
21052175
free_srv_ctx(ctx);
21062176
}

drivers/infiniband/ulp/rtrs/rtrs-srv.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,13 @@ struct rtrs_srv_ctx {
118118
struct list_head srv_list;
119119
};
120120

121+
struct rtrs_srv_ib_ctx {
122+
struct rtrs_srv_ctx *srv_ctx;
123+
u16 port;
124+
struct mutex ib_dev_mutex;
125+
int ib_dev_count;
126+
};
127+
121128
extern struct class *rtrs_dev_class;
122129

123130
void close_sess(struct rtrs_srv_sess *sess);

0 commit comments

Comments
 (0)