Commit 72d2854d4ebf5faf086ebccb2ed575c6b68a05dc

Authored by Con Kolivas
Committed by Linus Torvalds
1 parent d444886e14

[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>

Showing 1 changed file with 27 additions and 25 deletions Side-by-side Diff

... ... @@ -686,33 +686,35 @@
686 686 static int recalc_task_prio(task_t *p, unsigned long long now)
687 687 {
688 688 /* Caller must always ensure 'now >= p->timestamp' */
689   - unsigned long long __sleep_time = now - p->timestamp;
690   - unsigned long sleep_time;
  689 + unsigned long sleep_time = now - p->timestamp;
691 690  
692 691 if (batch_task(p))
693 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 694 if (likely(sleep_time > 0)) {
702 695 /*
703   - * User tasks that sleep a long time are categorised as
704   - * idle. They will only have their sleep_avg increased to a
705   - * level that makes them just interactive priority to stay
706   - * active yet prevent them suddenly becoming cpu hogs and
707   - * starving other processes.
  696 + * This ceiling is set to the lowest priority that would allow
  697 + * a task to be reinserted into the active array on timeslice
  698 + * completion.
708 699 */
709   - if (p->mm && sleep_time > INTERACTIVE_SLEEP(p)) {
710   - unsigned long ceiling;
  700 + unsigned long ceiling = INTERACTIVE_SLEEP(p);
711 701  
712   - ceiling = JIFFIES_TO_NS(MAX_SLEEP_AVG -
713   - DEF_TIMESLICE);
714   - if (p->sleep_avg < ceiling)
715   - p->sleep_avg = ceiling;
  702 + if (p->mm && sleep_time > ceiling && p->sleep_avg < ceiling) {
  703 + /*
  704 + * Prevents user tasks from achieving best priority
  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 718 } else {
717 719 /*
718 720 * Tasks waking from uninterruptible sleep are
719 721  
... ... @@ -720,12 +722,12 @@
720 722 * are likely to be waiting on I/O
721 723 */
722 724 if (p->sleep_type == SLEEP_NONINTERACTIVE && p->mm) {
723   - if (p->sleep_avg >= INTERACTIVE_SLEEP(p))
  725 + if (p->sleep_avg >= ceiling)
724 726 sleep_time = 0;
725 727 else if (p->sleep_avg + sleep_time >=
726   - INTERACTIVE_SLEEP(p)) {
727   - p->sleep_avg = INTERACTIVE_SLEEP(p);
728   - sleep_time = 0;
  728 + ceiling) {
  729 + p->sleep_avg = ceiling;
  730 + sleep_time = 0;
729 731 }
730 732 }
731 733  
732 734  
... ... @@ -739,9 +741,9 @@
739 741 */
740 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 749 return effective_prio(p);