Skip to content

Commit

Permalink
xprtrdma: Fix panic in rpcrdma_register_frmr_external()
Browse files Browse the repository at this point in the history
seg1->mr_nsegs is not yet initialized when it is used to unmap
segments during an error exit. Use the same unmapping logic for
all error exits.

"if (frmr_wr.wr.fast_reg.length < len) {" used to be a BUG_ON check.
The broken code will never be executed under normal operation.

Fixes: c977dea (xprtrdma: Remove BUG_ON() call sites)
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Tested-by: Steve Wise <swise@opengridcomputing.com>
Tested-by: Shirley Ma <shirley.ma@oracle.com>
Tested-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
  • Loading branch information
Chuck Lever authored and Anna Schumaker committed Jul 31, 2014
1 parent bf858ab commit 5fc83f4
Showing 1 changed file with 7 additions and 5 deletions.
12 changes: 7 additions & 5 deletions net/sunrpc/xprtrdma/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1548,9 +1548,8 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
frmr_wr.wr.fast_reg.length = page_no << PAGE_SHIFT;
if (frmr_wr.wr.fast_reg.length < len) {
while (seg1->mr_nsegs--)
rpcrdma_unmap_one(ia, seg++);
return -EIO;
rc = -EIO;
goto out_err;
}

/* Bump the key */
Expand All @@ -1568,15 +1567,18 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
if (rc) {
dprintk("RPC: %s: failed ib_post_send for register,"
" status %i\n", __func__, rc);
while (i--)
rpcrdma_unmap_one(ia, --seg);
goto out_err;
} else {
seg1->mr_rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey;
seg1->mr_base = seg1->mr_dma + pageoff;
seg1->mr_nsegs = i;
seg1->mr_len = len;
}
*nsegs = i;
return 0;
out_err:
while (i--)
rpcrdma_unmap_one(ia, --seg);
return rc;
}

Expand Down

0 comments on commit 5fc83f4

Please sign in to comment.