Skip to content

Commit 394b2c7

Browse files
chuckleveramschuma-ntap
authored andcommitted
xprtrdma: Fix error handling in rpcrdma_prepare_msg_sges()
When this function fails, it needs to undo the DMA mappings it's done so far. Otherwise these are leaked. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent ad99f05 commit 394b2c7

File tree

1 file changed

+24
-14
lines changed

1 file changed

+24
-14
lines changed

net/sunrpc/xprtrdma/rpc_rdma.c

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,28 @@ rpcrdma_encode_reply_chunk(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
511511
return 0;
512512
}
513513

514+
/**
515+
* rpcrdma_unmap_sges - DMA-unmap Send buffers
516+
* @ia: interface adapter (device)
517+
* @req: req with possibly some SGEs to be DMA unmapped
518+
*
519+
*/
520+
void
521+
rpcrdma_unmap_sges(struct rpcrdma_ia *ia, struct rpcrdma_req *req)
522+
{
523+
struct ib_sge *sge;
524+
unsigned int count;
525+
526+
/* The first two SGEs contain the transport header and
527+
* the inline buffer. These are always left mapped so
528+
* they can be cheaply re-used.
529+
*/
530+
sge = &req->rl_send_sge[2];
531+
for (count = req->rl_mapped_sges; count--; sge++)
532+
ib_dma_unmap_page(ia->ri_device,
533+
sge->addr, sge->length, DMA_TO_DEVICE);
534+
}
535+
514536
/* Prepare the RPC-over-RDMA header SGE.
515537
*/
516538
static bool
@@ -641,10 +663,12 @@ rpcrdma_prepare_msg_sges(struct rpcrdma_ia *ia, struct rpcrdma_req *req,
641663
return true;
642664

643665
out_mapping_overflow:
666+
rpcrdma_unmap_sges(ia, req);
644667
pr_err("rpcrdma: too many Send SGEs (%u)\n", sge_no);
645668
return false;
646669

647670
out_mapping_err:
671+
rpcrdma_unmap_sges(ia, req);
648672
pr_err("rpcrdma: Send mapping error\n");
649673
return false;
650674
}
@@ -671,20 +695,6 @@ rpcrdma_prepare_send_sges(struct rpcrdma_ia *ia, struct rpcrdma_req *req,
671695
return false;
672696
}
673697

674-
void
675-
rpcrdma_unmap_sges(struct rpcrdma_ia *ia, struct rpcrdma_req *req)
676-
{
677-
struct ib_device *device = ia->ri_device;
678-
struct ib_sge *sge;
679-
int count;
680-
681-
sge = &req->rl_send_sge[2];
682-
for (count = req->rl_mapped_sges; count--; sge++)
683-
ib_dma_unmap_page(device, sge->addr, sge->length,
684-
DMA_TO_DEVICE);
685-
req->rl_mapped_sges = 0;
686-
}
687-
688698
/**
689699
* rpcrdma_marshal_req - Marshal and send one RPC request
690700
* @r_xprt: controlling transport

0 commit comments

Comments
 (0)