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 4c64f85698ae..c13f1bd2df7d 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; |
