include/linux/sunrpc/timer.h | 11 ++++++++++- net/sunrpc/sched.c | 23 ++++++++++++++--------- 2 files changed, 24 insertions(+), 10 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.3-07-XID/include/linux/sunrpc/timer.h linux-2.6.3-08-rpc_fixes/include/linux/sunrpc/timer.h --- linux-2.6.3-07-XID/include/linux/sunrpc/timer.h 2004-02-27 12:44:41.000000000 -0800 +++ linux-2.6.3-08-rpc_fixes/include/linux/sunrpc/timer.h 2004-02-27 19:12:33.000000000 -0800 @@ -25,9 +25,18 @@ extern unsigned long rpc_calc_rto(struct static inline void rpc_set_timeo(struct rpc_rtt *rt, int timer, int ntimeo) { + int *t; if (!timer) return; - rt->ntimeouts[timer-1] = ntimeo; + t = &rt->ntimeouts[timer-1]; + if (ntimeo < *t) { + if (*t > 0) + (*t)--; + } else { + if (ntimeo > 8) + ntimeo = 8; + *t = ntimeo; + } } static inline int rpc_ntimeo(struct rpc_rtt *rt, int timer) diff -u --recursive --new-file --show-c-function linux-2.6.3-07-XID/net/sunrpc/sched.c linux-2.6.3-08-rpc_fixes/net/sunrpc/sched.c --- linux-2.6.3-07-XID/net/sunrpc/sched.c 2004-02-27 12:43:48.000000000 -0800 +++ linux-2.6.3-08-rpc_fixes/net/sunrpc/sched.c 2004-02-27 19:10:39.000000000 -0800 @@ -530,6 +530,9 @@ __rpc_execute(struct rpc_task *task) if (!task->tk_action) break; task->tk_action(task); + /* micro-optimization to avoid spinlock */ + if (RPC_IS_RUNNING(task)) + continue; } /* @@ -545,29 +548,31 @@ __rpc_execute(struct rpc_task *task) } spin_unlock_bh(&rpc_queue_lock); - while (RPC_IS_SLEEPING(task)) { - /* sync task: sleep here */ - dprintk("RPC: %4d sync task going to sleep\n", - task->tk_pid); - if (current->pid == rpciod_pid) - printk(KERN_ERR "RPC: rpciod waiting on sync task!\n"); + if (!RPC_IS_SLEEPING(task)) + continue; + /* sync task: sleep here */ + dprintk("RPC: %4d sync task going to sleep\n", task->tk_pid); + if (current->pid == rpciod_pid) + printk(KERN_ERR "RPC: rpciod waiting on sync task!\n"); + if (!task->tk_client->cl_intr) { __wait_event(task->tk_wait, !RPC_IS_SLEEPING(task)); - dprintk("RPC: %4d sync task resuming\n", task->tk_pid); - + } else { + __wait_event_interruptible(task->tk_wait, !RPC_IS_SLEEPING(task), status); /* * When a sync task receives a signal, it exits with * -ERESTARTSYS. In order to catch any callbacks that * clean up after sleeping on some queue, we don't * break the loop here, but go around once more. */ - if (task->tk_client->cl_intr && signalled()) { + if (status == -ERESTARTSYS) { dprintk("RPC: %4d got signal\n", task->tk_pid); task->tk_flags |= RPC_TASK_KILLED; rpc_exit(task, -ERESTARTSYS); rpc_wake_up_task(task); } } + dprintk("RPC: %4d sync task resuming\n", task->tk_pid); } if (task->tk_exit) {