|
@@ -1858,8 +1858,8 @@ rpcrdma_free_regbuf(struct rpcrdma_ia *ia, struct rpcrdma_regbuf *rb)
|
|
|
* Wrappers for chunk registration, shared by read/write chunk code.
|
|
|
*/
|
|
|
|
|
|
-static void
|
|
|
-rpcrdma_map_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg, int writing)
|
|
|
+void
|
|
|
+rpcrdma_map_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg, bool writing)
|
|
|
{
|
|
|
seg->mr_dir = writing ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
|
|
seg->mr_dmalen = seg->mr_len;
|
|
@@ -1879,7 +1879,7 @@ rpcrdma_map_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg, int writing)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
+void
|
|
|
rpcrdma_unmap_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg)
|
|
|
{
|
|
|
if (seg->mr_page)
|
|
@@ -1890,89 +1890,6 @@ rpcrdma_unmap_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg)
|
|
|
seg->mr_dma, seg->mr_dmalen, seg->mr_dir);
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
|
|
|
- int *nsegs, int writing, struct rpcrdma_ia *ia,
|
|
|
- struct rpcrdma_xprt *r_xprt)
|
|
|
-{
|
|
|
- struct rpcrdma_mr_seg *seg1 = seg;
|
|
|
- struct rpcrdma_mw *mw = seg1->rl_mw;
|
|
|
- struct rpcrdma_frmr *frmr = &mw->r.frmr;
|
|
|
- struct ib_mr *mr = frmr->fr_mr;
|
|
|
- struct ib_send_wr fastreg_wr, *bad_wr;
|
|
|
- u8 key;
|
|
|
- int len, pageoff;
|
|
|
- int i, rc;
|
|
|
- int seg_len;
|
|
|
- u64 pa;
|
|
|
- int page_no;
|
|
|
-
|
|
|
- pageoff = offset_in_page(seg1->mr_offset);
|
|
|
- seg1->mr_offset -= pageoff; /* start of page */
|
|
|
- seg1->mr_len += pageoff;
|
|
|
- len = -pageoff;
|
|
|
- if (*nsegs > ia->ri_max_frmr_depth)
|
|
|
- *nsegs = ia->ri_max_frmr_depth;
|
|
|
- for (page_no = i = 0; i < *nsegs;) {
|
|
|
- rpcrdma_map_one(ia, seg, writing);
|
|
|
- pa = seg->mr_dma;
|
|
|
- for (seg_len = seg->mr_len; seg_len > 0; seg_len -= PAGE_SIZE) {
|
|
|
- frmr->fr_pgl->page_list[page_no++] = pa;
|
|
|
- pa += PAGE_SIZE;
|
|
|
- }
|
|
|
- len += seg->mr_len;
|
|
|
- ++seg;
|
|
|
- ++i;
|
|
|
- /* Check for holes */
|
|
|
- if ((i < *nsegs && offset_in_page(seg->mr_offset)) ||
|
|
|
- offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
|
|
|
- break;
|
|
|
- }
|
|
|
- dprintk("RPC: %s: Using frmr %p to map %d segments (%d bytes)\n",
|
|
|
- __func__, mw, i, len);
|
|
|
-
|
|
|
- frmr->fr_state = FRMR_IS_VALID;
|
|
|
-
|
|
|
- memset(&fastreg_wr, 0, sizeof(fastreg_wr));
|
|
|
- fastreg_wr.wr_id = (unsigned long)(void *)mw;
|
|
|
- fastreg_wr.opcode = IB_WR_FAST_REG_MR;
|
|
|
- fastreg_wr.wr.fast_reg.iova_start = seg1->mr_dma + pageoff;
|
|
|
- fastreg_wr.wr.fast_reg.page_list = frmr->fr_pgl;
|
|
|
- fastreg_wr.wr.fast_reg.page_list_len = page_no;
|
|
|
- fastreg_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
|
|
|
- fastreg_wr.wr.fast_reg.length = len;
|
|
|
-
|
|
|
- /* Bump the key */
|
|
|
- key = (u8)(mr->rkey & 0x000000FF);
|
|
|
- ib_update_fast_reg_key(mr, ++key);
|
|
|
-
|
|
|
- fastreg_wr.wr.fast_reg.access_flags = (writing ?
|
|
|
- IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE :
|
|
|
- IB_ACCESS_REMOTE_READ);
|
|
|
- fastreg_wr.wr.fast_reg.rkey = mr->rkey;
|
|
|
- DECR_CQCOUNT(&r_xprt->rx_ep);
|
|
|
-
|
|
|
- rc = ib_post_send(ia->ri_id->qp, &fastreg_wr, &bad_wr);
|
|
|
- if (rc) {
|
|
|
- dprintk("RPC: %s: failed ib_post_send for register,"
|
|
|
- " status %i\n", __func__, rc);
|
|
|
- ib_update_fast_reg_key(mr, --key);
|
|
|
- goto out_err;
|
|
|
- } else {
|
|
|
- seg1->mr_rkey = mr->rkey;
|
|
|
- seg1->mr_base = seg1->mr_dma + pageoff;
|
|
|
- seg1->mr_nsegs = i;
|
|
|
- seg1->mr_len = len;
|
|
|
- }
|
|
|
- *nsegs = i;
|
|
|
- return 0;
|
|
|
-out_err:
|
|
|
- frmr->fr_state = FRMR_IS_INVALID;
|
|
|
- while (i--)
|
|
|
- rpcrdma_unmap_one(ia, --seg);
|
|
|
- return rc;
|
|
|
-}
|
|
|
-
|
|
|
static int
|
|
|
rpcrdma_deregister_frmr_external(struct rpcrdma_mr_seg *seg,
|
|
|
struct rpcrdma_ia *ia, struct rpcrdma_xprt *r_xprt)
|
|
@@ -2003,49 +1920,6 @@ rpcrdma_deregister_frmr_external(struct rpcrdma_mr_seg *seg,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-rpcrdma_register_fmr_external(struct rpcrdma_mr_seg *seg,
|
|
|
- int *nsegs, int writing, struct rpcrdma_ia *ia)
|
|
|
-{
|
|
|
- struct rpcrdma_mr_seg *seg1 = seg;
|
|
|
- u64 physaddrs[RPCRDMA_MAX_DATA_SEGS];
|
|
|
- int len, pageoff, i, rc;
|
|
|
-
|
|
|
- pageoff = offset_in_page(seg1->mr_offset);
|
|
|
- seg1->mr_offset -= pageoff; /* start of page */
|
|
|
- seg1->mr_len += pageoff;
|
|
|
- len = -pageoff;
|
|
|
- if (*nsegs > RPCRDMA_MAX_DATA_SEGS)
|
|
|
- *nsegs = RPCRDMA_MAX_DATA_SEGS;
|
|
|
- for (i = 0; i < *nsegs;) {
|
|
|
- rpcrdma_map_one(ia, seg, writing);
|
|
|
- physaddrs[i] = seg->mr_dma;
|
|
|
- len += seg->mr_len;
|
|
|
- ++seg;
|
|
|
- ++i;
|
|
|
- /* Check for holes */
|
|
|
- if ((i < *nsegs && offset_in_page(seg->mr_offset)) ||
|
|
|
- offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
|
|
|
- break;
|
|
|
- }
|
|
|
- rc = ib_map_phys_fmr(seg1->rl_mw->r.fmr, physaddrs, i, seg1->mr_dma);
|
|
|
- if (rc) {
|
|
|
- dprintk("RPC: %s: failed ib_map_phys_fmr "
|
|
|
- "%u@0x%llx+%i (%d)... status %i\n", __func__,
|
|
|
- len, (unsigned long long)seg1->mr_dma,
|
|
|
- pageoff, i, rc);
|
|
|
- while (i--)
|
|
|
- rpcrdma_unmap_one(ia, --seg);
|
|
|
- } else {
|
|
|
- seg1->mr_rkey = seg1->rl_mw->r.fmr->rkey;
|
|
|
- seg1->mr_base = seg1->mr_dma + pageoff;
|
|
|
- seg1->mr_nsegs = i;
|
|
|
- seg1->mr_len = len;
|
|
|
- }
|
|
|
- *nsegs = i;
|
|
|
- return rc;
|
|
|
-}
|
|
|
-
|
|
|
static int
|
|
|
rpcrdma_deregister_fmr_external(struct rpcrdma_mr_seg *seg,
|
|
|
struct rpcrdma_ia *ia)
|
|
@@ -2066,42 +1940,6 @@ rpcrdma_deregister_fmr_external(struct rpcrdma_mr_seg *seg,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-int
|
|
|
-rpcrdma_register_external(struct rpcrdma_mr_seg *seg,
|
|
|
- int nsegs, int writing, struct rpcrdma_xprt *r_xprt)
|
|
|
-{
|
|
|
- struct rpcrdma_ia *ia = &r_xprt->rx_ia;
|
|
|
- int rc = 0;
|
|
|
-
|
|
|
- switch (ia->ri_memreg_strategy) {
|
|
|
-
|
|
|
- case RPCRDMA_ALLPHYSICAL:
|
|
|
- rpcrdma_map_one(ia, seg, writing);
|
|
|
- seg->mr_rkey = ia->ri_bind_mem->rkey;
|
|
|
- seg->mr_base = seg->mr_dma;
|
|
|
- seg->mr_nsegs = 1;
|
|
|
- nsegs = 1;
|
|
|
- break;
|
|
|
-
|
|
|
- /* Registration using frmr registration */
|
|
|
- case RPCRDMA_FRMR:
|
|
|
- rc = rpcrdma_register_frmr_external(seg, &nsegs, writing, ia, r_xprt);
|
|
|
- break;
|
|
|
-
|
|
|
- /* Registration using fmr memory registration */
|
|
|
- case RPCRDMA_MTHCAFMR:
|
|
|
- rc = rpcrdma_register_fmr_external(seg, &nsegs, writing, ia);
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
-
|
|
|
- return nsegs;
|
|
|
-}
|
|
|
-
|
|
|
int
|
|
|
rpcrdma_deregister_external(struct rpcrdma_mr_seg *seg,
|
|
|
struct rpcrdma_xprt *r_xprt)
|