1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
From 5ef504e0ddfbc6856799fc6c342f36e0e4d18cbd Mon Sep 17 00:00:00 2001
From: Juri Lelli <juri.lelli@arm.com>
Date: Tue, 10 Feb 2015 12:05:22 +0000
Subject: [PATCH 68/92] arm64, topology: Define JUNO energy and provide it to
the scheduler
This patch is only here to be able to test provisioning of energy related
data from an arch topology shim layer to the scheduler. Since there is no
code today which deals with extracting energy related data from the dtb or
acpi, and process it in the topology shim layer, the content of the
sched_group_energy structures as well as the idle_state and capacity_state
arrays are hard-coded here.
This patch defines the sched_group_energy structure as well as the
idle_state and capacity_state array for the cluster (relates to sched
groups (sgs) in DIE sched domain level) and for the core (relates to sgs
in MC sd level) for a Cortex A53 as well as for a Cortex A57.
It further provides related implementations of the sched_domain_energy_f
functions (cpu_cluster_energy() and cpu_core_energy()).
To be able to propagate this information from the topology shim layer to
the scheduler, the elements of the arm_topology[] table have been
provisioned with the appropriate sched_domain_energy_f functions.
Signed-off-by: Juri Lelli <juri.lelli@arm.com>
(cherry picked from commit 037aceb5c5b768295bdda8f111ac9b0c8f97cc79)
Signed-off-by: Gaku Inami <gaku.inami.xw@bp.renesas.com>
---
arch/arm64/kernel/topology.c | 118 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 116 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index a8d986e..a75db2b 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -525,6 +525,120 @@ static int __init parse_dt_topology(void)
struct cpu_topology cpu_topology[NR_CPUS];
EXPORT_SYMBOL_GPL(cpu_topology);
+/*
+ * ARM JUNO specific energy cost model data. There are no unit requirements for
+ * the data. Data can be normalized to any reference point, but the
+ * normalization must be consistent. That is, one bogo-joule/watt must be the
+ * same quantity for all data, but we don't care what it is.
+ */
+
+static struct idle_state idle_states_cluster_a53[] = {
+ { .power = 56 }, /* arch_cpu_idle() (active idle) = WFI */
+ { .power = 56 }, /* WFI */
+ { .power = 56 }, /* cpu-sleep-0 */
+ { .power = 17 }, /* cluster-sleep-0 */
+};
+
+static struct idle_state idle_states_cluster_a57[] = {
+ { .power = 65 }, /* arch_cpu_idle() (active idle) = WFI */
+ { .power = 65 }, /* WFI */
+ { .power = 65 }, /* cpu-sleep-0 */
+ { .power = 24 }, /* cluster-sleep-0 */
+};
+
+static struct capacity_state cap_states_cluster_a53[] = {
+ /* Power per cluster */
+ { .cap = 235, .power = 26, }, /* 450 MHz */
+ { .cap = 303, .power = 30, }, /* 575 MHz */
+ { .cap = 368, .power = 39, }, /* 700 MHz */
+ { .cap = 406, .power = 47, }, /* 775 MHz */
+ { .cap = 447, .power = 57, }, /* 850 Mhz */
+};
+
+static struct capacity_state cap_states_cluster_a57[] = {
+ /* Power per cluster */
+ { .cap = 417, .power = 24, }, /* 450 MHz */
+ { .cap = 579, .power = 32, }, /* 625 MHz */
+ { .cap = 744, .power = 43, }, /* 800 MHz */
+ { .cap = 883, .power = 49, }, /* 950 MHz */
+ { .cap = 1024, .power = 64, }, /* 1100 MHz */
+};
+
+static struct sched_group_energy energy_cluster_a53 = {
+ .nr_idle_states = ARRAY_SIZE(idle_states_cluster_a53),
+ .idle_states = idle_states_cluster_a53,
+ .nr_cap_states = ARRAY_SIZE(cap_states_cluster_a53),
+ .cap_states = cap_states_cluster_a53,
+};
+
+static struct sched_group_energy energy_cluster_a57 = {
+ .nr_idle_states = ARRAY_SIZE(idle_states_cluster_a57),
+ .idle_states = idle_states_cluster_a57,
+ .nr_cap_states = ARRAY_SIZE(cap_states_cluster_a57),
+ .cap_states = cap_states_cluster_a57,
+};
+
+static struct idle_state idle_states_core_a53[] = {
+ { .power = 6 }, /* arch_cpu_idle() (active idle) = WFI */
+ { .power = 6 }, /* WFI */
+ { .power = 0 }, /* cpu-sleep-0 */
+ { .power = 0 }, /* cluster-sleep-0 */
+};
+
+static struct idle_state idle_states_core_a57[] = {
+ { .power = 15 }, /* arch_cpu_idle() (active idle) = WFI */
+ { .power = 15 }, /* WFI */
+ { .power = 0 }, /* cpu-sleep-0 */
+ { .power = 0 }, /* cluster-sleep-0 */
+};
+
+static struct capacity_state cap_states_core_a53[] = {
+ /* Power per cpu */
+ { .cap = 235, .power = 33, }, /* 450 MHz */
+ { .cap = 302, .power = 46, }, /* 575 MHz */
+ { .cap = 368, .power = 61, }, /* 700 MHz */
+ { .cap = 406, .power = 76, }, /* 775 MHz */
+ { .cap = 447, .power = 93, }, /* 850 Mhz */
+};
+
+static struct capacity_state cap_states_core_a57[] = {
+ /* Power per cpu */
+ { .cap = 417, .power = 168, }, /* 450 MHz */
+ { .cap = 579, .power = 251, }, /* 625 MHz */
+ { .cap = 744, .power = 359, }, /* 800 MHz */
+ { .cap = 883, .power = 479, }, /* 950 MHz */
+ { .cap = 1024, .power = 616, }, /* 1100 MHz */
+};
+
+static struct sched_group_energy energy_core_a53 = {
+ .nr_idle_states = ARRAY_SIZE(idle_states_core_a53),
+ .idle_states = idle_states_core_a53,
+ .nr_cap_states = ARRAY_SIZE(cap_states_core_a53),
+ .cap_states = cap_states_core_a53,
+};
+
+static struct sched_group_energy energy_core_a57 = {
+ .nr_idle_states = ARRAY_SIZE(idle_states_core_a57),
+ .idle_states = idle_states_core_a57,
+ .nr_cap_states = ARRAY_SIZE(cap_states_core_a57),
+ .cap_states = cap_states_core_a57,
+};
+
+/* sd energy functions */
+static inline
+const struct sched_group_energy * const cpu_cluster_energy(int cpu)
+{
+ return cpu_topology[cpu].cluster_id ? &energy_cluster_a53 :
+ &energy_cluster_a57;
+}
+
+static inline
+const struct sched_group_energy * const cpu_core_energy(int cpu)
+{
+ return cpu_topology[cpu].cluster_id ? &energy_core_a53 :
+ &energy_core_a57;
+}
+
const struct cpumask *cpu_coregroup_mask(int cpu)
{
return &cpu_topology[cpu].core_sibling;
@@ -636,9 +750,9 @@ static void __init reset_cpu_topology(void)
static struct sched_domain_topology_level arm64_topology[] = {
#ifdef CONFIG_SCHED_MC
- { cpu_coregroup_mask, cpu_coregroup_flags, SD_INIT_NAME(MC) },
+ { cpu_coregroup_mask, cpu_coregroup_flags, cpu_core_energy, SD_INIT_NAME(MC) },
#endif
- { cpu_cpu_mask, cpu_cpu_flags, SD_INIT_NAME(DIE) },
+ { cpu_cpu_mask, cpu_cpu_flags, cpu_cluster_energy, SD_INIT_NAME(DIE) },
{ NULL, }
};
--
1.9.1
|