9p/rdma: unmap receive dma buffer in rdma_request()/post_recv()

[ Upstream commit 74a25e6e91 ]

When down_interruptible() or ib_post_send() failed in rdma_request(),
receive dma buffer is not unmapped. Add unmap action to error path.
Also if ib_post_recv() failed in post_recv(), dma buffer is not unmapped.
Add unmap action to error path.

Link: https://lkml.kernel.org/r/20230104020424.611926-1-shaozhengchao@huawei.com
Fixes: fc79d4b104 ("9p: rdma: RDMA Transport Support for 9P")
Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Zhengchao Shao 2023-01-04 10:04:24 +08:00 committed by Greg Kroah-Hartman
parent 8d3fc907d0
commit 2721d96668

View File

@ -388,6 +388,7 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c)
struct p9_trans_rdma *rdma = client->trans;
struct ib_recv_wr wr;
struct ib_sge sge;
int ret;
c->busa = ib_dma_map_single(rdma->cm_id->device,
c->rc.sdata, client->msize,
@ -405,7 +406,12 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c)
wr.wr_cqe = &c->cqe;
wr.sg_list = &sge;
wr.num_sge = 1;
return ib_post_recv(rdma->qp, &wr, NULL);
ret = ib_post_recv(rdma->qp, &wr, NULL);
if (ret)
ib_dma_unmap_single(rdma->cm_id->device, c->busa,
client->msize, DMA_FROM_DEVICE);
return ret;
error:
p9_debug(P9_DEBUG_ERROR, "EIO\n");
@ -502,7 +508,7 @@ dont_need_post_recv:
if (down_interruptible(&rdma->sq_sem)) {
err = -EINTR;
goto send_error;
goto dma_unmap;
}
/* Mark request as `sent' *before* we actually send it,
@ -512,11 +518,14 @@ dont_need_post_recv:
req->status = REQ_STATUS_SENT;
err = ib_post_send(rdma->qp, &wr, NULL);
if (err)
goto send_error;
goto dma_unmap;
/* Success */
return 0;
dma_unmap:
ib_dma_unmap_single(rdma->cm_id->device, c->busa,
c->req->tc.size, DMA_TO_DEVICE);
/* Handle errors that happened during or while preparing the send: */
send_error:
req->status = REQ_STATUS_ERROR;