Loading kernel/sched/fair.c +80 −27 Original line number Diff line number Diff line Loading @@ -11093,6 +11093,71 @@ static inline int on_null_domain(struct rq *rq) } #ifdef CONFIG_NO_HZ_COMMON static inline int find_energy_aware_new_ilb(void) { int ilb = nr_cpu_ids; struct sched_domain *sd; int cpu = raw_smp_processor_id(); cpumask_t idle_cpus, tmp_cpus; struct sched_group *sg; unsigned long ref_cap = capacity_orig_of(cpu); unsigned long best_cap = 0, best_cap_cpu = -1; rcu_read_lock(); sd = rcu_dereference(per_cpu(sd_asym_cpucapacity, cpu)); if (!sd) goto out; cpumask_and(&idle_cpus, nohz.idle_cpus_mask, housekeeping_cpumask(HK_FLAG_MISC)); cpumask_andnot(&idle_cpus, &idle_cpus, cpu_isolated_mask); sg = sd->groups; do { int i; unsigned long cap; cpumask_and(&tmp_cpus, &idle_cpus, sched_group_span(sg)); i = cpumask_first(&tmp_cpus); /* This sg did not have any idle CPUs */ if (i >= nr_cpu_ids) continue; cap = capacity_orig_of(i); /* The first preference is for the same capacity CPU */ if (cap == ref_cap) { ilb = i; break; } /* * When there are no idle CPUs in the same capacity group, * we find the next best capacity CPU. */ if (best_cap > ref_cap) { if (cap > ref_cap && cap < best_cap) { best_cap = cap; best_cap_cpu = i; } continue; } if (cap > best_cap) { best_cap = cap; best_cap_cpu = i; } } while (sg = sg->next, sg != sd->groups); if (best_cap_cpu != -1) ilb = best_cap_cpu; out: rcu_read_unlock(); return ilb; } /* * idle load balancing details * - When one of the busy CPUs notice that there may be an idle rebalancing Loading @@ -11104,33 +11169,10 @@ static inline int on_null_domain(struct rq *rq) static inline int find_new_ilb(void) { int ilb = nr_cpu_ids; struct sched_domain *sd; int cpu = raw_smp_processor_id(); struct rq *rq = cpu_rq(cpu); cpumask_t cpumask; int ilb; rcu_read_lock(); sd = rcu_dereference_check_sched_domain(rq->sd); if (sd) { cpumask_and(&cpumask, nohz.idle_cpus_mask, sched_domain_span(sd)); cpumask_andnot(&cpumask, &cpumask, cpu_isolated_mask); ilb = cpumask_first(&cpumask); } rcu_read_unlock(); if (sd && (ilb >= nr_cpu_ids || !idle_cpu(ilb))) { if (!static_branch_unlikely(&sched_energy_present) || (capacity_orig_of(cpu) == cpu_rq(cpu)->rd->max_cpu_capacity.val || cpu_overutilized(cpu))) { cpumask_andnot(&cpumask, nohz.idle_cpus_mask, cpu_isolated_mask); ilb = cpumask_first(&cpumask); } } if (static_branch_likely(&sched_energy_present)) return find_energy_aware_new_ilb(); for_each_cpu_and(ilb, nohz.idle_cpus_mask, housekeeping_cpumask(HK_FLAG_MISC)) { Loading Loading @@ -11214,7 +11256,18 @@ static void nohz_balancer_kick(struct rq *rq) if (time_before(now, nohz.next_balance)) goto out; if (rq->nr_running >= 2 || rq->misfit_task_load) { /* * With EAS, no-hz idle balance is allowed only when the CPU * is overutilized and has 2 tasks. The misfit task migration * happens from the tickpath. */ if (static_branch_likely(&sched_energy_present)) { if (rq->nr_running >= 2 && cpu_overutilized(cpu)) flags = NOHZ_KICK_MASK; goto out; } if (rq->nr_running >= 2) { flags = NOHZ_KICK_MASK; goto out; } Loading Loading
kernel/sched/fair.c +80 −27 Original line number Diff line number Diff line Loading @@ -11093,6 +11093,71 @@ static inline int on_null_domain(struct rq *rq) } #ifdef CONFIG_NO_HZ_COMMON static inline int find_energy_aware_new_ilb(void) { int ilb = nr_cpu_ids; struct sched_domain *sd; int cpu = raw_smp_processor_id(); cpumask_t idle_cpus, tmp_cpus; struct sched_group *sg; unsigned long ref_cap = capacity_orig_of(cpu); unsigned long best_cap = 0, best_cap_cpu = -1; rcu_read_lock(); sd = rcu_dereference(per_cpu(sd_asym_cpucapacity, cpu)); if (!sd) goto out; cpumask_and(&idle_cpus, nohz.idle_cpus_mask, housekeeping_cpumask(HK_FLAG_MISC)); cpumask_andnot(&idle_cpus, &idle_cpus, cpu_isolated_mask); sg = sd->groups; do { int i; unsigned long cap; cpumask_and(&tmp_cpus, &idle_cpus, sched_group_span(sg)); i = cpumask_first(&tmp_cpus); /* This sg did not have any idle CPUs */ if (i >= nr_cpu_ids) continue; cap = capacity_orig_of(i); /* The first preference is for the same capacity CPU */ if (cap == ref_cap) { ilb = i; break; } /* * When there are no idle CPUs in the same capacity group, * we find the next best capacity CPU. */ if (best_cap > ref_cap) { if (cap > ref_cap && cap < best_cap) { best_cap = cap; best_cap_cpu = i; } continue; } if (cap > best_cap) { best_cap = cap; best_cap_cpu = i; } } while (sg = sg->next, sg != sd->groups); if (best_cap_cpu != -1) ilb = best_cap_cpu; out: rcu_read_unlock(); return ilb; } /* * idle load balancing details * - When one of the busy CPUs notice that there may be an idle rebalancing Loading @@ -11104,33 +11169,10 @@ static inline int on_null_domain(struct rq *rq) static inline int find_new_ilb(void) { int ilb = nr_cpu_ids; struct sched_domain *sd; int cpu = raw_smp_processor_id(); struct rq *rq = cpu_rq(cpu); cpumask_t cpumask; int ilb; rcu_read_lock(); sd = rcu_dereference_check_sched_domain(rq->sd); if (sd) { cpumask_and(&cpumask, nohz.idle_cpus_mask, sched_domain_span(sd)); cpumask_andnot(&cpumask, &cpumask, cpu_isolated_mask); ilb = cpumask_first(&cpumask); } rcu_read_unlock(); if (sd && (ilb >= nr_cpu_ids || !idle_cpu(ilb))) { if (!static_branch_unlikely(&sched_energy_present) || (capacity_orig_of(cpu) == cpu_rq(cpu)->rd->max_cpu_capacity.val || cpu_overutilized(cpu))) { cpumask_andnot(&cpumask, nohz.idle_cpus_mask, cpu_isolated_mask); ilb = cpumask_first(&cpumask); } } if (static_branch_likely(&sched_energy_present)) return find_energy_aware_new_ilb(); for_each_cpu_and(ilb, nohz.idle_cpus_mask, housekeeping_cpumask(HK_FLAG_MISC)) { Loading Loading @@ -11214,7 +11256,18 @@ static void nohz_balancer_kick(struct rq *rq) if (time_before(now, nohz.next_balance)) goto out; if (rq->nr_running >= 2 || rq->misfit_task_load) { /* * With EAS, no-hz idle balance is allowed only when the CPU * is overutilized and has 2 tasks. The misfit task migration * happens from the tickpath. */ if (static_branch_likely(&sched_energy_present)) { if (rq->nr_running >= 2 && cpu_overutilized(cpu)) flags = NOHZ_KICK_MASK; goto out; } if (rq->nr_running >= 2) { flags = NOHZ_KICK_MASK; goto out; } Loading