xprtrdma: disconnect and flush cqs before freeing buffers
Otherwise a FRMR completion can cause a touch-after-free crash. In xprt_rdma_destroy(), call rpcrdma_buffer_destroy() only after calling rpcrdma_ep_destroy(). In rpcrdma_ep_destroy(), disconnect the cm_id first which should flush the qp, then drain the cqs, then destroy the qp, and finally destroy the cqs. Signed-off-by: Steve Wise <swise@opengridcomputing.com> Tested-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
Родитель
d0f36c46de
Коммит
72c0217382
|
@ -270,8 +270,8 @@ xprt_rdma_destroy(struct rpc_xprt *xprt)
|
||||||
|
|
||||||
xprt_clear_connected(xprt);
|
xprt_clear_connected(xprt);
|
||||||
|
|
||||||
rpcrdma_buffer_destroy(&r_xprt->rx_buf);
|
|
||||||
rpcrdma_ep_destroy(&r_xprt->rx_ep, &r_xprt->rx_ia);
|
rpcrdma_ep_destroy(&r_xprt->rx_ep, &r_xprt->rx_ia);
|
||||||
|
rpcrdma_buffer_destroy(&r_xprt->rx_buf);
|
||||||
rpcrdma_ia_close(&r_xprt->rx_ia);
|
rpcrdma_ia_close(&r_xprt->rx_ia);
|
||||||
|
|
||||||
xprt_rdma_free_addresses(xprt);
|
xprt_rdma_free_addresses(xprt);
|
||||||
|
|
|
@ -755,19 +755,22 @@ rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
|
||||||
|
|
||||||
cancel_delayed_work_sync(&ep->rep_connect_worker);
|
cancel_delayed_work_sync(&ep->rep_connect_worker);
|
||||||
|
|
||||||
if (ia->ri_id->qp) {
|
if (ia->ri_id->qp)
|
||||||
rpcrdma_ep_disconnect(ep, ia);
|
rpcrdma_ep_disconnect(ep, ia);
|
||||||
|
|
||||||
|
rpcrdma_clean_cq(ep->rep_attr.recv_cq);
|
||||||
|
rpcrdma_clean_cq(ep->rep_attr.send_cq);
|
||||||
|
|
||||||
|
if (ia->ri_id->qp) {
|
||||||
rdma_destroy_qp(ia->ri_id);
|
rdma_destroy_qp(ia->ri_id);
|
||||||
ia->ri_id->qp = NULL;
|
ia->ri_id->qp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcrdma_clean_cq(ep->rep_attr.recv_cq);
|
|
||||||
rc = ib_destroy_cq(ep->rep_attr.recv_cq);
|
rc = ib_destroy_cq(ep->rep_attr.recv_cq);
|
||||||
if (rc)
|
if (rc)
|
||||||
dprintk("RPC: %s: ib_destroy_cq returned %i\n",
|
dprintk("RPC: %s: ib_destroy_cq returned %i\n",
|
||||||
__func__, rc);
|
__func__, rc);
|
||||||
|
|
||||||
rpcrdma_clean_cq(ep->rep_attr.send_cq);
|
|
||||||
rc = ib_destroy_cq(ep->rep_attr.send_cq);
|
rc = ib_destroy_cq(ep->rep_attr.send_cq);
|
||||||
if (rc)
|
if (rc)
|
||||||
dprintk("RPC: %s: ib_destroy_cq returned %i\n",
|
dprintk("RPC: %s: ib_destroy_cq returned %i\n",
|
||||||
|
|
Загрузка…
Ссылка в новой задаче