xprtrdma: Cache free MRs in each rpcrdma_req
Instead of a globally-contended MR free list, cache MRs in each rpcrdma_req as they are released. This means acquiring and releasing an MR will be lock-free in the common case, even outside the transport send lock. The original idea of per-rpcrdma_req MR free lists was suggested by Shirley Ma <shirley.ma@oracle.com> several years ago. I just now figured out how to make that idea work with on-demand MR allocation. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:

committed by
Anna Schumaker

parent
805a1f620b
commit
6dc6ec9e04
@@ -348,9 +348,14 @@ static struct rpcrdma_mr_seg *rpcrdma_mr_prepare(struct rpcrdma_xprt *r_xprt,
|
||||
int nsegs, bool writing,
|
||||
struct rpcrdma_mr **mr)
|
||||
{
|
||||
*mr = rpcrdma_mr_get(r_xprt);
|
||||
if (!*mr)
|
||||
goto out_getmr_err;
|
||||
*mr = rpcrdma_mr_pop(&req->rl_free_mrs);
|
||||
if (!*mr) {
|
||||
*mr = rpcrdma_mr_get(r_xprt);
|
||||
if (!*mr)
|
||||
goto out_getmr_err;
|
||||
trace_xprtrdma_mr_get(req);
|
||||
(*mr)->mr_req = req;
|
||||
}
|
||||
|
||||
rpcrdma_mr_push(*mr, &req->rl_registered);
|
||||
return frwr_map(r_xprt, seg, nsegs, writing, req->rl_slot.rq_xid, *mr);
|
||||
|
Reference in New Issue
Block a user