Loading kernel/sched/fair.c +24 −4 Original line number Diff line number Diff line Loading @@ -5774,6 +5774,7 @@ static unsigned long __read_mostly max_load_balance_interval = HZ/10; #define LBF_IGNORE_SMALL_TASKS 0x08 #define LBF_PWR_ACTIVE_BALANCE 0x10 #define LBF_SCHED_BOOST 0x20 #define LBF_IGNORE_BIG_TASKS 0x40 struct lb_env { struct sched_domain *sd; Loading Loading @@ -5856,6 +5857,7 @@ static int can_migrate_task(struct task_struct *p, struct lb_env *env) { int tsk_cache_hot = 0; int twf; /* * We do not migrate tasks that are: * 1) throttled_lb_pair, or Loading @@ -5874,8 +5876,22 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) if (env->flags & LBF_IGNORE_SMALL_TASKS && is_small_task(p)) return 0; if (!task_will_fit(p, env->dst_cpu) && env->busiest_nr_running <= env->busiest_grp_capacity) twf = task_will_fit(p, env->dst_cpu); /* * Attempt to not pull tasks that don't fit. We may get lucky and find * one that actually fits. */ if (env->flags & LBF_IGNORE_BIG_TASKS && !twf) return 0; /* * Group imbalance can sometimes cause work to be pulled across groups * even though the group could have managed the imbalance on its own. * Prevent inter-cluster migrations for big tasks when the number of * tasks is lower than the capacity of the group. */ if (!twf && env->busiest_nr_running <= env->busiest_grp_capacity) return 0; if (!cpumask_test_cpu(env->dst_cpu, tsk_cpus_allowed(p))) { Loading Loading @@ -5989,6 +6005,9 @@ static int move_tasks(struct lb_env *env) if (capacity(env->dst_rq) > capacity(env->src_rq)) env->flags |= LBF_IGNORE_SMALL_TASKS; else if (capacity(env->dst_rq) < capacity(env->src_rq) && !sched_boost()) env->flags |= LBF_IGNORE_BIG_TASKS; redo: while (!list_empty(tasks)) { Loading Loading @@ -6044,9 +6063,10 @@ next: list_move_tail(&p->se.group_node, tasks); } if (env->flags & LBF_IGNORE_SMALL_TASKS && !pulled) { if (env->flags & (LBF_IGNORE_SMALL_TASKS | LBF_IGNORE_BIG_TASKS) && !pulled) { tasks = &env->src_rq->cfs_tasks; env->flags &= ~LBF_IGNORE_SMALL_TASKS; env->flags &= ~(LBF_IGNORE_SMALL_TASKS | LBF_IGNORE_BIG_TASKS); env->loop = orig_loop; goto redo; } Loading Loading
kernel/sched/fair.c +24 −4 Original line number Diff line number Diff line Loading @@ -5774,6 +5774,7 @@ static unsigned long __read_mostly max_load_balance_interval = HZ/10; #define LBF_IGNORE_SMALL_TASKS 0x08 #define LBF_PWR_ACTIVE_BALANCE 0x10 #define LBF_SCHED_BOOST 0x20 #define LBF_IGNORE_BIG_TASKS 0x40 struct lb_env { struct sched_domain *sd; Loading Loading @@ -5856,6 +5857,7 @@ static int can_migrate_task(struct task_struct *p, struct lb_env *env) { int tsk_cache_hot = 0; int twf; /* * We do not migrate tasks that are: * 1) throttled_lb_pair, or Loading @@ -5874,8 +5876,22 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) if (env->flags & LBF_IGNORE_SMALL_TASKS && is_small_task(p)) return 0; if (!task_will_fit(p, env->dst_cpu) && env->busiest_nr_running <= env->busiest_grp_capacity) twf = task_will_fit(p, env->dst_cpu); /* * Attempt to not pull tasks that don't fit. We may get lucky and find * one that actually fits. */ if (env->flags & LBF_IGNORE_BIG_TASKS && !twf) return 0; /* * Group imbalance can sometimes cause work to be pulled across groups * even though the group could have managed the imbalance on its own. * Prevent inter-cluster migrations for big tasks when the number of * tasks is lower than the capacity of the group. */ if (!twf && env->busiest_nr_running <= env->busiest_grp_capacity) return 0; if (!cpumask_test_cpu(env->dst_cpu, tsk_cpus_allowed(p))) { Loading Loading @@ -5989,6 +6005,9 @@ static int move_tasks(struct lb_env *env) if (capacity(env->dst_rq) > capacity(env->src_rq)) env->flags |= LBF_IGNORE_SMALL_TASKS; else if (capacity(env->dst_rq) < capacity(env->src_rq) && !sched_boost()) env->flags |= LBF_IGNORE_BIG_TASKS; redo: while (!list_empty(tasks)) { Loading Loading @@ -6044,9 +6063,10 @@ next: list_move_tail(&p->se.group_node, tasks); } if (env->flags & LBF_IGNORE_SMALL_TASKS && !pulled) { if (env->flags & (LBF_IGNORE_SMALL_TASKS | LBF_IGNORE_BIG_TASKS) && !pulled) { tasks = &env->src_rq->cfs_tasks; env->flags &= ~LBF_IGNORE_SMALL_TASKS; env->flags &= ~(LBF_IGNORE_SMALL_TASKS | LBF_IGNORE_BIG_TASKS); env->loop = orig_loop; goto redo; } Loading