aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index b4dab63c6dbd..0ec84f57695d 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1941,6 +1941,7 @@ int can_migrate_task(task_t *p, runqueue_t *rq, int this_cpu,
1941 return 1; 1941 return 1;
1942} 1942}
1943 1943
1944#define rq_best_prio(rq) min((rq)->curr->prio, (rq)->best_expired_prio)
1944/* 1945/*
1945 * move_tasks tries to move up to max_nr_move tasks and max_load_move weighted 1946 * move_tasks tries to move up to max_nr_move tasks and max_load_move weighted
1946 * load from busiest to this_rq, as part of a balancing operation within 1947 * load from busiest to this_rq, as part of a balancing operation within
@@ -1955,7 +1956,9 @@ static int move_tasks(runqueue_t *this_rq, int this_cpu, runqueue_t *busiest,
1955{ 1956{
1956 prio_array_t *array, *dst_array; 1957 prio_array_t *array, *dst_array;
1957 struct list_head *head, *curr; 1958 struct list_head *head, *curr;
1958 int idx, pulled = 0, pinned = 0, this_min_prio; 1959 int idx, pulled = 0, pinned = 0, this_best_prio, busiest_best_prio;
1960 int busiest_best_prio_seen;
1961 int skip_for_load; /* skip the task based on weighted load issues */
1959 long rem_load_move; 1962 long rem_load_move;
1960 task_t *tmp; 1963 task_t *tmp;
1961 1964
@@ -1964,7 +1967,16 @@ static int move_tasks(runqueue_t *this_rq, int this_cpu, runqueue_t *busiest,
1964 1967
1965 rem_load_move = max_load_move; 1968 rem_load_move = max_load_move;
1966 pinned = 1; 1969 pinned = 1;
1967 this_min_prio = this_rq->curr->prio; 1970 this_best_prio = rq_best_prio(this_rq);
1971 busiest_best_prio = rq_best_prio(busiest);
1972 /*
1973 * Enable handling of the case where there is more than one task
1974 * with the best priority. If the current running task is one
1975 * of those with prio==busiest_best_prio we know it won't be moved
1976 * and therefore it's safe to override the skip (based on load) of
1977 * any task we find with that prio.
1978 */
1979 busiest_best_prio_seen = busiest_best_prio == busiest->curr->prio;
1968 1980
1969 /* 1981 /*
1970 * We first consider expired tasks. Those will likely not be 1982 * We first consider expired tasks. Those will likely not be
@@ -2009,8 +2021,12 @@ skip_queue:
2009 * skip a task if it will be the highest priority task (i.e. smallest 2021 * skip a task if it will be the highest priority task (i.e. smallest
2010 * prio value) on its new queue regardless of its load weight 2022 * prio value) on its new queue regardless of its load weight
2011 */ 2023 */
2012 if ((idx >= this_min_prio && tmp->load_weight > rem_load_move) || 2024 skip_for_load = tmp->load_weight > rem_load_move;
2025 if (skip_for_load && idx < this_best_prio)
2026 skip_for_load = !busiest_best_prio_seen && idx == busiest_best_prio;
2027 if (skip_for_load ||
2013 !can_migrate_task(tmp, busiest, this_cpu, sd, idle, &pinned)) { 2028 !can_migrate_task(tmp, busiest, this_cpu, sd, idle, &pinned)) {
2029 busiest_best_prio_seen |= idx == busiest_best_prio;
2014 if (curr != head) 2030 if (curr != head)
2015 goto skip_queue; 2031 goto skip_queue;
2016 idx++; 2032 idx++;
@@ -2031,8 +2047,8 @@ skip_queue:
2031 * and the prescribed amount of weighted load. 2047 * and the prescribed amount of weighted load.
2032 */ 2048 */
2033 if (pulled < max_nr_move && rem_load_move > 0) { 2049 if (pulled < max_nr_move && rem_load_move > 0) {
2034 if (idx < this_min_prio) 2050 if (idx < this_best_prio)
2035 this_min_prio = idx; 2051 this_best_prio = idx;
2036 if (curr != head) 2052 if (curr != head)
2037 goto skip_queue; 2053 goto skip_queue;
2038 idx++; 2054 idx++;