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.c142
1 files changed, 53 insertions, 89 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 6c091d6e159d..e2a530515619 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -202,17 +202,12 @@ static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq)
202 202
203static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq) 203static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
204{ 204{
205 struct rb_node **link = &cfs_rq->tasks_timeline.rb_node; 205 struct rb_node *last = rb_last(&cfs_rq->tasks_timeline);
206 struct sched_entity *se = NULL;
207 struct rb_node *parent;
208 206
209 while (*link) { 207 if (!last)
210 parent = *link; 208 return NULL;
211 se = rb_entry(parent, struct sched_entity, run_node);
212 link = &parent->rb_right;
213 }
214 209
215 return se; 210 return rb_entry(last, struct sched_entity, run_node);
216} 211}
217 212
218/************************************************************** 213/**************************************************************
@@ -732,8 +727,6 @@ static inline struct sched_entity *parent_entity(struct sched_entity *se)
732 return se->parent; 727 return se->parent;
733} 728}
734 729
735#define GROUP_IMBALANCE_PCT 20
736
737#else /* CONFIG_FAIR_GROUP_SCHED */ 730#else /* CONFIG_FAIR_GROUP_SCHED */
738 731
739#define for_each_sched_entity(se) \ 732#define for_each_sched_entity(se) \
@@ -824,26 +817,15 @@ hrtick_start_fair(struct rq *rq, struct task_struct *p)
824static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup) 817static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
825{ 818{
826 struct cfs_rq *cfs_rq; 819 struct cfs_rq *cfs_rq;
827 struct sched_entity *se = &p->se, 820 struct sched_entity *se = &p->se;
828 *topse = NULL; /* Highest schedulable entity */
829 int incload = 1;
830 821
831 for_each_sched_entity(se) { 822 for_each_sched_entity(se) {
832 topse = se; 823 if (se->on_rq)
833 if (se->on_rq) {
834 incload = 0;
835 break; 824 break;
836 }
837 cfs_rq = cfs_rq_of(se); 825 cfs_rq = cfs_rq_of(se);
838 enqueue_entity(cfs_rq, se, wakeup); 826 enqueue_entity(cfs_rq, se, wakeup);
839 wakeup = 1; 827 wakeup = 1;
840 } 828 }
841 /* Increment cpu load if we just enqueued the first task of a group on
842 * 'rq->cpu'. 'topse' represents the group to which task 'p' belongs
843 * at the highest grouping level.
844 */
845 if (incload)
846 inc_cpu_load(rq, topse->load.weight);
847 829
848 hrtick_start_fair(rq, rq->curr); 830 hrtick_start_fair(rq, rq->curr);
849} 831}
@@ -856,28 +838,16 @@ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
856static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep) 838static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep)
857{ 839{
858 struct cfs_rq *cfs_rq; 840 struct cfs_rq *cfs_rq;
859 struct sched_entity *se = &p->se, 841 struct sched_entity *se = &p->se;
860 *topse = NULL; /* Highest schedulable entity */
861 int decload = 1;
862 842
863 for_each_sched_entity(se) { 843 for_each_sched_entity(se) {
864 topse = se;
865 cfs_rq = cfs_rq_of(se); 844 cfs_rq = cfs_rq_of(se);
866 dequeue_entity(cfs_rq, se, sleep); 845 dequeue_entity(cfs_rq, se, sleep);
867 /* Don't dequeue parent if it has other entities besides us */ 846 /* Don't dequeue parent if it has other entities besides us */
868 if (cfs_rq->load.weight) { 847 if (cfs_rq->load.weight)
869 if (parent_entity(se))
870 decload = 0;
871 break; 848 break;
872 }
873 sleep = 1; 849 sleep = 1;
874 } 850 }
875 /* Decrement cpu load if we just dequeued the last task of a group on
876 * 'rq->cpu'. 'topse' represents the group to which task 'p' belongs
877 * at the highest grouping level.
878 */
879 if (decload)
880 dec_cpu_load(rq, topse->load.weight);
881 851
882 hrtick_start_fair(rq, rq->curr); 852 hrtick_start_fair(rq, rq->curr);
883} 853}
@@ -1191,6 +1161,25 @@ static struct task_struct *load_balance_next_fair(void *arg)
1191 return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr); 1161 return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr);
1192} 1162}
1193 1163
1164#ifdef CONFIG_FAIR_GROUP_SCHED
1165static int cfs_rq_best_prio(struct cfs_rq *cfs_rq)
1166{
1167 struct sched_entity *curr;
1168 struct task_struct *p;
1169
1170 if (!cfs_rq->nr_running || !first_fair(cfs_rq))
1171 return MAX_PRIO;
1172
1173 curr = cfs_rq->curr;
1174 if (!curr)
1175 curr = __pick_next_entity(cfs_rq);
1176
1177 p = task_of(curr);
1178
1179 return p->prio;
1180}
1181#endif
1182
1194static unsigned long 1183static unsigned long
1195load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, 1184load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
1196 unsigned long max_load_move, 1185 unsigned long max_load_move,
@@ -1200,45 +1189,28 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
1200 struct cfs_rq *busy_cfs_rq; 1189 struct cfs_rq *busy_cfs_rq;
1201 long rem_load_move = max_load_move; 1190 long rem_load_move = max_load_move;
1202 struct rq_iterator cfs_rq_iterator; 1191 struct rq_iterator cfs_rq_iterator;
1203 unsigned long load_moved;
1204 1192
1205 cfs_rq_iterator.start = load_balance_start_fair; 1193 cfs_rq_iterator.start = load_balance_start_fair;
1206 cfs_rq_iterator.next = load_balance_next_fair; 1194 cfs_rq_iterator.next = load_balance_next_fair;
1207 1195
1208 for_each_leaf_cfs_rq(busiest, busy_cfs_rq) { 1196 for_each_leaf_cfs_rq(busiest, busy_cfs_rq) {
1209#ifdef CONFIG_FAIR_GROUP_SCHED 1197#ifdef CONFIG_FAIR_GROUP_SCHED
1210 struct cfs_rq *this_cfs_rq = busy_cfs_rq->tg->cfs_rq[this_cpu]; 1198 struct cfs_rq *this_cfs_rq;
1211 unsigned long maxload, task_load, group_weight; 1199 long imbalance;
1212 unsigned long thisload, per_task_load; 1200 unsigned long maxload;
1213 struct sched_entity *se = busy_cfs_rq->tg->se[busiest->cpu];
1214
1215 task_load = busy_cfs_rq->load.weight;
1216 group_weight = se->load.weight;
1217 1201
1218 /* 1202 this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu);
1219 * 'group_weight' is contributed by tasks of total weight
1220 * 'task_load'. To move 'rem_load_move' worth of weight only,
1221 * we need to move a maximum task load of:
1222 *
1223 * maxload = (remload / group_weight) * task_load;
1224 */
1225 maxload = (rem_load_move * task_load) / group_weight;
1226 1203
1227 if (!maxload || !task_load) 1204 imbalance = busy_cfs_rq->load.weight - this_cfs_rq->load.weight;
1205 /* Don't pull if this_cfs_rq has more load than busy_cfs_rq */
1206 if (imbalance <= 0)
1228 continue; 1207 continue;
1229 1208
1230 per_task_load = task_load / busy_cfs_rq->nr_running; 1209 /* Don't pull more than imbalance/2 */
1231 /* 1210 imbalance /= 2;
1232 * balance_tasks will try to forcibly move atleast one task if 1211 maxload = min(rem_load_move, imbalance);
1233 * possible (because of SCHED_LOAD_SCALE_FUZZ). Avoid that if
1234 * maxload is less than GROUP_IMBALANCE_FUZZ% the per_task_load.
1235 */
1236 if (100 * maxload < GROUP_IMBALANCE_PCT * per_task_load)
1237 continue;
1238 1212
1239 /* Disable priority-based load balance */ 1213 *this_best_prio = cfs_rq_best_prio(this_cfs_rq);
1240 *this_best_prio = 0;
1241 thisload = this_cfs_rq->load.weight;
1242#else 1214#else
1243# define maxload rem_load_move 1215# define maxload rem_load_move
1244#endif 1216#endif
@@ -1247,33 +1219,11 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
1247 * load_balance_[start|next]_fair iterators 1219 * load_balance_[start|next]_fair iterators
1248 */ 1220 */
1249 cfs_rq_iterator.arg = busy_cfs_rq; 1221 cfs_rq_iterator.arg = busy_cfs_rq;
1250 load_moved = balance_tasks(this_rq, this_cpu, busiest, 1222 rem_load_move -= balance_tasks(this_rq, this_cpu, busiest,
1251 maxload, sd, idle, all_pinned, 1223 maxload, sd, idle, all_pinned,
1252 this_best_prio, 1224 this_best_prio,
1253 &cfs_rq_iterator); 1225 &cfs_rq_iterator);
1254 1226
1255#ifdef CONFIG_FAIR_GROUP_SCHED
1256 /*
1257 * load_moved holds the task load that was moved. The
1258 * effective (group) weight moved would be:
1259 * load_moved_eff = load_moved/task_load * group_weight;
1260 */
1261 load_moved = (group_weight * load_moved) / task_load;
1262
1263 /* Adjust shares on both cpus to reflect load_moved */
1264 group_weight -= load_moved;
1265 set_se_shares(se, group_weight);
1266
1267 se = busy_cfs_rq->tg->se[this_cpu];
1268 if (!thisload)
1269 group_weight = load_moved;
1270 else
1271 group_weight = se->load.weight + load_moved;
1272 set_se_shares(se, group_weight);
1273#endif
1274
1275 rem_load_move -= load_moved;
1276
1277 if (rem_load_move <= 0) 1227 if (rem_load_move <= 0)
1278 break; 1228 break;
1279 } 1229 }
@@ -1403,6 +1353,16 @@ static void set_curr_task_fair(struct rq *rq)
1403 set_next_entity(cfs_rq_of(se), se); 1353 set_next_entity(cfs_rq_of(se), se);
1404} 1354}
1405 1355
1356#ifdef CONFIG_FAIR_GROUP_SCHED
1357static void moved_group_fair(struct task_struct *p)
1358{
1359 struct cfs_rq *cfs_rq = task_cfs_rq(p);
1360
1361 update_curr(cfs_rq);
1362 place_entity(cfs_rq, &p->se, 1);
1363}
1364#endif
1365
1406/* 1366/*
1407 * All the scheduling class methods: 1367 * All the scheduling class methods:
1408 */ 1368 */
@@ -1431,6 +1391,10 @@ static const struct sched_class fair_sched_class = {
1431 1391
1432 .prio_changed = prio_changed_fair, 1392 .prio_changed = prio_changed_fair,
1433 .switched_to = switched_to_fair, 1393 .switched_to = switched_to_fair,
1394
1395#ifdef CONFIG_FAIR_GROUP_SCHED
1396 .moved_group = moved_group_fair,
1397#endif
1434}; 1398};
1435 1399
1436#ifdef CONFIG_SCHED_DEBUG 1400#ifdef CONFIG_SCHED_DEBUG