[RFC PATCH 5/7] sched/topology: Make {lowest/highest}_flag_domain() work with > 1 flags

From: Valentin Schneider
Date: Wed Dec 11 2019 - 11:44:52 EST


In some cases, select_task_rq_fair() ends up looking for the highest domain
with both SD_LOAD_BALANCE and one of SD_BALANCE_{WAKE, FORK, EXEC}.
This is pretty much a highest_flag_domain() call, but that latter
can only cope with a single flag.

Make the existing helpers cope with being passed more than one flag. While
at it, rename them to make their newfound powers explicit.

Signed-off-by: Valentin Schneider <valentin.schneider@xxxxxxx>
---
kernel/sched/sched.h | 23 ++++++++++++++++-------
kernel/sched/topology.c | 8 ++++----
2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 62efc0443cac..233b3d41e347 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1340,20 +1340,20 @@ extern void sched_ttwu_pending(void);
#define for_each_lower_domain(sd) for (; sd; sd = sd->child)

/**
- * highest_flag_domain - Return highest sched_domain containing flag.
+ * highest_flags_domain - Return highest sched_domain containing flags.
* @cpu: The CPU whose highest level of sched domain is to
* be returned.
- * @flag: The flag to check for the highest sched_domain
+ * @flags: The flags to check for the highest sched_domain
* for the given CPU.
*
- * Returns the highest sched_domain of a CPU which contains the given flag.
+ * Returns the highest sched_domain of a CPU which contains all given flags.
*/
-static inline struct sched_domain *highest_flag_domain(int cpu, int flag)
+static inline struct sched_domain *highest_flags_domain(int cpu, int flags)
{
struct sched_domain *sd, *hsd = NULL;

for_each_domain(cpu, sd) {
- if (!(sd->flags & flag))
+ if (!((sd->flags & flags) == flags))
break;
hsd = sd;
}
@@ -1361,12 +1361,21 @@ static inline struct sched_domain *highest_flag_domain(int cpu, int flag)
return hsd;
}

-static inline struct sched_domain *lowest_flag_domain(int cpu, int flag)
+/**
+ * lowest_flags_domain - Return lowest sched_domain containing flags.
+ * @cpu: The CPU whose lowest level of sched domain is to
+ * be returned.
+ * @flags: The flags to check for the lowest sched_domain
+ * for the given CPU.
+ *
+ * Returns the lowest sched_domain of a CPU which contains all given flags.
+ */
+static inline struct sched_domain *lowest_flags_domain(int cpu, int flags)
{
struct sched_domain *sd;

for_each_domain(cpu, sd) {
- if (sd->flags & flag)
+ if ((sd->flags & flags) == flags)
break;
}

diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index 6ec1e595b1d4..f0d2a15fd10b 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -631,7 +631,7 @@ static void update_top_cache_domain(int cpu)
int id = cpu;
int size = 1;

- sd = highest_flag_domain(cpu, SD_SHARE_PKG_RESOURCES);
+ sd = highest_flags_domain(cpu, SD_SHARE_PKG_RESOURCES);
if (sd) {
id = cpumask_first(sched_domain_span(sd));
size = cpumask_weight(sched_domain_span(sd));
@@ -643,13 +643,13 @@ static void update_top_cache_domain(int cpu)
per_cpu(sd_llc_id, cpu) = id;
rcu_assign_pointer(per_cpu(sd_llc_shared, cpu), sds);

- sd = lowest_flag_domain(cpu, SD_NUMA);
+ sd = lowest_flags_domain(cpu, SD_NUMA);
rcu_assign_pointer(per_cpu(sd_numa, cpu), sd);

- sd = highest_flag_domain(cpu, SD_ASYM_PACKING);
+ sd = highest_flags_domain(cpu, SD_ASYM_PACKING);
rcu_assign_pointer(per_cpu(sd_asym_packing, cpu), sd);

- sd = lowest_flag_domain(cpu, SD_ASYM_CPUCAPACITY);
+ sd = lowest_flags_domain(cpu, SD_ASYM_CPUCAPACITY);
rcu_assign_pointer(per_cpu(sd_asym_cpucapacity, cpu), sd);
}

--
2.24.0