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.c302
1 files changed, 213 insertions, 89 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 18fd17172eb6..51aa3e102acb 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -73,6 +73,8 @@ unsigned int sysctl_sched_wakeup_granularity = 5000000UL;
73 73
74const_debug unsigned int sysctl_sched_migration_cost = 500000UL; 74const_debug unsigned int sysctl_sched_migration_cost = 500000UL;
75 75
76static const struct sched_class fair_sched_class;
77
76/************************************************************** 78/**************************************************************
77 * CFS operations on generic schedulable entities: 79 * CFS operations on generic schedulable entities:
78 */ 80 */
@@ -141,6 +143,49 @@ static inline struct sched_entity *parent_entity(struct sched_entity *se)
141 return se->parent; 143 return se->parent;
142} 144}
143 145
146/* return depth at which a sched entity is present in the hierarchy */
147static inline int depth_se(struct sched_entity *se)
148{
149 int depth = 0;
150
151 for_each_sched_entity(se)
152 depth++;
153
154 return depth;
155}
156
157static void
158find_matching_se(struct sched_entity **se, struct sched_entity **pse)
159{
160 int se_depth, pse_depth;
161
162 /*
163 * preemption test can be made between sibling entities who are in the
164 * same cfs_rq i.e who have a common parent. Walk up the hierarchy of
165 * both tasks until we find their ancestors who are siblings of common
166 * parent.
167 */
168
169 /* First walk up until both entities are at same depth */
170 se_depth = depth_se(*se);
171 pse_depth = depth_se(*pse);
172
173 while (se_depth > pse_depth) {
174 se_depth--;
175 *se = parent_entity(*se);
176 }
177
178 while (pse_depth > se_depth) {
179 pse_depth--;
180 *pse = parent_entity(*pse);
181 }
182
183 while (!is_same_group(*se, *pse)) {
184 *se = parent_entity(*se);
185 *pse = parent_entity(*pse);
186 }
187}
188
144#else /* CONFIG_FAIR_GROUP_SCHED */ 189#else /* CONFIG_FAIR_GROUP_SCHED */
145 190
146static inline struct rq *rq_of(struct cfs_rq *cfs_rq) 191static inline struct rq *rq_of(struct cfs_rq *cfs_rq)
@@ -191,6 +236,11 @@ static inline struct sched_entity *parent_entity(struct sched_entity *se)
191 return NULL; 236 return NULL;
192} 237}
193 238
239static inline void
240find_matching_se(struct sched_entity **se, struct sched_entity **pse)
241{
242}
243
194#endif /* CONFIG_FAIR_GROUP_SCHED */ 244#endif /* CONFIG_FAIR_GROUP_SCHED */
195 245
196 246
@@ -221,6 +271,27 @@ static inline s64 entity_key(struct cfs_rq *cfs_rq, struct sched_entity *se)
221 return se->vruntime - cfs_rq->min_vruntime; 271 return se->vruntime - cfs_rq->min_vruntime;
222} 272}
223 273
274static void update_min_vruntime(struct cfs_rq *cfs_rq)
275{
276 u64 vruntime = cfs_rq->min_vruntime;
277
278 if (cfs_rq->curr)
279 vruntime = cfs_rq->curr->vruntime;
280
281 if (cfs_rq->rb_leftmost) {
282 struct sched_entity *se = rb_entry(cfs_rq->rb_leftmost,
283 struct sched_entity,
284 run_node);
285
286 if (vruntime == cfs_rq->min_vruntime)
287 vruntime = se->vruntime;
288 else
289 vruntime = min_vruntime(vruntime, se->vruntime);
290 }
291
292 cfs_rq->min_vruntime = max_vruntime(cfs_rq->min_vruntime, vruntime);
293}
294
224/* 295/*
225 * Enqueue an entity into the rb-tree: 296 * Enqueue an entity into the rb-tree:
226 */ 297 */
@@ -254,15 +325,8 @@ static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
254 * Maintain a cache of leftmost tree entries (it is frequently 325 * Maintain a cache of leftmost tree entries (it is frequently
255 * used): 326 * used):
256 */ 327 */
257 if (leftmost) { 328 if (leftmost)
258 cfs_rq->rb_leftmost = &se->run_node; 329 cfs_rq->rb_leftmost = &se->run_node;
259 /*
260 * maintain cfs_rq->min_vruntime to be a monotonic increasing
261 * value tracking the leftmost vruntime in the tree.
262 */
263 cfs_rq->min_vruntime =
264 max_vruntime(cfs_rq->min_vruntime, se->vruntime);
265 }
266 330
267 rb_link_node(&se->run_node, parent, link); 331 rb_link_node(&se->run_node, parent, link);
268 rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline); 332 rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline);
@@ -272,37 +336,25 @@ static void __dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
272{ 336{
273 if (cfs_rq->rb_leftmost == &se->run_node) { 337 if (cfs_rq->rb_leftmost == &se->run_node) {
274 struct rb_node *next_node; 338 struct rb_node *next_node;
275 struct sched_entity *next;
276 339
277 next_node = rb_next(&se->run_node); 340 next_node = rb_next(&se->run_node);
278 cfs_rq->rb_leftmost = next_node; 341 cfs_rq->rb_leftmost = next_node;
279
280 if (next_node) {
281 next = rb_entry(next_node,
282 struct sched_entity, run_node);
283 cfs_rq->min_vruntime =
284 max_vruntime(cfs_rq->min_vruntime,
285 next->vruntime);
286 }
287 } 342 }
288 343
289 if (cfs_rq->next == se)
290 cfs_rq->next = NULL;
291
292 rb_erase(&se->run_node, &cfs_rq->tasks_timeline); 344 rb_erase(&se->run_node, &cfs_rq->tasks_timeline);
293} 345}
294 346
295static inline struct rb_node *first_fair(struct cfs_rq *cfs_rq)
296{
297 return cfs_rq->rb_leftmost;
298}
299
300static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq) 347static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq)
301{ 348{
302 return rb_entry(first_fair(cfs_rq), struct sched_entity, run_node); 349 struct rb_node *left = cfs_rq->rb_leftmost;
350
351 if (!left)
352 return NULL;
353
354 return rb_entry(left, struct sched_entity, run_node);
303} 355}
304 356
305static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq) 357static struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
306{ 358{
307 struct rb_node *last = rb_last(&cfs_rq->tasks_timeline); 359 struct rb_node *last = rb_last(&cfs_rq->tasks_timeline);
308 360
@@ -334,7 +386,7 @@ int sched_nr_latency_handler(struct ctl_table *table, int write,
334#endif 386#endif
335 387
336/* 388/*
337 * delta *= w / rw 389 * delta *= P[w / rw]
338 */ 390 */
339static inline unsigned long 391static inline unsigned long
340calc_delta_weight(unsigned long delta, struct sched_entity *se) 392calc_delta_weight(unsigned long delta, struct sched_entity *se)
@@ -348,15 +400,13 @@ calc_delta_weight(unsigned long delta, struct sched_entity *se)
348} 400}
349 401
350/* 402/*
351 * delta *= rw / w 403 * delta /= w
352 */ 404 */
353static inline unsigned long 405static inline unsigned long
354calc_delta_fair(unsigned long delta, struct sched_entity *se) 406calc_delta_fair(unsigned long delta, struct sched_entity *se)
355{ 407{
356 for_each_sched_entity(se) { 408 if (unlikely(se->load.weight != NICE_0_LOAD))
357 delta = calc_delta_mine(delta, 409 delta = calc_delta_mine(delta, NICE_0_LOAD, &se->load);
358 cfs_rq_of(se)->load.weight, &se->load);
359 }
360 410
361 return delta; 411 return delta;
362} 412}
@@ -386,26 +436,26 @@ static u64 __sched_period(unsigned long nr_running)
386 * We calculate the wall-time slice from the period by taking a part 436 * We calculate the wall-time slice from the period by taking a part
387 * proportional to the weight. 437 * proportional to the weight.
388 * 438 *
389 * s = p*w/rw 439 * s = p*P[w/rw]
390 */ 440 */
391static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se) 441static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se)
392{ 442{
393 return calc_delta_weight(__sched_period(cfs_rq->nr_running), se); 443 unsigned long nr_running = cfs_rq->nr_running;
444
445 if (unlikely(!se->on_rq))
446 nr_running++;
447
448 return calc_delta_weight(__sched_period(nr_running), se);
394} 449}
395 450
396/* 451/*
397 * We calculate the vruntime slice of a to be inserted task 452 * We calculate the vruntime slice of a to be inserted task
398 * 453 *
399 * vs = s*rw/w = p 454 * vs = s/w
400 */ 455 */
401static u64 sched_vslice_add(struct cfs_rq *cfs_rq, struct sched_entity *se) 456static u64 sched_vslice(struct cfs_rq *cfs_rq, struct sched_entity *se)
402{ 457{
403 unsigned long nr_running = cfs_rq->nr_running; 458 return calc_delta_fair(sched_slice(cfs_rq, se), se);
404
405 if (!se->on_rq)
406 nr_running++;
407
408 return __sched_period(nr_running);
409} 459}
410 460
411/* 461/*
@@ -424,6 +474,7 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr,
424 schedstat_add(cfs_rq, exec_clock, delta_exec); 474 schedstat_add(cfs_rq, exec_clock, delta_exec);
425 delta_exec_weighted = calc_delta_fair(delta_exec, curr); 475 delta_exec_weighted = calc_delta_fair(delta_exec, curr);
426 curr->vruntime += delta_exec_weighted; 476 curr->vruntime += delta_exec_weighted;
477 update_min_vruntime(cfs_rq);
427} 478}
428 479
429static void update_curr(struct cfs_rq *cfs_rq) 480static void update_curr(struct cfs_rq *cfs_rq)
@@ -449,6 +500,7 @@ static void update_curr(struct cfs_rq *cfs_rq)
449 struct task_struct *curtask = task_of(curr); 500 struct task_struct *curtask = task_of(curr);
450 501
451 cpuacct_charge(curtask, delta_exec); 502 cpuacct_charge(curtask, delta_exec);
503 account_group_exec_runtime(curtask, delta_exec);
452 } 504 }
453} 505}
454 506
@@ -612,13 +664,7 @@ static void check_spread(struct cfs_rq *cfs_rq, struct sched_entity *se)
612static void 664static void
613place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) 665place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
614{ 666{
615 u64 vruntime; 667 u64 vruntime = cfs_rq->min_vruntime;
616
617 if (first_fair(cfs_rq)) {
618 vruntime = min_vruntime(cfs_rq->min_vruntime,
619 __pick_next_entity(cfs_rq)->vruntime);
620 } else
621 vruntime = cfs_rq->min_vruntime;
622 668
623 /* 669 /*
624 * The 'current' period is already promised to the current tasks, 670 * The 'current' period is already promised to the current tasks,
@@ -627,7 +673,7 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
627 * stays open at the end. 673 * stays open at the end.
628 */ 674 */
629 if (initial && sched_feat(START_DEBIT)) 675 if (initial && sched_feat(START_DEBIT))
630 vruntime += sched_vslice_add(cfs_rq, se); 676 vruntime += sched_vslice(cfs_rq, se);
631 677
632 if (!initial) { 678 if (!initial) {
633 /* sleeps upto a single latency don't count. */ 679 /* sleeps upto a single latency don't count. */
@@ -692,9 +738,16 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
692#endif 738#endif
693 } 739 }
694 740
741 if (cfs_rq->last == se)
742 cfs_rq->last = NULL;
743
744 if (cfs_rq->next == se)
745 cfs_rq->next = NULL;
746
695 if (se != cfs_rq->curr) 747 if (se != cfs_rq->curr)
696 __dequeue_entity(cfs_rq, se); 748 __dequeue_entity(cfs_rq, se);
697 account_entity_dequeue(cfs_rq, se); 749 account_entity_dequeue(cfs_rq, se);
750 update_min_vruntime(cfs_rq);
698} 751}
699 752
700/* 753/*
@@ -741,29 +794,18 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
741 se->prev_sum_exec_runtime = se->sum_exec_runtime; 794 se->prev_sum_exec_runtime = se->sum_exec_runtime;
742} 795}
743 796
744static struct sched_entity * 797static int
745pick_next(struct cfs_rq *cfs_rq, struct sched_entity *se) 798wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se);
746{
747 struct rq *rq = rq_of(cfs_rq);
748 u64 pair_slice = rq->clock - cfs_rq->pair_start;
749
750 if (!cfs_rq->next || pair_slice > sched_slice(cfs_rq, cfs_rq->next)) {
751 cfs_rq->pair_start = rq->clock;
752 return se;
753 }
754
755 return cfs_rq->next;
756}
757 799
758static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq) 800static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq)
759{ 801{
760 struct sched_entity *se = NULL; 802 struct sched_entity *se = __pick_next_entity(cfs_rq);
761 803
762 if (first_fair(cfs_rq)) { 804 if (cfs_rq->next && wakeup_preempt_entity(cfs_rq->next, se) < 1)
763 se = __pick_next_entity(cfs_rq); 805 return cfs_rq->next;
764 se = pick_next(cfs_rq, se); 806
765 set_next_entity(cfs_rq, se); 807 if (cfs_rq->last && wakeup_preempt_entity(cfs_rq->last, se) < 1)
766 } 808 return cfs_rq->last;
767 809
768 return se; 810 return se;
769} 811}
@@ -848,11 +890,31 @@ static void hrtick_start_fair(struct rq *rq, struct task_struct *p)
848 hrtick_start(rq, delta); 890 hrtick_start(rq, delta);
849 } 891 }
850} 892}
893
894/*
895 * called from enqueue/dequeue and updates the hrtick when the
896 * current task is from our class and nr_running is low enough
897 * to matter.
898 */
899static void hrtick_update(struct rq *rq)
900{
901 struct task_struct *curr = rq->curr;
902
903 if (curr->sched_class != &fair_sched_class)
904 return;
905
906 if (cfs_rq_of(&curr->se)->nr_running < sched_nr_latency)
907 hrtick_start_fair(rq, curr);
908}
851#else /* !CONFIG_SCHED_HRTICK */ 909#else /* !CONFIG_SCHED_HRTICK */
852static inline void 910static inline void
853hrtick_start_fair(struct rq *rq, struct task_struct *p) 911hrtick_start_fair(struct rq *rq, struct task_struct *p)
854{ 912{
855} 913}
914
915static inline void hrtick_update(struct rq *rq)
916{
917}
856#endif 918#endif
857 919
858/* 920/*
@@ -873,7 +935,7 @@ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
873 wakeup = 1; 935 wakeup = 1;
874 } 936 }
875 937
876 hrtick_start_fair(rq, rq->curr); 938 hrtick_update(rq);
877} 939}
878 940
879/* 941/*
@@ -895,7 +957,7 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep)
895 sleep = 1; 957 sleep = 1;
896 } 958 }
897 959
898 hrtick_start_fair(rq, rq->curr); 960 hrtick_update(rq);
899} 961}
900 962
901/* 963/*
@@ -1001,8 +1063,6 @@ static inline int wake_idle(int cpu, struct task_struct *p)
1001 1063
1002#ifdef CONFIG_SMP 1064#ifdef CONFIG_SMP
1003 1065
1004static const struct sched_class fair_sched_class;
1005
1006#ifdef CONFIG_FAIR_GROUP_SCHED 1066#ifdef CONFIG_FAIR_GROUP_SCHED
1007/* 1067/*
1008 * effective_load() calculates the load change as seen from the root_task_group 1068 * effective_load() calculates the load change as seen from the root_task_group
@@ -1103,10 +1163,9 @@ wake_affine(struct sched_domain *this_sd, struct rq *this_rq,
1103 if (!(this_sd->flags & SD_WAKE_AFFINE) || !sched_feat(AFFINE_WAKEUPS)) 1163 if (!(this_sd->flags & SD_WAKE_AFFINE) || !sched_feat(AFFINE_WAKEUPS))
1104 return 0; 1164 return 0;
1105 1165
1106 if (!sync && sched_feat(SYNC_WAKEUPS) && 1166 if (sync && (curr->se.avg_overlap > sysctl_sched_migration_cost ||
1107 curr->se.avg_overlap < sysctl_sched_migration_cost && 1167 p->se.avg_overlap > sysctl_sched_migration_cost))
1108 p->se.avg_overlap < sysctl_sched_migration_cost) 1168 sync = 0;
1109 sync = 1;
1110 1169
1111 /* 1170 /*
1112 * If sync wakeup then subtract the (maximum possible) 1171 * If sync wakeup then subtract the (maximum possible)
@@ -1225,33 +1284,88 @@ static unsigned long wakeup_gran(struct sched_entity *se)
1225 * More easily preempt - nice tasks, while not making it harder for 1284 * More easily preempt - nice tasks, while not making it harder for
1226 * + nice tasks. 1285 * + nice tasks.
1227 */ 1286 */
1228 if (sched_feat(ASYM_GRAN)) 1287 if (!sched_feat(ASYM_GRAN) || se->load.weight > NICE_0_LOAD)
1229 gran = calc_delta_mine(gran, NICE_0_LOAD, &se->load); 1288 gran = calc_delta_fair(sysctl_sched_wakeup_granularity, se);
1230 1289
1231 return gran; 1290 return gran;
1232} 1291}
1233 1292
1234/* 1293/*
1294 * Should 'se' preempt 'curr'.
1295 *
1296 * |s1
1297 * |s2
1298 * |s3
1299 * g
1300 * |<--->|c
1301 *
1302 * w(c, s1) = -1
1303 * w(c, s2) = 0
1304 * w(c, s3) = 1
1305 *
1306 */
1307static int
1308wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se)
1309{
1310 s64 gran, vdiff = curr->vruntime - se->vruntime;
1311
1312 if (vdiff <= 0)
1313 return -1;
1314
1315 gran = wakeup_gran(curr);
1316 if (vdiff > gran)
1317 return 1;
1318
1319 return 0;
1320}
1321
1322static void set_last_buddy(struct sched_entity *se)
1323{
1324 for_each_sched_entity(se)
1325 cfs_rq_of(se)->last = se;
1326}
1327
1328static void set_next_buddy(struct sched_entity *se)
1329{
1330 for_each_sched_entity(se)
1331 cfs_rq_of(se)->next = se;
1332}
1333
1334/*
1235 * Preempt the current task with a newly woken task if needed: 1335 * Preempt the current task with a newly woken task if needed:
1236 */ 1336 */
1237static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync) 1337static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
1238{ 1338{
1239 struct task_struct *curr = rq->curr; 1339 struct task_struct *curr = rq->curr;
1240 struct cfs_rq *cfs_rq = task_cfs_rq(curr);
1241 struct sched_entity *se = &curr->se, *pse = &p->se; 1340 struct sched_entity *se = &curr->se, *pse = &p->se;
1242 s64 delta_exec;
1243 1341
1244 if (unlikely(rt_prio(p->prio))) { 1342 if (unlikely(rt_prio(p->prio))) {
1343 struct cfs_rq *cfs_rq = task_cfs_rq(curr);
1344
1245 update_rq_clock(rq); 1345 update_rq_clock(rq);
1246 update_curr(cfs_rq); 1346 update_curr(cfs_rq);
1247 resched_task(curr); 1347 resched_task(curr);
1248 return; 1348 return;
1249 } 1349 }
1250 1350
1351 if (unlikely(p->sched_class != &fair_sched_class))
1352 return;
1353
1251 if (unlikely(se == pse)) 1354 if (unlikely(se == pse))
1252 return; 1355 return;
1253 1356
1254 cfs_rq_of(pse)->next = pse; 1357 /*
1358 * Only set the backward buddy when the current task is still on the
1359 * rq. This can happen when a wakeup gets interleaved with schedule on
1360 * the ->pre_schedule() or idle_balance() point, either of which can
1361 * drop the rq lock.
1362 *
1363 * Also, during early boot the idle thread is in the fair class, for
1364 * obvious reasons its a bad idea to schedule back to the idle thread.
1365 */
1366 if (sched_feat(LAST_BUDDY) && likely(se->on_rq && curr != rq->idle))
1367 set_last_buddy(se);
1368 set_next_buddy(pse);
1255 1369
1256 /* 1370 /*
1257 * We can come here with TIF_NEED_RESCHED already set from new task 1371 * We can come here with TIF_NEED_RESCHED already set from new task
@@ -1277,9 +1391,19 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
1277 return; 1391 return;
1278 } 1392 }
1279 1393
1280 delta_exec = se->sum_exec_runtime - se->prev_sum_exec_runtime; 1394 find_matching_se(&se, &pse);
1281 if (delta_exec > wakeup_gran(pse)) 1395
1282 resched_task(curr); 1396 while (se) {
1397 BUG_ON(!pse);
1398
1399 if (wakeup_preempt_entity(se, pse) == 1) {
1400 resched_task(curr);
1401 break;
1402 }
1403
1404 se = parent_entity(se);
1405 pse = parent_entity(pse);
1406 }
1283} 1407}
1284 1408
1285static struct task_struct *pick_next_task_fair(struct rq *rq) 1409static struct task_struct *pick_next_task_fair(struct rq *rq)
@@ -1293,6 +1417,7 @@ static struct task_struct *pick_next_task_fair(struct rq *rq)
1293 1417
1294 do { 1418 do {
1295 se = pick_next_entity(cfs_rq); 1419 se = pick_next_entity(cfs_rq);
1420 set_next_entity(cfs_rq, se);
1296 cfs_rq = group_cfs_rq(se); 1421 cfs_rq = group_cfs_rq(se);
1297 } while (cfs_rq); 1422 } while (cfs_rq);
1298 1423
@@ -1575,9 +1700,6 @@ static const struct sched_class fair_sched_class = {
1575 .enqueue_task = enqueue_task_fair, 1700 .enqueue_task = enqueue_task_fair,
1576 .dequeue_task = dequeue_task_fair, 1701 .dequeue_task = dequeue_task_fair,
1577 .yield_task = yield_task_fair, 1702 .yield_task = yield_task_fair,
1578#ifdef CONFIG_SMP
1579 .select_task_rq = select_task_rq_fair,
1580#endif /* CONFIG_SMP */
1581 1703
1582 .check_preempt_curr = check_preempt_wakeup, 1704 .check_preempt_curr = check_preempt_wakeup,
1583 1705
@@ -1585,6 +1707,8 @@ static const struct sched_class fair_sched_class = {
1585 .put_prev_task = put_prev_task_fair, 1707 .put_prev_task = put_prev_task_fair,
1586 1708
1587#ifdef CONFIG_SMP 1709#ifdef CONFIG_SMP
1710 .select_task_rq = select_task_rq_fair,
1711
1588 .load_balance = load_balance_fair, 1712 .load_balance = load_balance_fair,
1589 .move_one_task = move_one_task_fair, 1713 .move_one_task = move_one_task_fair,
1590#endif 1714#endif