Skip to content

Commit 092d303

Browse files
Ajaykumar HotchandaniLinuxMinion
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 Acked-by: Santosh Shilimkar <[email protected]> Signed-off-by: Ajaykumar Hotchandani <[email protected]>
1 parent bb8811d commit 092d303

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
@@ -406,6 +406,11 @@ struct rds_ib_conn_drop_work {
406406
struct rds_connection *conn;
407407
};
408408

409+
struct rds_ib_conn_destroy_work {
410+
struct delayed_work work;
411+
struct rds_connection *conn;
412+
};
413+
409414
struct rds_ib_addr_change_work {
410415
struct delayed_work work;
411416
__be32 addr;
@@ -581,6 +586,7 @@ int rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id);
581586
void rds_ib_cm_connect_complete(struct rds_connection *conn,
582587
struct rdma_cm_event *event);
583588
void rds_ib_init_frag(unsigned int version);
589+
void rds_ib_conn_destroy_init(struct rds_connection *conn);
584590

585591
#define rds_ib_conn_error(conn, fmt...) \
586592
__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
@@ -220,17 +220,13 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
220220

221221
if (conn->c_version < RDS_PROTOCOL_VERSION) {
222222
if (conn->c_version != RDS_PROTOCOL_COMPAT_VERSION) {
223-
/*
224-
* BUG: destroying connection here can deadlock with
225-
* the CM event handler on the c_cm_lock.
226-
*/
227223
printk(KERN_NOTICE "RDS/IB: Connection to"
228224
" %u.%u.%u.%u version %u.%u failed,"
229225
" no longer supported\n",
230226
NIPQUAD(conn->c_faddr),
231227
RDS_PROTOCOL_MAJOR(conn->c_version),
232228
RDS_PROTOCOL_MINOR(conn->c_version));
233-
rds_conn_destroy(conn);
229+
rds_ib_conn_destroy_init(conn);
234230
return;
235231
}
236232
}
@@ -989,6 +985,31 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
989985
return destroy;
990986
}
991987

988+
void rds_ib_conn_destroy_worker(struct work_struct *_work)
989+
{
990+
struct rds_ib_conn_destroy_work *work =
991+
container_of(_work, struct rds_ib_conn_destroy_work, work.work);
992+
struct rds_connection *conn = work->conn;
993+
994+
rds_conn_destroy(conn);
995+
996+
kfree(work);
997+
}
998+
999+
void rds_ib_conn_destroy_init(struct rds_connection *conn)
1000+
{
1001+
struct rds_ib_conn_destroy_work *work;
1002+
1003+
work = kzalloc(sizeof *work, GFP_ATOMIC);
1004+
if (!work) {
1005+
pr_err("RDS/IB: failed to allocate connection destroy work\n");
1006+
return;
1007+
}
1008+
1009+
work->conn = conn;
1010+
INIT_DELAYED_WORK(&work->work, rds_ib_conn_destroy_worker);
1011+
queue_delayed_work(rds_aux_wq, &work->work, 0);
1012+
}
9921013

9931014
int rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id)
9941015
{

0 commit comments

Comments
 (0)