Skip to content

Commit 427de26

Browse files
Ajaykumar HotchandaniSomasundaram Krishnasamy
authored andcommitted
RDS: IB: invoke connection destruction in worker
This is to avoid deadlock with c_cm_lock mutex. In event handling path of Infiniband, whenever connection destruction is required; we should invoke worker in order to avoid deadlock with mutex. Orabug: 23222944 Signed-off-by: Ajaykumar Hotchandani <[email protected]> Acked-by: Santosh Shilimkar <[email protected]> Orabug: 27364391 (cherry picked from commit 092d303) cherry-pick-repo=linux-uek.git Signed-off-by: Gerd Rausch <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent b9e4f8d commit 427de26

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

net/rds/ib.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,11 @@ struct rds_ib_conn_drop_work {
410410
struct rds_connection *conn;
411411
};
412412

413+
struct rds_ib_conn_destroy_work {
414+
struct delayed_work work;
415+
struct rds_connection *conn;
416+
};
417+
413418
struct rds_ib_addr_change_work {
414419
struct delayed_work work;
415420
__be32 addr;
@@ -585,6 +590,7 @@ int rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id);
585590
void rds_ib_cm_connect_complete(struct rds_connection *conn,
586591
struct rdma_cm_event *event);
587592
void rds_ib_init_frag(unsigned int version);
593+
void rds_ib_conn_destroy_init(struct rds_connection *conn);
588594

589595
#define rds_ib_conn_error(conn, fmt...) \
590596
__rds_ib_conn_error(conn, KERN_WARNING "RDS/IB: " fmt)

net/rds/ib_cm.c

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,17 +221,13 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
221221

222222
if (conn->c_version < RDS_PROTOCOL_VERSION) {
223223
if (conn->c_version != RDS_PROTOCOL_COMPAT_VERSION) {
224-
/*
225-
* BUG: destroying connection here can deadlock with
226-
* the CM event handler on the c_cm_lock.
227-
*/
228224
printk(KERN_NOTICE "RDS/IB: Connection to"
229225
" %pI4 version %u.%u failed,"
230226
" no longer supported\n",
231227
&conn->c_faddr,
232228
RDS_PROTOCOL_MAJOR(conn->c_version),
233229
RDS_PROTOCOL_MINOR(conn->c_version));
234-
rds_conn_destroy(conn);
230+
rds_ib_conn_destroy_init(conn);
235231
return;
236232
}
237233
}
@@ -997,6 +993,31 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
997993
return destroy;
998994
}
999995

996+
void rds_ib_conn_destroy_worker(struct work_struct *_work)
997+
{
998+
struct rds_ib_conn_destroy_work *work =
999+
container_of(_work, struct rds_ib_conn_destroy_work, work.work);
1000+
struct rds_connection *conn = work->conn;
1001+
1002+
rds_conn_destroy(conn);
1003+
1004+
kfree(work);
1005+
}
1006+
1007+
void rds_ib_conn_destroy_init(struct rds_connection *conn)
1008+
{
1009+
struct rds_ib_conn_destroy_work *work;
1010+
1011+
work = kzalloc(sizeof *work, GFP_ATOMIC);
1012+
if (!work) {
1013+
pr_err("RDS/IB: failed to allocate connection destroy work\n");
1014+
return;
1015+
}
1016+
1017+
work->conn = conn;
1018+
INIT_DELAYED_WORK(&work->work, rds_ib_conn_destroy_worker);
1019+
queue_delayed_work(rds_aux_wq, &work->work, 0);
1020+
}
10001021

10011022
int rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id)
10021023
{

0 commit comments

Comments
 (0)