This patch addresses the adverse effect that the NFS client can have on
interactive response when CPU bound tasks (such as a kernel build)
operate on files mounted via NFS. (NB It is emphasized that this has
nothing to do with the effects of interactive tasks accessing NFS
mounted files themselves.)
The problem occurs because tasks accessing NFS mounted files for data
can undergo quite a lot of TASK_INTERRUPTIBLE sleep depending on the
load on the server and the quality of the network connection. This can
result in these tasks getting quite high values for sleep_avg and
consequently a large priority bonus. On the system where I noticed this
problem they were getting the full 10 bonus points and being given the
same dynamic priority as genuine interactive tasks such as the X server
and rythmbox.
The solution to this problem is to use TASK_NONINTERACTIVE to tell the
scheduler that the TASK_INTERRUPTIBLE sleeps in the NFS client and
SUNRPC are NOT interactive sleeps.
Signed-off-by: Peter Williams <[email protected]>
--
fs/nfs/inode.c | 3 ++-
fs/nfs/nfs4proc.c | 2 +-
fs/nfs/pagelist.c | 3 ++-
fs/nfs/write.c | 3 ++-
net/sunrpc/sched.c | 2 +-
net/sunrpc/svcsock.c | 2 +-
6 files changed, 9 insertions(+), 6 deletions(-)
--
Peter Williams [email protected]
"Learning, n. The kind of ignorance distinguishing the studious."
-- Ambrose Bierce
Index: GIT-warnings/fs/nfs/inode.c
===================================================================
--- GIT-warnings.orig/fs/nfs/inode.c 2005-12-21 16:22:09.000000000 +1100
+++ GIT-warnings/fs/nfs/inode.c 2005-12-21 16:22:11.000000000 +1100
@@ -937,7 +937,8 @@ static int nfs_wait_on_inode(struct inod
rpc_clnt_sigmask(clnt, &oldmask);
error = wait_on_bit_lock(&nfsi->flags, NFS_INO_REVALIDATING,
- nfs_wait_schedule, TASK_INTERRUPTIBLE);
+ nfs_wait_schedule,
+ TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
rpc_clnt_sigunmask(clnt, &oldmask);
return error;
Index: GIT-warnings/fs/nfs/nfs4proc.c
===================================================================
--- GIT-warnings.orig/fs/nfs/nfs4proc.c 2005-12-21 16:22:09.000000000 +1100
+++ GIT-warnings/fs/nfs/nfs4proc.c 2005-12-21 16:22:11.000000000 +1100
@@ -2547,7 +2547,7 @@ static int nfs4_wait_clnt_recover(struct
rpc_clnt_sigmask(clnt, &oldset);
interruptible = TASK_UNINTERRUPTIBLE;
if (clnt->cl_intr)
- interruptible = TASK_INTERRUPTIBLE;
+ interruptible = TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE;
prepare_to_wait(&clp->cl_waitq, &wait, interruptible);
nfs4_schedule_state_recovery(clp);
if (clnt->cl_intr && signalled())
Index: GIT-warnings/fs/nfs/pagelist.c
===================================================================
--- GIT-warnings.orig/fs/nfs/pagelist.c 2005-12-21 16:22:09.000000000 +1100
+++ GIT-warnings/fs/nfs/pagelist.c 2005-12-21 16:22:11.000000000 +1100
@@ -210,7 +210,8 @@ nfs_wait_on_request(struct nfs_page *req
*/
rpc_clnt_sigmask(clnt, &oldmask);
ret = out_of_line_wait_on_bit(&req->wb_flags, PG_BUSY,
- nfs_wait_bit_interruptible, TASK_INTERRUPTIBLE);
+ nfs_wait_bit_interruptible,
+ TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
rpc_clnt_sigunmask(clnt, &oldmask);
out:
return ret;
Index: GIT-warnings/fs/nfs/write.c
===================================================================
--- GIT-warnings.orig/fs/nfs/write.c 2005-12-21 16:22:09.000000000 +1100
+++ GIT-warnings/fs/nfs/write.c 2005-12-21 16:22:11.000000000 +1100
@@ -595,7 +595,8 @@ static int nfs_wait_on_write_congestion(
sigset_t oldset;
rpc_clnt_sigmask(clnt, &oldset);
- prepare_to_wait(&nfs_write_congestion, &wait, TASK_INTERRUPTIBLE);
+ prepare_to_wait(&nfs_write_congestion, &wait,
+ TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
if (bdi_write_congested(bdi)) {
if (signalled())
ret = -ERESTARTSYS;
Index: GIT-warnings/net/sunrpc/sched.c
===================================================================
--- GIT-warnings.orig/net/sunrpc/sched.c 2005-12-21 16:22:09.000000000 +1100
+++ GIT-warnings/net/sunrpc/sched.c 2005-12-21 16:22:11.000000000 +1100
@@ -659,7 +659,7 @@ static int __rpc_execute(struct rpc_task
/* Note: Caller should be using rpc_clnt_sigmask() */
status = out_of_line_wait_on_bit(&task->tk_runstate,
RPC_TASK_QUEUED, rpc_wait_bit_interruptible,
- TASK_INTERRUPTIBLE);
+ TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
if (status == -ERESTARTSYS) {
/*
* When a sync task receives a signal, it exits with
Index: GIT-warnings/net/sunrpc/svcsock.c
===================================================================
--- GIT-warnings.orig/net/sunrpc/svcsock.c 2005-12-21 16:22:09.000000000 +1100
+++ GIT-warnings/net/sunrpc/svcsock.c 2005-12-21 16:22:11.000000000 +1100
@@ -1213,7 +1213,7 @@ svc_recv(struct svc_serv *serv, struct s
* We have to be able to interrupt this wait
* to bring down the daemons ...
*/
- set_current_state(TASK_INTERRUPTIBLE);
+ set_current_state(TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
add_wait_queue(&rqstp->rq_wait, &wait);
spin_unlock_bh(&serv->sv_lock);
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]