[PATCH 08/16] SUNRPC: Avoid unnecessary copies in xdr_buf_pages_copy_left/right()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>

Moving data in the XDR page arrays can be expensive, since it can
involve touching up to a megabyte of data. Try to avoid doing so for the
case where the server returned less data than we preallocated.

Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
---
 net/sunrpc/xdr.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 7ca6208e7623..86a48c4cdcfc 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -600,14 +600,20 @@ static void xdr_buf_tail_shift_right(const struct xdr_buf *buf,
 static void xdr_buf_pages_shift_right(const struct xdr_buf *buf,
 				      unsigned int base, unsigned int shift)
 {
+	struct xdr_buf subbuf;
+
 	if (!shift)
 		return;
 	if (base >= buf->page_len) {
 		xdr_buf_tail_shift_right(buf, base - buf->page_len, shift);
 		return;
 	}
-	xdr_buf_tail_shift_right(buf, 0, shift);
-	xdr_buf_pages_copy_right(buf, base, shift);
+	base += buf->head->iov_len;
+	if (base >= buf->len)
+		return;
+	xdr_buf_subsegment(buf, &subbuf, base, buf->len - base);
+	xdr_buf_tail_shift_right(&subbuf, 0, shift);
+	xdr_buf_pages_copy_right(&subbuf, 0, shift);
 }
 
 static void xdr_buf_head_shift_right(const struct xdr_buf *buf,
@@ -710,14 +716,16 @@ static void xdr_buf_tail_shift_left(const struct xdr_buf *buf,
 static void xdr_buf_pages_shift_left(const struct xdr_buf *buf,
 				     unsigned int base, unsigned int shift)
 {
+	struct xdr_buf subbuf;
 	if (!shift)
 		return;
 	if (base >= buf->page_len) {
 		xdr_buf_tail_shift_left(buf, base - buf->page_len, shift);
 		return;
 	}
-	xdr_buf_pages_copy_left(buf, base, shift);
-	xdr_buf_tail_shift_left(buf, 0, shift);
+	xdr_buf_subsegment(buf, &subbuf, 0, buf->len);
+	xdr_buf_pages_copy_left(&subbuf, base, shift);
+	xdr_buf_tail_shift_left(&subbuf, 0, shift);
 }
 
 /**
-- 
2.29.2




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux