Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72c02173 authored by Steve Wise's avatar Steve Wise Committed by Anna Schumaker
Browse files

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: default avatarSteve Wise <swise@opengridcomputing.com>
Tested-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent d0f36c46
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -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);
+6 −3
Original line number Original line Diff line number Diff line
@@ -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",