> On Feb 3, 2021, at 1:06 PM, Tom Talpey <tom@xxxxxxxxxx> wrote: > > On 2/3/2021 11:23 AM, Chuck Lever wrote: >> Support for FMR was removed by commit ba69cd122ece ("xprtrdma: >> Remove support for FMR memory registration") [Dec 2018]. That means >> the buffer-splitting behavior of rpcrdma_convert_kvec(), added by >> commit 821c791a0bde ("xprtrdma: Segment head and tail XDR buffers >> on page boundaries") [Mar 2016], is no longer necessary. FRWR >> memory registration handles this case with aplomb. >> Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx> >> --- >> net/sunrpc/xprtrdma/rpc_rdma.c | 19 ++++--------------- >> 1 file changed, 4 insertions(+), 15 deletions(-) >> diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c >> index 8f5d0cb68360..832765f3ebba 100644 >> --- a/net/sunrpc/xprtrdma/rpc_rdma.c >> +++ b/net/sunrpc/xprtrdma/rpc_rdma.c >> @@ -204,9 +204,7 @@ rpcrdma_alloc_sparse_pages(struct xdr_buf *buf) >> return 0; >> } >> -/* Split @vec on page boundaries into SGEs. FMR registers pages, not >> - * a byte range. Other modes coalesce these SGEs into a single MR >> - * when they can. >> +/* Convert @vec to a single SGL element. >> * >> * Returns pointer to next available SGE, and bumps the total number >> * of SGEs consumed. >> @@ -215,21 +213,12 @@ static struct rpcrdma_mr_seg * >> rpcrdma_convert_kvec(struct kvec *vec, struct rpcrdma_mr_seg *seg, >> unsigned int *n) >> { >> - u32 remaining, page_offset; >> - char *base; >> - >> - base = vec->iov_base; >> - page_offset = offset_in_page(base); >> - remaining = vec->iov_len; >> - while (remaining) { >> + if (vec->iov_len) { > > This is weird. Is it ever possible for a zero-length segment to be > passed? If so, it's obviously wrong to return an uninitialized "seg" > to the caller. I'd suggest simply asserting that iov_len is != 0. > > I guess this was an issue in the existing code, but there, it would > only trigger if *all* the segs were zero. It would be a bug if head.iov_len was zero. tail.iov_len is checked before the call. I think that means this check is superfluous and can be removed. > >> seg->mr_page = NULL; >> - seg->mr_offset = base; >> - seg->mr_len = min_t(u32, PAGE_SIZE - page_offset, remaining); >> - remaining -= seg->mr_len; >> - base += seg->mr_len; >> + seg->mr_offset = vec->iov_base; > > I thought the previous discussion was that this should be offset_in_page > not the (virtual) iov_base. Addressed in 3/6? > > Tom. > >> + seg->mr_len = vec->iov_len; >> ++seg; >> ++(*n); >> - page_offset = 0; >> } >> return seg; >> } -- Chuck Lever