diff options
author | Tom Tucker <tom@ogc.us> | 2012-02-20 14:07:57 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-21 09:31:47 -0400 |
commit | 9b78145c0f280d4f01c460d6251eab2584181fa9 (patch) | |
tree | 09f0f8b13541db68f23e73be122129a9ee4e4dcb /net/sunrpc/xprtrdma | |
parent | 4a6862b3649d705bf41a36e3c7943d0322a9ee27 (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/xprtrdma')
-rw-r--r-- | net/sunrpc/xprtrdma/verbs.c | 17 |
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 : |