|
@@ -220,12 +220,12 @@ int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt,
|
|
{
|
|
{
|
|
struct ib_rdma_wr read_wr;
|
|
struct ib_rdma_wr read_wr;
|
|
struct ib_send_wr inv_wr;
|
|
struct ib_send_wr inv_wr;
|
|
- struct ib_fast_reg_wr fastreg_wr;
|
|
|
|
|
|
+ struct ib_reg_wr reg_wr;
|
|
u8 key;
|
|
u8 key;
|
|
- int pages_needed = PAGE_ALIGN(*page_offset + rs_length) >> PAGE_SHIFT;
|
|
|
|
|
|
+ int nents = PAGE_ALIGN(*page_offset + rs_length) >> PAGE_SHIFT;
|
|
struct svc_rdma_op_ctxt *ctxt = svc_rdma_get_context(xprt);
|
|
struct svc_rdma_op_ctxt *ctxt = svc_rdma_get_context(xprt);
|
|
struct svc_rdma_fastreg_mr *frmr = svc_rdma_get_frmr(xprt);
|
|
struct svc_rdma_fastreg_mr *frmr = svc_rdma_get_frmr(xprt);
|
|
- int ret, read, pno;
|
|
|
|
|
|
+ int ret, read, pno, dma_nents, n;
|
|
u32 pg_off = *page_offset;
|
|
u32 pg_off = *page_offset;
|
|
u32 pg_no = *page_no;
|
|
u32 pg_no = *page_no;
|
|
|
|
|
|
@@ -234,16 +234,14 @@ int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt,
|
|
|
|
|
|
ctxt->direction = DMA_FROM_DEVICE;
|
|
ctxt->direction = DMA_FROM_DEVICE;
|
|
ctxt->frmr = frmr;
|
|
ctxt->frmr = frmr;
|
|
- pages_needed = min_t(int, pages_needed, xprt->sc_frmr_pg_list_len);
|
|
|
|
- read = min_t(int, pages_needed << PAGE_SHIFT, rs_length);
|
|
|
|
|
|
+ nents = min_t(unsigned int, nents, xprt->sc_frmr_pg_list_len);
|
|
|
|
+ read = min_t(int, nents << PAGE_SHIFT, rs_length);
|
|
|
|
|
|
- frmr->kva = page_address(rqstp->rq_arg.pages[pg_no]);
|
|
|
|
frmr->direction = DMA_FROM_DEVICE;
|
|
frmr->direction = DMA_FROM_DEVICE;
|
|
frmr->access_flags = (IB_ACCESS_LOCAL_WRITE|IB_ACCESS_REMOTE_WRITE);
|
|
frmr->access_flags = (IB_ACCESS_LOCAL_WRITE|IB_ACCESS_REMOTE_WRITE);
|
|
- frmr->map_len = pages_needed << PAGE_SHIFT;
|
|
|
|
- frmr->page_list_len = pages_needed;
|
|
|
|
|
|
+ frmr->sg_nents = nents;
|
|
|
|
|
|
- for (pno = 0; pno < pages_needed; pno++) {
|
|
|
|
|
|
+ for (pno = 0; pno < nents; pno++) {
|
|
int len = min_t(int, rs_length, PAGE_SIZE - pg_off);
|
|
int len = min_t(int, rs_length, PAGE_SIZE - pg_off);
|
|
|
|
|
|
head->arg.pages[pg_no] = rqstp->rq_arg.pages[pg_no];
|
|
head->arg.pages[pg_no] = rqstp->rq_arg.pages[pg_no];
|
|
@@ -251,17 +249,12 @@ int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt,
|
|
head->arg.len += len;
|
|
head->arg.len += len;
|
|
if (!pg_off)
|
|
if (!pg_off)
|
|
head->count++;
|
|
head->count++;
|
|
|
|
+
|
|
|
|
+ sg_set_page(&frmr->sg[pno], rqstp->rq_arg.pages[pg_no],
|
|
|
|
+ len, pg_off);
|
|
|
|
+
|
|
rqstp->rq_respages = &rqstp->rq_arg.pages[pg_no+1];
|
|
rqstp->rq_respages = &rqstp->rq_arg.pages[pg_no+1];
|
|
rqstp->rq_next_page = rqstp->rq_respages + 1;
|
|
rqstp->rq_next_page = rqstp->rq_respages + 1;
|
|
- frmr->page_list->page_list[pno] =
|
|
|
|
- ib_dma_map_page(xprt->sc_cm_id->device,
|
|
|
|
- head->arg.pages[pg_no], 0,
|
|
|
|
- PAGE_SIZE, DMA_FROM_DEVICE);
|
|
|
|
- ret = ib_dma_mapping_error(xprt->sc_cm_id->device,
|
|
|
|
- frmr->page_list->page_list[pno]);
|
|
|
|
- if (ret)
|
|
|
|
- goto err;
|
|
|
|
- atomic_inc(&xprt->sc_dma_used);
|
|
|
|
|
|
|
|
/* adjust offset and wrap to next page if needed */
|
|
/* adjust offset and wrap to next page if needed */
|
|
pg_off += len;
|
|
pg_off += len;
|
|
@@ -277,28 +270,42 @@ int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt,
|
|
else
|
|
else
|
|
clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
|
|
clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
|
|
|
|
|
|
|
|
+ dma_nents = ib_dma_map_sg(xprt->sc_cm_id->device,
|
|
|
|
+ frmr->sg, frmr->sg_nents,
|
|
|
|
+ frmr->direction);
|
|
|
|
+ if (!dma_nents) {
|
|
|
|
+ pr_err("svcrdma: failed to dma map sg %p\n",
|
|
|
|
+ frmr->sg);
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ }
|
|
|
|
+ atomic_inc(&xprt->sc_dma_used);
|
|
|
|
+
|
|
|
|
+ n = ib_map_mr_sg(frmr->mr, frmr->sg, frmr->sg_nents, PAGE_SIZE);
|
|
|
|
+ if (unlikely(n != frmr->sg_nents)) {
|
|
|
|
+ pr_err("svcrdma: failed to map mr %p (%d/%d elements)\n",
|
|
|
|
+ frmr->mr, n, frmr->sg_nents);
|
|
|
|
+ return n < 0 ? n : -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* Bump the key */
|
|
/* Bump the key */
|
|
key = (u8)(frmr->mr->lkey & 0x000000FF);
|
|
key = (u8)(frmr->mr->lkey & 0x000000FF);
|
|
ib_update_fast_reg_key(frmr->mr, ++key);
|
|
ib_update_fast_reg_key(frmr->mr, ++key);
|
|
|
|
|
|
- ctxt->sge[0].addr = (unsigned long)frmr->kva + *page_offset;
|
|
|
|
|
|
+ ctxt->sge[0].addr = frmr->mr->iova;
|
|
ctxt->sge[0].lkey = frmr->mr->lkey;
|
|
ctxt->sge[0].lkey = frmr->mr->lkey;
|
|
- ctxt->sge[0].length = read;
|
|
|
|
|
|
+ ctxt->sge[0].length = frmr->mr->length;
|
|
ctxt->count = 1;
|
|
ctxt->count = 1;
|
|
ctxt->read_hdr = head;
|
|
ctxt->read_hdr = head;
|
|
|
|
|
|
- /* Prepare FASTREG WR */
|
|
|
|
- memset(&fastreg_wr, 0, sizeof(fastreg_wr));
|
|
|
|
- fastreg_wr.wr.opcode = IB_WR_FAST_REG_MR;
|
|
|
|
- fastreg_wr.wr.send_flags = IB_SEND_SIGNALED;
|
|
|
|
- fastreg_wr.iova_start = (unsigned long)frmr->kva;
|
|
|
|
- fastreg_wr.page_list = frmr->page_list;
|
|
|
|
- fastreg_wr.page_list_len = frmr->page_list_len;
|
|
|
|
- fastreg_wr.page_shift = PAGE_SHIFT;
|
|
|
|
- fastreg_wr.length = frmr->map_len;
|
|
|
|
- fastreg_wr.access_flags = frmr->access_flags;
|
|
|
|
- fastreg_wr.rkey = frmr->mr->lkey;
|
|
|
|
- fastreg_wr.wr.next = &read_wr.wr;
|
|
|
|
|
|
+ /* Prepare REG WR */
|
|
|
|
+ reg_wr.wr.opcode = IB_WR_REG_MR;
|
|
|
|
+ reg_wr.wr.wr_id = 0;
|
|
|
|
+ reg_wr.wr.send_flags = IB_SEND_SIGNALED;
|
|
|
|
+ reg_wr.wr.num_sge = 0;
|
|
|
|
+ reg_wr.mr = frmr->mr;
|
|
|
|
+ reg_wr.key = frmr->mr->lkey;
|
|
|
|
+ reg_wr.access = frmr->access_flags;
|
|
|
|
+ reg_wr.wr.next = &read_wr.wr;
|
|
|
|
|
|
/* Prepare RDMA_READ */
|
|
/* Prepare RDMA_READ */
|
|
memset(&read_wr, 0, sizeof(read_wr));
|
|
memset(&read_wr, 0, sizeof(read_wr));
|
|
@@ -324,7 +331,7 @@ int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt,
|
|
ctxt->wr_op = read_wr.wr.opcode;
|
|
ctxt->wr_op = read_wr.wr.opcode;
|
|
|
|
|
|
/* Post the chain */
|
|
/* Post the chain */
|
|
- ret = svc_rdma_send(xprt, &fastreg_wr.wr);
|
|
|
|
|
|
+ ret = svc_rdma_send(xprt, ®_wr.wr);
|
|
if (ret) {
|
|
if (ret) {
|
|
pr_err("svcrdma: Error %d posting RDMA_READ\n", ret);
|
|
pr_err("svcrdma: Error %d posting RDMA_READ\n", ret);
|
|
set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
|
|
set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
|
|
@@ -338,7 +345,8 @@ int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt,
|
|
atomic_inc(&rdma_stat_read);
|
|
atomic_inc(&rdma_stat_read);
|
|
return ret;
|
|
return ret;
|
|
err:
|
|
err:
|
|
- svc_rdma_unmap_dma(ctxt);
|
|
|
|
|
|
+ ib_dma_unmap_sg(xprt->sc_cm_id->device,
|
|
|
|
+ frmr->sg, frmr->sg_nents, frmr->direction);
|
|
svc_rdma_put_context(ctxt, 0);
|
|
svc_rdma_put_context(ctxt, 0);
|
|
svc_rdma_put_frmr(xprt, frmr);
|
|
svc_rdma_put_frmr(xprt, frmr);
|
|
return ret;
|
|
return ret;
|