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.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index be47ce6da2a5..cea2fa853274 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3132,6 +3132,8 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd)
3132} 3132}
3133 3133
3134#define LBF_ALL_PINNED 0x01 3134#define LBF_ALL_PINNED 0x01
3135#define LBF_NEED_BREAK 0x02
3136#define LBF_ABORT 0x04
3135 3137
3136/* 3138/*
3137 * can_migrate_task - may task p from runqueue rq be migrated to this_cpu? 3139 * can_migrate_task - may task p from runqueue rq be migrated to this_cpu?
@@ -3237,8 +3239,10 @@ balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
3237 goto out; 3239 goto out;
3238 3240
3239 list_for_each_entry_safe(p, n, &busiest_cfs_rq->tasks, se.group_node) { 3241 list_for_each_entry_safe(p, n, &busiest_cfs_rq->tasks, se.group_node) {
3240 if (loops++ > sysctl_sched_nr_migrate) 3242 if (loops++ > sysctl_sched_nr_migrate) {
3243 *lb_flags |= LBF_NEED_BREAK;
3241 break; 3244 break;
3245 }
3242 3246
3243 if ((p->se.load.weight >> 1) > rem_load_move || 3247 if ((p->se.load.weight >> 1) > rem_load_move ||
3244 !can_migrate_task(p, busiest, this_cpu, sd, idle, 3248 !can_migrate_task(p, busiest, this_cpu, sd, idle,
@@ -3255,8 +3259,10 @@ balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
3255 * kernels will stop after the first task is pulled to minimize 3259 * kernels will stop after the first task is pulled to minimize
3256 * the critical section. 3260 * the critical section.
3257 */ 3261 */
3258 if (idle == CPU_NEWLY_IDLE) 3262 if (idle == CPU_NEWLY_IDLE) {
3263 *lb_flags |= LBF_ABORT;
3259 break; 3264 break;
3265 }
3260#endif 3266#endif
3261 3267
3262 /* 3268 /*
@@ -3374,6 +3380,9 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
3374 unsigned long busiest_weight = busiest_cfs_rq->load.weight; 3380 unsigned long busiest_weight = busiest_cfs_rq->load.weight;
3375 u64 rem_load, moved_load; 3381 u64 rem_load, moved_load;
3376 3382
3383 if (*lb_flags & (LBF_NEED_BREAK|LBF_ABORT))
3384 break;
3385
3377 /* 3386 /*
3378 * empty group or part of a throttled hierarchy 3387 * empty group or part of a throttled hierarchy
3379 */ 3388 */
@@ -3440,18 +3449,19 @@ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
3440 3449
3441 total_load_moved += load_moved; 3450 total_load_moved += load_moved;
3442 3451
3452 if (*lb_flags & (LBF_NEED_BREAK|LBF_ABORT))
3453 break;
3454
3443#ifdef CONFIG_PREEMPT 3455#ifdef CONFIG_PREEMPT
3444 /* 3456 /*
3445 * NEWIDLE balancing is a source of latency, so preemptible 3457 * NEWIDLE balancing is a source of latency, so preemptible
3446 * kernels will stop after the first task is pulled to minimize 3458 * kernels will stop after the first task is pulled to minimize
3447 * the critical section. 3459 * the critical section.
3448 */ 3460 */
3449 if (idle == CPU_NEWLY_IDLE && this_rq->nr_running) 3461 if (idle == CPU_NEWLY_IDLE && this_rq->nr_running) {
3450 break; 3462 *lb_flags |= LBF_ABORT;
3451
3452 if (raw_spin_is_contended(&this_rq->lock) ||
3453 raw_spin_is_contended(&busiest->lock))
3454 break; 3463 break;
3464 }
3455#endif 3465#endif
3456 } while (load_moved && max_load_move > total_load_moved); 3466 } while (load_moved && max_load_move > total_load_moved);
3457 3467
@@ -4496,6 +4506,14 @@ redo:
4496 if (ld_moved && this_cpu != smp_processor_id()) 4506 if (ld_moved && this_cpu != smp_processor_id())
4497 resched_cpu(this_cpu); 4507 resched_cpu(this_cpu);
4498 4508
4509 if (lb_flags & LBF_ABORT)
4510 goto out_balanced;
4511
4512 if (lb_flags & LBF_NEED_BREAK) {
4513 lb_flags &= ~LBF_NEED_BREAK;
4514 goto redo;
4515 }
4516
4499 /* All tasks on this runqueue were pinned by CPU affinity */ 4517 /* All tasks on this runqueue were pinned by CPU affinity */
4500 if (unlikely(lb_flags & LBF_ALL_PINNED)) { 4518 if (unlikely(lb_flags & LBF_ALL_PINNED)) {
4501 cpumask_clear_cpu(cpu_of(busiest), cpus); 4519 cpumask_clear_cpu(cpu_of(busiest), cpus);