mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-13 16:50:05 +00:00
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>
This commit is contained in:
parent
4a6862b364
commit
9b78145c0f
@ -1490,6 +1490,9 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
|
|||||||
u8 key;
|
u8 key;
|
||||||
int len, pageoff;
|
int len, pageoff;
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
int seg_len;
|
||||||
|
u64 pa;
|
||||||
|
int page_no;
|
||||||
|
|
||||||
pageoff = offset_in_page(seg1->mr_offset);
|
pageoff = offset_in_page(seg1->mr_offset);
|
||||||
seg1->mr_offset -= pageoff; /* start of page */
|
seg1->mr_offset -= pageoff; /* start of page */
|
||||||
@ -1497,11 +1500,15 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
|
|||||||
len = -pageoff;
|
len = -pageoff;
|
||||||
if (*nsegs > RPCRDMA_MAX_DATA_SEGS)
|
if (*nsegs > RPCRDMA_MAX_DATA_SEGS)
|
||||||
*nsegs = RPCRDMA_MAX_DATA_SEGS;
|
*nsegs = RPCRDMA_MAX_DATA_SEGS;
|
||||||
for (i = 0; i < *nsegs;) {
|
for (page_no = i = 0; i < *nsegs;) {
|
||||||
rpcrdma_map_one(ia, seg, writing);
|
rpcrdma_map_one(ia, seg, writing);
|
||||||
seg1->mr_chunk.rl_mw->r.frmr.fr_pgl->page_list[i] = seg->mr_dma;
|
pa = seg->mr_dma;
|
||||||
|
for (seg_len = seg->mr_len; seg_len > 0; seg_len -= PAGE_SIZE) {
|
||||||
|
seg1->mr_chunk.rl_mw->r.frmr.fr_pgl->
|
||||||
|
page_list[page_no++] = pa;
|
||||||
|
pa += PAGE_SIZE;
|
||||||
|
}
|
||||||
len += seg->mr_len;
|
len += seg->mr_len;
|
||||||
BUG_ON(seg->mr_len > PAGE_SIZE);
|
|
||||||
++seg;
|
++seg;
|
||||||
++i;
|
++i;
|
||||||
/* Check for holes */
|
/* Check for holes */
|
||||||
@ -1540,9 +1547,9 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
|
|||||||
frmr_wr.send_flags = IB_SEND_SIGNALED;
|
frmr_wr.send_flags = IB_SEND_SIGNALED;
|
||||||
frmr_wr.wr.fast_reg.iova_start = seg1->mr_dma;
|
frmr_wr.wr.fast_reg.iova_start = seg1->mr_dma;
|
||||||
frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl;
|
frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl;
|
||||||
frmr_wr.wr.fast_reg.page_list_len = i;
|
frmr_wr.wr.fast_reg.page_list_len = page_no;
|
||||||
frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
|
frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
|
||||||
frmr_wr.wr.fast_reg.length = i << PAGE_SHIFT;
|
frmr_wr.wr.fast_reg.length = page_no << PAGE_SHIFT;
|
||||||
BUG_ON(frmr_wr.wr.fast_reg.length < len);
|
BUG_ON(frmr_wr.wr.fast_reg.length < len);
|
||||||
frmr_wr.wr.fast_reg.access_flags = (writing ?
|
frmr_wr.wr.fast_reg.access_flags = (writing ?
|
||||||
IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE :
|
IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE :
|
||||||
|
Loading…
x
Reference in New Issue
Block a user