arm64: introduce sys sd energy model infrastructure
authorDietmar Eggemann <dietmar.eggemann@arm.com>
Thu, 18 Aug 2016 11:06:07 +0000 (12:06 +0100)
committerLukasz Luba <l.luba@partner.samsung.com>
Mon, 10 Sep 2018 08:24:07 +0000 (10:24 +0200)
Allow the energy model to contain a system level besides the already
existing core and cluster level.

This is necessary for platforms with frequency domains spanning all
cpus to let the EAS algorithm work properly.

The whole idea of this system level has to be rethought once
the idea of the 'struct sched_domain_shared' gets more momentum:

https://lkml.org/lkml/2016/6/16/209

Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Signed-off-by: Lukasz Luba <l.luba@partner.samsung.com>
arch/arm64/kernel/energy_model.h
arch/arm64/kernel/topology.c

index a71c78da5b43ef763ec65875862077e4c053eccf..4a86fa37901c8803bcc4c2f6337d7a40120564f6 100644 (file)
@@ -153,24 +153,27 @@ static struct sched_group_energy energy_core_hikey = {
        .cap_states     = cap_states_core_hikey,
 };
 
-/* An energy model contains core and cluster sched group energy for 2
- * clusters (cluster id 0 and 1). set_energy_model() relies on this
- * feature. It is enforced by a BUG_ON in energy().
+/* An energy model contains core, cluster and system sched group energy
+ * for 2 clusters (cluster id 0 and 1). set_energy_model() relies on
+ * this feature. It is enforced by a BUG_ON in energy().
  */
 
 struct energy_model {
        struct sched_group_energy *core_energy[2];
        struct sched_group_energy *cluster_energy[2];
+       struct sched_group_energy *system_energy[2];
 };
 
 static struct energy_model juno_model = {
        { &energy_core_juno_a57, &energy_core_juno_a53, },
        { &energy_cluster_juno_a57, &energy_cluster_juno_a53, },
+       {},
 };
 
 static struct energy_model hikey_model = {
        { &energy_core_hikey, &energy_core_hikey, },
        { &energy_cluster_hikey, &energy_cluster_hikey, },
+       {},
 };
 
 static struct of_device_id model_matches[] = {
@@ -179,14 +182,14 @@ static struct of_device_id model_matches[] = {
        {},
 };
 
-static struct sched_group_energy **core_energy, **cluster_energy;
+struct sched_group_energy **core_energy, **cluster_energy, **system_energy;
 
 static void __init set_energy_model(void)
 {
        const struct of_device_id *match;
        struct energy_model *em;
 
-       BUG_ON(core_energy || cluster_energy);
+       BUG_ON(core_energy || cluster_energy || system_energy);
 
        match = of_match_node(model_matches, of_root);
 
@@ -197,10 +200,12 @@ static void __init set_energy_model(void)
 
        core_energy = em->core_energy;
        cluster_energy = em->cluster_energy;
+       system_energy = em->system_energy;
 
-       pr_debug("energy model core[0,1]=[%p,%p] cluster=[%p,%p]\n",
+       pr_debug("energy model core[0,1]=[%p,%p] cluster=[%p,%p] system=[%p,%p]\n",
                 em->core_energy[0], em->core_energy[1],
-                em->cluster_energy[0], em->cluster_energy[1]);
+                em->cluster_energy[0], em->cluster_energy[1],
+                em->system_energy[0], em->system_energy[1]);
 }
 
 static inline
@@ -211,7 +216,8 @@ struct sched_group_energy *energy(int cpu, struct sched_group_energy **sge)
        BUG_ON(idx != 0 && idx != 1);
 
        pr_debug("cpu=%d %s%s[%d]=%p\n", cpu, (sge == core_energy) ?
-                "core" : "cluster", "_energy", idx, sge[idx]);
+                "core" : (sge == cluster_energy) ? "cluster" :
+                "system", "_energy", idx, sge[idx]);
 
        return sge[idx];
 }
@@ -227,3 +233,9 @@ const struct sched_group_energy * const cpu_cluster_energy(int cpu)
 {
        return cluster_energy ? energy(cpu, cluster_energy) : NULL;
 }
+
+static inline
+const struct sched_group_energy * const cpu_system_energy(int cpu)
+{
+       return system_energy ? energy(cpu, system_energy) : NULL;
+}
index 019bbf654918aa7db8ebce623ab9f8555c4ac13c..66306b9db6a9daf2afc5371d38aa5242c59a7251 100644 (file)
@@ -332,6 +332,7 @@ static struct sched_domain_topology_level arm64_topology[] = {
        { cpu_coregroup_mask, core_flags, cpu_core_energy, SD_INIT_NAME(MC) },
 #endif
        { cpu_cpu_mask, cpu_flags, cpu_cluster_energy, SD_INIT_NAME(DIE) },
+       { cpu_cpu_mask, NULL, cpu_system_energy, SD_INIT_NAME(SYS) },
        { NULL, }
 };