aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched_fair.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched_fair.c')
-rw-r--r--kernel/sched_fair.c84
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
971static 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
989static unsigned long 972static unsigned long
990load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, 973load_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 }