Skip to content

Commit e458716

Browse files
Vincent Donnefortrafaeljw
authored andcommitted
PM: EM: Mark inefficiencies in CPUFreq
The Energy Model has a 1:1 mapping between OPPs and performance states (em_perf_state). If a CPUFreq driver registers an Energy Model, inefficiencies found by the latter can be applied to CPUFreq. Signed-off-by: Vincent Donnefort <[email protected]> Acked-by: Viresh Kumar <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent b894d20 commit e458716

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

kernel/power/energy_model.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define pr_fmt(fmt) "energy_model: " fmt
1111

1212
#include <linux/cpu.h>
13+
#include <linux/cpufreq.h>
1314
#include <linux/cpumask.h>
1415
#include <linux/debugfs.h>
1516
#include <linux/energy_model.h>
@@ -231,6 +232,43 @@ static int em_create_pd(struct device *dev, int nr_states,
231232
return 0;
232233
}
233234

235+
static void em_cpufreq_update_efficiencies(struct device *dev)
236+
{
237+
struct em_perf_domain *pd = dev->em_pd;
238+
struct em_perf_state *table;
239+
struct cpufreq_policy *policy;
240+
int found = 0;
241+
int i;
242+
243+
if (!_is_cpu_device(dev) || !pd)
244+
return;
245+
246+
policy = cpufreq_cpu_get(cpumask_first(em_span_cpus(pd)));
247+
if (!policy) {
248+
dev_warn(dev, "EM: Access to CPUFreq policy failed");
249+
return;
250+
}
251+
252+
table = pd->table;
253+
254+
for (i = 0; i < pd->nr_perf_states; i++) {
255+
if (!(table[i].flags & EM_PERF_STATE_INEFFICIENT))
256+
continue;
257+
258+
if (!cpufreq_table_set_inefficient(policy, table[i].frequency))
259+
found++;
260+
}
261+
262+
if (!found)
263+
return;
264+
265+
/*
266+
* Efficiencies have been installed in CPUFreq, inefficient frequencies
267+
* will be skipped. The EM can do the same.
268+
*/
269+
pd->flags |= EM_PERF_DOMAIN_SKIP_INEFFICIENCIES;
270+
}
271+
234272
/**
235273
* em_pd_get() - Return the performance domain for a device
236274
* @dev : Device to find the performance domain for
@@ -347,6 +385,8 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
347385
if (milliwatts)
348386
dev->em_pd->flags |= EM_PERF_DOMAIN_MILLIWATTS;
349387

388+
em_cpufreq_update_efficiencies(dev);
389+
350390
em_debug_create_pd(dev);
351391
dev_info(dev, "EM: created perf domain\n");
352392

0 commit comments

Comments
 (0)