Skip to content

Commit faf7075

Browse files
lukaszluba-armrafaeljw
authored andcommitted
PM: EM: Introduce em_compute_costs()
Move the EM costs computation code into a new dedicated function, em_compute_costs(), that can be reused in other places in the future. This change is not expected to alter the general functionality. Reviewed-by: Dietmar Eggemann <[email protected]> Tested-by: Dietmar Eggemann <[email protected]> Signed-off-by: Lukasz Luba <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent a3c7877 commit faf7075

File tree

1 file changed

+43
-29
lines changed

1 file changed

+43
-29
lines changed

kernel/power/energy_model.c

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,52 @@ static void em_debug_create_pd(struct device *dev) {}
103103
static void em_debug_remove_pd(struct device *dev) {}
104104
#endif
105105

106+
static int em_compute_costs(struct device *dev, struct em_perf_state *table,
107+
struct em_data_callback *cb, int nr_states,
108+
unsigned long flags)
109+
{
110+
unsigned long prev_cost = ULONG_MAX;
111+
u64 fmax;
112+
int i, ret;
113+
114+
/* Compute the cost of each performance state. */
115+
fmax = (u64) table[nr_states - 1].frequency;
116+
for (i = nr_states - 1; i >= 0; i--) {
117+
unsigned long power_res, cost;
118+
119+
if (flags & EM_PERF_DOMAIN_ARTIFICIAL) {
120+
ret = cb->get_cost(dev, table[i].frequency, &cost);
121+
if (ret || !cost || cost > EM_MAX_POWER) {
122+
dev_err(dev, "EM: invalid cost %lu %d\n",
123+
cost, ret);
124+
return -EINVAL;
125+
}
126+
} else {
127+
power_res = table[i].power;
128+
cost = div64_u64(fmax * power_res, table[i].frequency);
129+
}
130+
131+
table[i].cost = cost;
132+
133+
if (table[i].cost >= prev_cost) {
134+
table[i].flags = EM_PERF_STATE_INEFFICIENT;
135+
dev_dbg(dev, "EM: OPP:%lu is inefficient\n",
136+
table[i].frequency);
137+
} else {
138+
prev_cost = table[i].cost;
139+
}
140+
}
141+
142+
return 0;
143+
}
144+
106145
static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
107146
int nr_states, struct em_data_callback *cb,
108147
unsigned long flags)
109148
{
110-
unsigned long power, freq, prev_freq = 0, prev_cost = ULONG_MAX;
149+
unsigned long power, freq, prev_freq = 0;
111150
struct em_perf_state *table;
112151
int i, ret;
113-
u64 fmax;
114152

115153
table = kcalloc(nr_states, sizeof(*table), GFP_KERNEL);
116154
if (!table)
@@ -154,33 +192,9 @@ static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
154192
table[i].frequency = prev_freq = freq;
155193
}
156194

157-
/* Compute the cost of each performance state. */
158-
fmax = (u64) table[nr_states - 1].frequency;
159-
for (i = nr_states - 1; i >= 0; i--) {
160-
unsigned long power_res, cost;
161-
162-
if (flags & EM_PERF_DOMAIN_ARTIFICIAL) {
163-
ret = cb->get_cost(dev, table[i].frequency, &cost);
164-
if (ret || !cost || cost > EM_MAX_POWER) {
165-
dev_err(dev, "EM: invalid cost %lu %d\n",
166-
cost, ret);
167-
goto free_ps_table;
168-
}
169-
} else {
170-
power_res = table[i].power;
171-
cost = div64_u64(fmax * power_res, table[i].frequency);
172-
}
173-
174-
table[i].cost = cost;
175-
176-
if (table[i].cost >= prev_cost) {
177-
table[i].flags = EM_PERF_STATE_INEFFICIENT;
178-
dev_dbg(dev, "EM: OPP:%lu is inefficient\n",
179-
table[i].frequency);
180-
} else {
181-
prev_cost = table[i].cost;
182-
}
183-
}
195+
ret = em_compute_costs(dev, table, cb, nr_states, flags);
196+
if (ret)
197+
goto free_ps_table;
184198

185199
pd->table = table;
186200
pd->nr_perf_states = nr_states;

0 commit comments

Comments
 (0)