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