Increasing the server wsize/rsize

Neil Brown neilb at suse.de
Thu Aug 3 03:23:26 EDT 2006


On Wednesday August 2, bfields at fieldses.org wrote:
> On Fri, Jul 28, 2006 at 07:34:43PM -0400, Dean Hildebrand wrote:
> > Thanks for the updates Greg.  One issue I've found is that if we want to 
> > go larger than 1MB, we still need to fix svc_tcp_recvfrom to use the 
> > heap instead of the stack.
> 
> Even with only 1MB, we're still putting a 1k array on the stack in that
> one function, which seems like a problem.
> 

But do we really need to scale the 'vec' array at all?
Why not just call svc_recvfrom multiple times.
We have exclusive access to read from the socket at this point so I
cannot see room for a race.

Something like this maybe? 
(Very rough-and-ready, haven't even compile tested, probably lots of
things you can tidyup..)

NeilBrown


Signed-off-by: Neil Brown <neilb at suse.de>

### Diffstat output
 ./net/sunrpc/svcsock.c |   36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-08-03 11:23:44.000000000 +1000
+++ ./net/sunrpc/svcsock.c	2006-08-03 17:22:13.000000000 +1000
@@ -958,7 +958,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
 	struct svc_sock	*svsk = rqstp->rq_sock;
 	struct svc_serv	*serv = svsk->sk_server;
 	int		len;
-	struct kvec vec[RPCSVC_MAXPAGES];
+	struct kvec vec[16];
 	int pnum, vlen;
 
 	dprintk("svc: tcp_recv %p data %d conn %d close %d\n",
@@ -1059,20 +1059,32 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
 	vec[0] = rqstp->rq_arg.head[0];
 	vlen = PAGE_SIZE;
 	pnum = 1;
-	while (vlen < len) {
-		vec[pnum].iov_base = page_address(rqstp->rq_argpages[rqstp->rq_argused++]);
-		vec[pnum].iov_len = PAGE_SIZE;
-		pnum++;
-		vlen += PAGE_SIZE;
-	}
 
-	/* Now receive data */
-	len = svc_recvfrom(rqstp, vec, pnum, len);
-	if (len < 0)
-		goto error;
+	rqstp->rq_arg.len = len;
+	while (len) {
+		int rlen;
+		while (vlen < len && pnum < ARRAY_SIZE(vec)) {
+			vec[pnum].iov_base = 
+				page_address(rqstp->
+					     rq_argpages[rqstp->rq_argused++]);
+			vec[pnum].iov_len = PAGE_SIZE;
+			pnum++;
+			vlen += PAGE_SIZE;
+		}
+		if (vlen > len)
+			vlen = len;
+		rlen = svc_recvfrom(rqstp, vec, pnum, vlen);
+		if (rlen != vlen) {
+			len = rlen;
+			goto error;
+		}
+		len -= rlen;
+		pnum = 0;
+		vlen = 0;
+	}
 
+	len = rqstp->rq_arg.len;
 	dprintk("svc: TCP complete record (%d bytes)\n", len);
-	rqstp->rq_arg.len = len;
 	rqstp->rq_arg.page_base = 0;
 	if (len <= rqstp->rq_arg.head[0].iov_len) {
 		rqstp->rq_arg.head[0].iov_len = len;


More information about the NFSv4 mailing list