diff options
Diffstat (limited to 'kernel/sched_fair.c')
-rw-r--r-- | kernel/sched_fair.c | 84 |
1 files changed, 53 insertions, 31 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 30ae9c2a2861..5c208e090ae4 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -707,6 +707,8 @@ static inline struct sched_entity *parent_entity(struct sched_entity *se) | |||
707 | return se->parent; | 707 | return se->parent; |
708 | } | 708 | } |
709 | 709 | ||
710 | #define GROUP_IMBALANCE_PCT 20 | ||
711 | |||
710 | #else /* CONFIG_FAIR_GROUP_SCHED */ | 712 | #else /* CONFIG_FAIR_GROUP_SCHED */ |
711 | 713 | ||
712 | #define for_each_sched_entity(se) \ | 714 | #define for_each_sched_entity(se) \ |
@@ -967,25 +969,6 @@ static struct task_struct *load_balance_next_fair(void *arg) | |||
967 | return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr); | 969 | return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr); |
968 | } | 970 | } |
969 | 971 | ||
970 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
971 | static int cfs_rq_best_prio(struct cfs_rq *cfs_rq) | ||
972 | { | ||
973 | struct sched_entity *curr; | ||
974 | struct task_struct *p; | ||
975 | |||
976 | if (!cfs_rq->nr_running) | ||
977 | return MAX_PRIO; | ||
978 | |||
979 | curr = cfs_rq->curr; | ||
980 | if (!curr) | ||
981 | curr = __pick_next_entity(cfs_rq); | ||
982 | |||
983 | p = task_of(curr); | ||
984 | |||
985 | return p->prio; | ||
986 | } | ||
987 | #endif | ||
988 | |||
989 | static unsigned long | 972 | static unsigned long |
990 | load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, | 973 | load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, |
991 | unsigned long max_load_move, | 974 | unsigned long max_load_move, |
@@ -995,28 +978,45 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
995 | struct cfs_rq *busy_cfs_rq; | 978 | struct cfs_rq *busy_cfs_rq; |
996 | long rem_load_move = max_load_move; | 979 | long rem_load_move = max_load_move; |
997 | struct rq_iterator cfs_rq_iterator; | 980 | struct rq_iterator cfs_rq_iterator; |
981 | unsigned long load_moved; | ||
998 | 982 | ||
999 | cfs_rq_iterator.start = load_balance_start_fair; | 983 | cfs_rq_iterator.start = load_balance_start_fair; |
1000 | cfs_rq_iterator.next = load_balance_next_fair; | 984 | cfs_rq_iterator.next = load_balance_next_fair; |
1001 | 985 | ||
1002 | for_each_leaf_cfs_rq(busiest, busy_cfs_rq) { | 986 | for_each_leaf_cfs_rq(busiest, busy_cfs_rq) { |
1003 | #ifdef CONFIG_FAIR_GROUP_SCHED | 987 | #ifdef CONFIG_FAIR_GROUP_SCHED |
1004 | struct cfs_rq *this_cfs_rq; | 988 | struct cfs_rq *this_cfs_rq = busy_cfs_rq->tg->cfs_rq[this_cpu]; |
1005 | long imbalance; | 989 | unsigned long maxload, task_load, group_weight; |
1006 | unsigned long maxload; | 990 | unsigned long thisload, per_task_load; |
991 | struct sched_entity *se = busy_cfs_rq->tg->se[busiest->cpu]; | ||
1007 | 992 | ||
1008 | this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu); | 993 | task_load = busy_cfs_rq->load.weight; |
994 | group_weight = se->load.weight; | ||
1009 | 995 | ||
1010 | imbalance = busy_cfs_rq->load.weight - this_cfs_rq->load.weight; | 996 | /* |
1011 | /* Don't pull if this_cfs_rq has more load than busy_cfs_rq */ | 997 | * 'group_weight' is contributed by tasks of total weight |
1012 | if (imbalance <= 0) | 998 | * 'task_load'. To move 'rem_load_move' worth of weight only, |
999 | * we need to move a maximum task load of: | ||
1000 | * | ||
1001 | * maxload = (remload / group_weight) * task_load; | ||
1002 | */ | ||
1003 | maxload = (rem_load_move * task_load) / group_weight; | ||
1004 | |||
1005 | if (!maxload || !task_load) | ||
1013 | continue; | 1006 | continue; |
1014 | 1007 | ||
1015 | /* Don't pull more than imbalance/2 */ | 1008 | per_task_load = task_load / busy_cfs_rq->nr_running; |
1016 | imbalance /= 2; | 1009 | /* |
1017 | maxload = min(rem_load_move, imbalance); | 1010 | * balance_tasks will try to forcibly move atleast one task if |
1011 | * possible (because of SCHED_LOAD_SCALE_FUZZ). Avoid that if | ||
1012 | * maxload is less than GROUP_IMBALANCE_FUZZ% the per_task_load. | ||
1013 | */ | ||
1014 | if (100 * maxload < GROUP_IMBALANCE_PCT * per_task_load) | ||
1015 | continue; | ||
1018 | 1016 | ||
1019 | *this_best_prio = cfs_rq_best_prio(this_cfs_rq); | 1017 | /* Disable priority-based load balance */ |
1018 | *this_best_prio = 0; | ||
1019 | thisload = this_cfs_rq->load.weight; | ||
1020 | #else | 1020 | #else |
1021 | # define maxload rem_load_move | 1021 | # define maxload rem_load_move |
1022 | #endif | 1022 | #endif |
@@ -1025,11 +1025,33 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
1025 | * load_balance_[start|next]_fair iterators | 1025 | * load_balance_[start|next]_fair iterators |
1026 | */ | 1026 | */ |
1027 | cfs_rq_iterator.arg = busy_cfs_rq; | 1027 | cfs_rq_iterator.arg = busy_cfs_rq; |
1028 | rem_load_move -= balance_tasks(this_rq, this_cpu, busiest, | 1028 | load_moved = balance_tasks(this_rq, this_cpu, busiest, |
1029 | maxload, sd, idle, all_pinned, | 1029 | maxload, sd, idle, all_pinned, |
1030 | this_best_prio, | 1030 | this_best_prio, |
1031 | &cfs_rq_iterator); | 1031 | &cfs_rq_iterator); |
1032 | 1032 | ||
1033 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
1034 | /* | ||
1035 | * load_moved holds the task load that was moved. The | ||
1036 | * effective (group) weight moved would be: | ||
1037 | * load_moved_eff = load_moved/task_load * group_weight; | ||
1038 | */ | ||
1039 | load_moved = (group_weight * load_moved) / task_load; | ||
1040 | |||
1041 | /* Adjust shares on both cpus to reflect load_moved */ | ||
1042 | group_weight -= load_moved; | ||
1043 | set_se_shares(se, group_weight); | ||
1044 | |||
1045 | se = busy_cfs_rq->tg->se[this_cpu]; | ||
1046 | if (!thisload) | ||
1047 | group_weight = load_moved; | ||
1048 | else | ||
1049 | group_weight = se->load.weight + load_moved; | ||
1050 | set_se_shares(se, group_weight); | ||
1051 | #endif | ||
1052 | |||
1053 | rem_load_move -= load_moved; | ||
1054 | |||
1033 | if (rem_load_move <= 0) | 1055 | if (rem_load_move <= 0) |
1034 | break; | 1056 | break; |
1035 | } | 1057 | } |