diff --git a/fs/pipe.c b/fs/pipe.c index 2c7a23dde2d83f1ae18190e5723c0eb8d8ae0548..66aa0b938d6aca876bf2d246462c5fa2e3586e8b 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -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 --git a/include/linux/sched.h b/include/linux/sched.h index 8a1fcfe80fc722ff11c33d044ed195b9e05bc877..ac70f845b5b1d03d80c115bde4da3291485dfaad 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -114,6 +114,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 --git a/kernel/sched.c b/kernel/sched.c index 24eed372d2800d0658e237a282cf05815be80c87..6da13bba3e23c18add93ec275e904106dfdda2af 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1260,6 +1260,16 @@ static int try_to_wake_up(task_t *p, unsigned int state, int sync) p->activated = -1; } + /* + * 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) @@ -1268,7 +1278,6 @@ static int try_to_wake_up(task_t *p, unsigned int state, int sync) * 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);