From: Ingo Molnar This patch implements a task state bit (TASK_NONINTERACTIVE), which can be used by blocking points to mark the task's wait as "non-interactive". This does not mean the task will be considered a CPU-hog - the wait will simply not have an effect on the waiting task's priority - positive or negative alike. Right now only pipe_wait() will make use of it, because it's a common source of not-so-interactive waits (kernel compilation jobs, etc.). Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton --- fs/pipe.c | 6 +++++- include/linux/sched.h | 1 + kernel/sched.c | 11 ++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff -puN fs/pipe.c~sched-task_noninteractive fs/pipe.c --- 25/fs/pipe.c~sched-task_noninteractive 2005-06-21 00:47:37.000000000 -0700 +++ 25-akpm/fs/pipe.c 2005-06-21 00:47:37.000000000 -0700 @@ -39,7 +39,11 @@ void pipe_wait(struct inode * inode) { DEFINE_WAIT(wait); - prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE); + /* + * Pipes are system-local resources, so sleeping on them + * is considered a noninteractive wait: + */ + prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE); up(PIPE_SEM(*inode)); schedule(); finish_wait(PIPE_WAIT(*inode), &wait); diff -puN include/linux/sched.h~sched-task_noninteractive include/linux/sched.h --- 25/include/linux/sched.h~sched-task_noninteractive 2005-06-21 00:47:37.000000000 -0700 +++ 25-akpm/include/linux/sched.h 2005-06-21 00:47:37.000000000 -0700 @@ -112,6 +112,7 @@ extern unsigned long nr_iowait(void); #define TASK_TRACED 8 #define EXIT_ZOMBIE 16 #define EXIT_DEAD 32 +#define TASK_NONINTERACTIVE 64 #define __set_task_state(tsk, state_value) \ do { (tsk)->state = (state_value); } while (0) diff -puN kernel/sched.c~sched-task_noninteractive kernel/sched.c --- 25/kernel/sched.c~sched-task_noninteractive 2005-06-21 00:47:37.000000000 -0700 +++ 25-akpm/kernel/sched.c 2005-06-21 00:47:37.000000000 -0700 @@ -1262,6 +1262,16 @@ out_activate: } /* + * Tasks that have marked their sleep as noninteractive get + * woken up without updating their sleep average. (i.e. their + * sleep is handled in a priority-neutral manner, no priority + * boost and no penalty.) + */ + if (old_state & TASK_NONINTERACTIVE) + __activate_task(p, rq); + else + activate_task(p, rq, cpu == this_cpu); + /* * Sync wakeups (i.e. those types of wakeups where the waker * has indicated that it will leave the CPU in short order) * don't trigger a preemption, if the woken up task will run on @@ -1269,7 +1279,6 @@ out_activate: * the waker guarantees that the freshly woken up task is going * to be considered on this CPU.) */ - activate_task(p, rq, cpu == this_cpu); if (!sync || cpu != this_cpu) { if (TASK_PREEMPTS_CURR(p, rq)) resched_task(rq->curr); _