diff -u --recursive --new-file linux-2.4.19-rpc_cong1/include/linux/sunrpc/xprt.h linux-2.4.19-rpc_cong2/include/linux/sunrpc/xprt.h --- linux-2.4.19-rpc_cong1/include/linux/sunrpc/xprt.h Thu Aug 1 11:14:36 2002 +++ linux-2.4.19-rpc_cong2/include/linux/sunrpc/xprt.h Thu Aug 1 11:15:09 2002 @@ -33,9 +33,9 @@ * MAXREQS value: At 32 outstanding reqs with 8 megs of RAM, fragment * reassembly will frequently run out of memory. */ -#define RPC_MAXCONG 16 -#define RPC_MAXREQS (RPC_MAXCONG + 1) -#define RPC_CWNDSCALE 256 +#define RPC_MAXCONG (16) +#define RPC_MAXREQS RPC_MAXCONG +#define RPC_CWNDSCALE (256) #define RPC_MAXCWND (RPC_MAXCONG * RPC_CWNDSCALE) #define RPC_INITCWND RPC_CWNDSCALE #define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd) @@ -121,7 +121,6 @@ unsigned long cong; /* current congestion */ unsigned long cwnd; /* congestion window */ - unsigned long congtime; /* hold cwnd until then */ struct rpc_wait_queue sending; /* requests waiting to send */ struct rpc_wait_queue pending; /* requests in flight */ diff -u --recursive --new-file linux-2.4.19-rpc_cong1/net/sunrpc/xprt.c linux-2.4.19-rpc_cong2/net/sunrpc/xprt.c --- linux-2.4.19-rpc_cong1/net/sunrpc/xprt.c Thu Aug 1 11:14:36 2002 +++ linux-2.4.19-rpc_cong2/net/sunrpc/xprt.c Thu Aug 1 11:16:33 2002 @@ -138,11 +138,12 @@ static int __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task) { - if (!xprt->snd_task) - xprt->snd_task = task; - else if (xprt->snd_task != task) { - dprintk("RPC: %4d TCP write queue full (task %d)\n", - task->tk_pid, xprt->snd_task->tk_pid); + if (!xprt->snd_task) { + if (xprt->nocong || __xprt_get_cong(xprt, task)) + xprt->snd_task = task; + } + if (xprt->snd_task != task) { + dprintk("RPC: %4d TCP write queue full\n", task->tk_pid); task->tk_timeout = 0; task->tk_status = -EAGAIN; rpc_sleep_on(&xprt->sending, task, NULL, NULL); @@ -167,10 +168,13 @@ if (xprt->snd_task) return; + if (!xprt->nocong && RPCXPRT_CONGESTED(xprt)) + return; task = rpc_wake_up_next(&xprt->sending); if (!task) return; - xprt->snd_task = task; + if (xprt->nocong || __xprt_get_cong(xprt, task)) + xprt->snd_task = task; } /* @@ -302,40 +306,22 @@ { unsigned long cwnd; - if (xprt->nocong) - return; - /* - * Note: we're in a BH context - */ - spin_lock(&xprt->xprt_lock); cwnd = xprt->cwnd; - if (result >= 0) { - if (xprt->cong < cwnd || time_before(jiffies, xprt->congtime)) - goto out; + if (result >= 0 && cwnd <= xprt->cong) { /* The (cwnd >> 1) term makes sure * the result gets rounded properly. */ cwnd += (RPC_CWNDSCALE * RPC_CWNDSCALE + (cwnd >> 1)) / cwnd; if (cwnd > RPC_MAXCWND) cwnd = RPC_MAXCWND; - else - pprintk("RPC: %lu %ld cwnd\n", jiffies, cwnd); - xprt->congtime = jiffies + ((cwnd * HZ) << 2) / RPC_CWNDSCALE; - dprintk("RPC: cong %08lx, cwnd was %08lx, now %08lx, " - "time %ld ms\n", xprt->cong, xprt->cwnd, cwnd, - (xprt->congtime-jiffies)*1000/HZ); + __xprt_lock_write_next(xprt); } else if (result == -ETIMEDOUT) { - if ((cwnd >>= 1) < RPC_CWNDSCALE) + cwnd >>= 1; + if (cwnd < RPC_CWNDSCALE) cwnd = RPC_CWNDSCALE; - xprt->congtime = jiffies + ((cwnd * HZ) << 3) / RPC_CWNDSCALE; - dprintk("RPC: cong %ld, cwnd was %ld, now %ld, " - "time %ld ms\n", xprt->cong, xprt->cwnd, cwnd, - (xprt->congtime-jiffies)*1000/HZ); - pprintk("RPC: %lu %ld cwnd\n", jiffies, cwnd); } - + dprintk("RPC: cong %ld, cwnd was %ld, now %ld\n", + xprt->cong, xprt->cwnd, cwnd); xprt->cwnd = cwnd; - out: - spin_unlock(&xprt->xprt_lock); } /* @@ -549,6 +535,7 @@ /* Adjust congestion window */ if (!xprt->nocong) { xprt_adjust_cwnd(xprt, copied); + __xprt_put_cong(xprt, req); if (!req->rq_nresend) { int timer = rpcproc_timer(clnt, task->tk_msg.rpc_proc); if (timer) @@ -1026,6 +1013,7 @@ } rpc_inc_timeo(&task->tk_client->cl_rtt); xprt_adjust_cwnd(req->rq_xprt, -ETIMEDOUT); + __xprt_put_cong(xprt, req); } req->rq_nresend++; @@ -1162,7 +1150,10 @@ req->rq_bytes_sent = 0; } out_release: - xprt_release_write(xprt, task); + spin_lock_bh(&xprt->sock_lock); + __xprt_release_write(xprt, task); + __xprt_put_cong(xprt, req); + spin_unlock_bh(&xprt->sock_lock); return; out_receive: dprintk("RPC: %4d xmit complete\n", task->tk_pid); @@ -1194,7 +1185,7 @@ if (task->tk_rqstp) return 0; - spin_lock_bh(&xprt->xprt_lock); + spin_lock(&xprt->xprt_lock); xprt_reserve_status(task); if (task->tk_rqstp) { task->tk_timeout = 0; @@ -1205,7 +1196,7 @@ task->tk_status = -EAGAIN; rpc_sleep_on(&xprt->backlog, task, NULL, NULL); } - spin_unlock_bh(&xprt->xprt_lock); + spin_unlock(&xprt->xprt_lock); dprintk("RPC: %4d xprt_reserve returns %d\n", task->tk_pid, task->tk_status); return task->tk_status; @@ -1229,17 +1220,11 @@ } else { if (!(req = xprt->free)) goto out_nofree; - if (!(xprt->nocong || __xprt_get_cong(xprt, req))) - goto out_nofree; - /* OK: There's room for us. Grab a free slot and bump - * congestion value */ + /* OK: There's room for us. Grab a free slot */ xprt->free = req->rq_next; req->rq_next = NULL; task->tk_rqstp = req; xprt_request_init(task, xprt); - - if (xprt->free) - xprt_clear_backlog(xprt); } return; @@ -1284,6 +1269,7 @@ return; spin_lock_bh(&xprt->sock_lock); __xprt_release_write(xprt, task); + __xprt_put_cong(xprt, req); if (!list_empty(&req->rq_list)) list_del(&req->rq_list); spin_unlock_bh(&xprt->sock_lock); @@ -1292,13 +1278,12 @@ dprintk("RPC: %4d release request %p\n", task->tk_pid, req); - spin_lock_bh(&xprt->xprt_lock); + spin_lock(&xprt->xprt_lock); req->rq_next = xprt->free; xprt->free = req; - __xprt_put_cong(xprt, req); xprt_clear_backlog(xprt); - spin_unlock_bh(&xprt->xprt_lock); + spin_unlock(&xprt->xprt_lock); } /* @@ -1354,7 +1339,6 @@ xprt->nocong = 1; } else xprt->cwnd = RPC_INITCWND; - xprt->congtime = jiffies; spin_lock_init(&xprt->sock_lock); spin_lock_init(&xprt->xprt_lock); init_waitqueue_head(&xprt->cong_wait); @@ -1513,8 +1497,6 @@ */ int xprt_clear_backlog(struct rpc_xprt *xprt) { - if (RPCXPRT_CONGESTED(xprt)) - return 0; rpc_wake_up_next(&xprt->backlog); if (waitqueue_active(&xprt->cong_wait)) wake_up(&xprt->cong_wait);