Skip to content

Commit d219fac

Browse files
krishna-ejgunthorpe
authored andcommitted
RDMA/iw_cxgb4: initiate CLOSE when entering TERM
As per draft-hilland-iwarp-verbs-v1.0, sec 6.2.3, always initiate a CLOSE when entering into TERM state. In c4iw_modify_qp(), disconnect operation should only be performed when the modify_qp call is invoked from ib_core. And all other internal modify_qp calls(invoked within iw_cxgb4) that needs 'disconnect' should call c4iw_ep_disconnect() explicitly after modify_qp. Otherwise, deadlocks like below can occur: Call Trace: schedule+0x2f/0xa0 schedule_preempt_disabled+0xa/0x10 __mutex_lock.isra.5+0x2d0/0x4a0 c4iw_ep_disconnect+0x39/0x430 => tries to reacquire ep lock again c4iw_modify_qp+0x468/0x10d0 rx_data+0x218/0x570 => acquires ep lock process_work+0x5f/0x70 process_one_work+0x1a7/0x3b0 worker_thread+0x30/0x390 kthread+0x112/0x130 ret_from_fork+0x35/0x40 Fixes: d2c3337 ("RDMA/iw_cxgb4: Always disconnect when QP is transitioning to TERMINATE state") Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Krishnamraju Eraparaju <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 10189e8 commit d219fac

File tree

2 files changed

+6
-2
lines changed

2 files changed

+6
-2
lines changed

drivers/infiniband/hw/cxgb4/cm.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3036,6 +3036,10 @@ static int terminate(struct c4iw_dev *dev, struct sk_buff *skb)
30363036
C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
30373037
}
30383038

3039+
/* As per draft-hilland-iwarp-verbs-v1.0, sec 6.2.3,
3040+
* when entering the TERM state the RNIC MUST initiate a CLOSE.
3041+
*/
3042+
c4iw_ep_disconnect(ep, 1, GFP_KERNEL);
30393043
c4iw_put_ep(&ep->com);
30403044
} else
30413045
pr_warn("TERM received tid %u no ep/qp\n", tid);

drivers/infiniband/hw/cxgb4/qp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1948,10 +1948,10 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
19481948
qhp->attr.layer_etype = attrs->layer_etype;
19491949
qhp->attr.ecode = attrs->ecode;
19501950
ep = qhp->ep;
1951-
c4iw_get_ep(&ep->com);
1952-
disconnect = 1;
19531951
if (!internal) {
1952+
c4iw_get_ep(&ep->com);
19541953
terminate = 1;
1954+
disconnect = 1;
19551955
} else {
19561956
terminate = qhp->attr.send_term;
19571957
ret = rdma_fini(rhp, qhp, ep);

0 commit comments

Comments
 (0)