diff options
-rw-r--r-- | kernel/sched.c | 62 |
1 files changed, 18 insertions, 44 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 4c64f85698a..c13f1bd2df7 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -665,55 +665,13 @@ static int effective_prio(task_t *p) | |||
665 | } | 665 | } |
666 | 666 | ||
667 | /* | 667 | /* |
668 | * We place interactive tasks back into the active array, if possible. | ||
669 | * | ||
670 | * To guarantee that this does not starve expired tasks we ignore the | ||
671 | * interactivity of a task if the first expired task had to wait more | ||
672 | * than a 'reasonable' amount of time. This deadline timeout is | ||
673 | * load-dependent, as the frequency of array switched decreases with | ||
674 | * increasing number of running tasks. We also ignore the interactivity | ||
675 | * if a better static_prio task has expired, and switch periodically | ||
676 | * regardless, to ensure that highly interactive tasks do not starve | ||
677 | * the less fortunate for unreasonably long periods. | ||
678 | */ | ||
679 | static inline int expired_starving(runqueue_t *rq) | ||
680 | { | ||
681 | int limit; | ||
682 | |||
683 | /* | ||
684 | * Arrays were recently switched, all is well | ||
685 | */ | ||
686 | if (!rq->expired_timestamp) | ||
687 | return 0; | ||
688 | |||
689 | limit = STARVATION_LIMIT * rq->nr_running; | ||
690 | |||
691 | /* | ||
692 | * It's time to switch arrays | ||
693 | */ | ||
694 | if (jiffies - rq->expired_timestamp >= limit) | ||
695 | return 1; | ||
696 | |||
697 | /* | ||
698 | * There's a better selection in the expired array | ||
699 | */ | ||
700 | if (rq->curr->static_prio > rq->best_expired_prio) | ||
701 | return 1; | ||
702 | |||
703 | /* | ||
704 | * All is well | ||
705 | */ | ||
706 | return 0; | ||
707 | } | ||
708 | |||
709 | /* | ||
710 | * __activate_task - move a task to the runqueue. | 668 | * __activate_task - move a task to the runqueue. |
711 | */ | 669 | */ |
712 | static void __activate_task(task_t *p, runqueue_t *rq) | 670 | static void __activate_task(task_t *p, runqueue_t *rq) |
713 | { | 671 | { |
714 | prio_array_t *target = rq->active; | 672 | prio_array_t *target = rq->active; |
715 | 673 | ||
716 | if (unlikely(batch_task(p) || (expired_starving(rq) && !rt_task(p)))) | 674 | if (batch_task(p)) |
717 | target = rq->expired; | 675 | target = rq->expired; |
718 | enqueue_task(p, target); | 676 | enqueue_task(p, target); |
719 | rq->nr_running++; | 677 | rq->nr_running++; |
@@ -2532,6 +2490,22 @@ unsigned long long current_sched_time(const task_t *tsk) | |||
2532 | } | 2490 | } |
2533 | 2491 | ||
2534 | /* | 2492 | /* |
2493 | * We place interactive tasks back into the active array, if possible. | ||
2494 | * | ||
2495 | * To guarantee that this does not starve expired tasks we ignore the | ||
2496 | * interactivity of a task if the first expired task had to wait more | ||
2497 | * than a 'reasonable' amount of time. This deadline timeout is | ||
2498 | * load-dependent, as the frequency of array switched decreases with | ||
2499 | * increasing number of running tasks. We also ignore the interactivity | ||
2500 | * if a better static_prio task has expired: | ||
2501 | */ | ||
2502 | #define EXPIRED_STARVING(rq) \ | ||
2503 | ((STARVATION_LIMIT && ((rq)->expired_timestamp && \ | ||
2504 | (jiffies - (rq)->expired_timestamp >= \ | ||
2505 | STARVATION_LIMIT * ((rq)->nr_running) + 1))) || \ | ||
2506 | ((rq)->curr->static_prio > (rq)->best_expired_prio)) | ||
2507 | |||
2508 | /* | ||
2535 | * Account user cpu time to a process. | 2509 | * Account user cpu time to a process. |
2536 | * @p: the process that the cpu time gets accounted to | 2510 | * @p: the process that the cpu time gets accounted to |
2537 | * @hardirq_offset: the offset to subtract from hardirq_count() | 2511 | * @hardirq_offset: the offset to subtract from hardirq_count() |
@@ -2666,7 +2640,7 @@ void scheduler_tick(void) | |||
2666 | 2640 | ||
2667 | if (!rq->expired_timestamp) | 2641 | if (!rq->expired_timestamp) |
2668 | rq->expired_timestamp = jiffies; | 2642 | rq->expired_timestamp = jiffies; |
2669 | if (!TASK_INTERACTIVE(p) || expired_starving(rq)) { | 2643 | if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) { |
2670 | enqueue_task(p, rq->expired); | 2644 | enqueue_task(p, rq->expired); |
2671 | if (p->static_prio < rq->best_expired_prio) | 2645 | if (p->static_prio < rq->best_expired_prio) |
2672 | rq->best_expired_prio = p->static_prio; | 2646 | rq->best_expired_prio = p->static_prio; |