aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCon Kolivas <kernel@kolivas.org>2006-06-27 05:54:30 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-27 20:32:44 -0400
commit72d2854d4ebf5faf086ebccb2ed575c6b68a05dc (patch)
tree2a0b00a32a810b76ff29bde7d269998561408f8b
parentd444886e149a8413159da8b43ada2bc287e69b0c (diff)
[PATCH] sched: fix interactive ceiling code
The relationship between INTERACTIVE_SLEEP and the ceiling is not perfect and not explicit enough. The sleep boost is not supposed to be any larger than without this code and the comment is not clear enough about what exactly it does, just the reason it does it. Fix it. There is a ceiling to the priority beyond which tasks that only ever sleep for very long periods cannot surpass. Fix it. Prevent the on-runqueue bonus logic from defeating the idle sleep logic. Opportunity to micro-optimise. Signed-off-by: Con Kolivas <kernel@kolivas.org> Signed-off-by: Mike Galbraith <efault@gmx.de> Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Ken Chen <kenneth.w.chen@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--kernel/sched.c52
1 files changed, 27 insertions, 25 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 582faed3d360..cb146219d532 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -686,33 +686,35 @@ static inline void __activate_idle_task(task_t *p, runqueue_t *rq)
686static int recalc_task_prio(task_t *p, unsigned long long now) 686static int recalc_task_prio(task_t *p, unsigned long long now)
687{ 687{
688 /* Caller must always ensure 'now >= p->timestamp' */ 688 /* Caller must always ensure 'now >= p->timestamp' */
689 unsigned long long __sleep_time = now - p->timestamp; 689 unsigned long sleep_time = now - p->timestamp;
690 unsigned long sleep_time;
691 690
692 if (batch_task(p)) 691 if (batch_task(p))
693 sleep_time = 0; 692 sleep_time = 0;
694 else {
695 if (__sleep_time > NS_MAX_SLEEP_AVG)
696 sleep_time = NS_MAX_SLEEP_AVG;
697 else
698 sleep_time = (unsigned long)__sleep_time;
699 }
700 693
701 if (likely(sleep_time > 0)) { 694 if (likely(sleep_time > 0)) {
702 /* 695 /*
703 * User tasks that sleep a long time are categorised as 696 * This ceiling is set to the lowest priority that would allow
704 * idle. They will only have their sleep_avg increased to a 697 * a task to be reinserted into the active array on timeslice
705 * level that makes them just interactive priority to stay 698 * completion.
706 * active yet prevent them suddenly becoming cpu hogs and
707 * starving other processes.
708 */ 699 */
709 if (p->mm && sleep_time > INTERACTIVE_SLEEP(p)) { 700 unsigned long ceiling = INTERACTIVE_SLEEP(p);
710 unsigned long ceiling;
711 701
712 ceiling = JIFFIES_TO_NS(MAX_SLEEP_AVG - 702 if (p->mm && sleep_time > ceiling && p->sleep_avg < ceiling) {
713 DEF_TIMESLICE); 703 /*
714 if (p->sleep_avg < ceiling) 704 * Prevents user tasks from achieving best priority
715 p->sleep_avg = ceiling; 705 * with one single large enough sleep.
706 */
707 p->sleep_avg = ceiling;
708 /*
709 * Using INTERACTIVE_SLEEP() as a ceiling places a
710 * nice(0) task 1ms sleep away from promotion, and
711 * gives it 700ms to round-robin with no chance of
712 * being demoted. This is more than generous, so
713 * mark this sleep as non-interactive to prevent the
714 * on-runqueue bonus logic from intervening should
715 * this task not receive cpu immediately.
716 */
717 p->sleep_type = SLEEP_NONINTERACTIVE;
716 } else { 718 } else {
717 /* 719 /*
718 * Tasks waking from uninterruptible sleep are 720 * Tasks waking from uninterruptible sleep are
@@ -720,12 +722,12 @@ static int recalc_task_prio(task_t *p, unsigned long long now)
720 * are likely to be waiting on I/O 722 * are likely to be waiting on I/O
721 */ 723 */
722 if (p->sleep_type == SLEEP_NONINTERACTIVE && p->mm) { 724 if (p->sleep_type == SLEEP_NONINTERACTIVE && p->mm) {
723 if (p->sleep_avg >= INTERACTIVE_SLEEP(p)) 725 if (p->sleep_avg >= ceiling)
724 sleep_time = 0; 726 sleep_time = 0;
725 else if (p->sleep_avg + sleep_time >= 727 else if (p->sleep_avg + sleep_time >=
726 INTERACTIVE_SLEEP(p)) { 728 ceiling) {
727 p->sleep_avg = INTERACTIVE_SLEEP(p); 729 p->sleep_avg = ceiling;
728 sleep_time = 0; 730 sleep_time = 0;
729 } 731 }
730 } 732 }
731 733
@@ -739,9 +741,9 @@ static int recalc_task_prio(task_t *p, unsigned long long now)
739 */ 741 */
740 p->sleep_avg += sleep_time; 742 p->sleep_avg += sleep_time;
741 743
742 if (p->sleep_avg > NS_MAX_SLEEP_AVG)
743 p->sleep_avg = NS_MAX_SLEEP_AVG;
744 } 744 }
745 if (p->sleep_avg > NS_MAX_SLEEP_AVG)
746 p->sleep_avg = NS_MAX_SLEEP_AVG;
745 } 747 }
746 748
747 return effective_prio(p); 749 return effective_prio(p);