aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorTom Tucker <tom@ogc.us>2012-02-20 14:07:57 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-03-21 09:31:47 -0400
commit9b78145c0f280d4f01c460d6251eab2584181fa9 (patch)
tree09f0f8b13541db68f23e73be122129a9ee4e4dcb /net/sunrpc
parent4a6862b3649d705bf41a36e3c7943d0322a9ee27 (diff)
xprtrdma: Remove assumption that each segment is <= PAGE_SIZE
The xprtrdma FRMR mapping logic assumes that a segment is <= PAGE_SIZE. This is not true for NFS4. Signed-off-by: Tom Tucker <tom@ogc.us> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/xprtrdma/verbs.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 28236bab57f9..745973b729af 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -1490,6 +1490,9 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
1490 u8 key; 1490 u8 key;
1491 int len, pageoff; 1491 int len, pageoff;
1492 int i, rc; 1492 int i, rc;
1493 int seg_len;
1494 u64 pa;
1495 int page_no;
1493 1496
1494 pageoff = offset_in_page(seg1->mr_offset); 1497 pageoff = offset_in_page(seg1->mr_offset);
1495 seg1->mr_offset -= pageoff; /* start of page */ 1498 seg1->mr_offset -= pageoff; /* start of page */
@@ -1497,11 +1500,15 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
1497 len = -pageoff; 1500 len = -pageoff;
1498 if (*nsegs > RPCRDMA_MAX_DATA_SEGS) 1501 if (*nsegs > RPCRDMA_MAX_DATA_SEGS)
1499 *nsegs = RPCRDMA_MAX_DATA_SEGS; 1502 *nsegs = RPCRDMA_MAX_DATA_SEGS;
1500 for (i = 0; i < *nsegs;) { 1503 for (page_no = i = 0; i < *nsegs;) {
1501 rpcrdma_map_one(ia, seg, writing); 1504 rpcrdma_map_one(ia, seg, writing);
1502 seg1->mr_chunk.rl_mw->r.frmr.fr_pgl->page_list[i] = seg->mr_dma; 1505 pa = seg->mr_dma;
1506 for (seg_len = seg->mr_len; seg_len > 0; seg_len -= PAGE_SIZE) {
1507 seg1->mr_chunk.rl_mw->r.frmr.fr_pgl->
1508 page_list[page_no++] = pa;
1509 pa += PAGE_SIZE;
1510 }
1503 len += seg->mr_len; 1511 len += seg->mr_len;
1504 BUG_ON(seg->mr_len > PAGE_SIZE);
1505 ++seg; 1512 ++seg;
1506 ++i; 1513 ++i;
1507 /* Check for holes */ 1514 /* Check for holes */
@@ -1540,9 +1547,9 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
1540 frmr_wr.send_flags = IB_SEND_SIGNALED; 1547 frmr_wr.send_flags = IB_SEND_SIGNALED;
1541 frmr_wr.wr.fast_reg.iova_start = seg1->mr_dma; 1548 frmr_wr.wr.fast_reg.iova_start = seg1->mr_dma;
1542 frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl; 1549 frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl;
1543 frmr_wr.wr.fast_reg.page_list_len = i; 1550 frmr_wr.wr.fast_reg.page_list_len = page_no;
1544 frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT; 1551 frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
1545 frmr_wr.wr.fast_reg.length = i << PAGE_SHIFT; 1552 frmr_wr.wr.fast_reg.length = page_no << PAGE_SHIFT;
1546 BUG_ON(frmr_wr.wr.fast_reg.length < len); 1553 BUG_ON(frmr_wr.wr.fast_reg.length < len);
1547 frmr_wr.wr.fast_reg.access_flags = (writing ? 1554 frmr_wr.wr.fast_reg.access_flags = (writing ?
1548 IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE : 1555 IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE :