Skip to content

Commit aa1a432

Browse files
Vincent Donnefortrafaeljw
authored andcommitted
PM: EM: Fix inefficient states detection
Currently, a debug message is printed if an inefficient state is detected in the Energy Model. Unfortunately, it won't detect if the first state is inefficient or if two successive states are. Fix this behavior. Fixes: 27871f7 (PM: Introduce an Energy Model management framework) Signed-off-by: Vincent Donnefort <[email protected]> Reviewed-by: Quentin Perret <[email protected]> Reviewed-by: Lukasz Luba <[email protected]> Reviewed-by: Matthias Kaehlcke <[email protected]> Acked-by: Viresh Kumar <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 9e1ff30 commit aa1a432

File tree

1 file changed

+8
-15
lines changed

1 file changed

+8
-15
lines changed

kernel/power/energy_model.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ static void em_debug_remove_pd(struct device *dev) {}
107107
static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
108108
int nr_states, struct em_data_callback *cb)
109109
{
110-
unsigned long opp_eff, prev_opp_eff = ULONG_MAX;
111-
unsigned long power, freq, prev_freq = 0;
110+
unsigned long power, freq, prev_freq = 0, prev_cost = ULONG_MAX;
112111
struct em_perf_state *table;
113112
int i, ret;
114113
u64 fmax;
@@ -153,27 +152,21 @@ static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
153152

154153
table[i].power = power;
155154
table[i].frequency = prev_freq = freq;
156-
157-
/*
158-
* The hertz/watts efficiency ratio should decrease as the
159-
* frequency grows on sane platforms. But this isn't always
160-
* true in practice so warn the user if a higher OPP is more
161-
* power efficient than a lower one.
162-
*/
163-
opp_eff = freq / power;
164-
if (opp_eff >= prev_opp_eff)
165-
dev_dbg(dev, "EM: hertz/watts ratio non-monotonically decreasing: em_perf_state %d >= em_perf_state%d\n",
166-
i, i - 1);
167-
prev_opp_eff = opp_eff;
168155
}
169156

170157
/* Compute the cost of each performance state. */
171158
fmax = (u64) table[nr_states - 1].frequency;
172-
for (i = 0; i < nr_states; i++) {
159+
for (i = nr_states - 1; i >= 0; i--) {
173160
unsigned long power_res = em_scale_power(table[i].power);
174161

175162
table[i].cost = div64_u64(fmax * power_res,
176163
table[i].frequency);
164+
if (table[i].cost >= prev_cost) {
165+
dev_dbg(dev, "EM: OPP:%lu is inefficient\n",
166+
table[i].frequency);
167+
} else {
168+
prev_cost = table[i].cost;
169+
}
177170
}
178171

179172
pd->table = table;

0 commit comments

Comments
 (0)