9p/rdma: unmap receive dma buffer in rdma_request()/post_recv()
authorZhengchao Shao <shaozhengchao@huawei.com>
Wed, 4 Jan 2023 02:04:24 +0000 (10:04 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 11 Mar 2023 12:55:26 +0000 (13:55 +0100)
[ Upstream commit 74a25e6e916cb57dab4267a96fbe8864ed21abdb ]

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: fc79d4b104f0 ("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>
net/9p/trans_rdma.c

index e9a830c..29a9292 100644 (file)
@@ -386,6 +386,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,
@@ -403,7 +404,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");
@@ -500,7 +506,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,
@@ -510,11 +516,14 @@ dont_need_post_recv:
        WRITE_ONCE(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:
        WRITE_ONCE(req->status, REQ_STATUS_ERROR);