History

PM: EM: Mark inefficient states

Some SoCs, such as the sd855 have OPPs within the same performance domain, whose cost is higher than others with a higher frequency. Even though those OPPs are interesting from a cooling perspective, it makes no sense to use them when the device can run at full capacity. Those OPPs handicap the performance domain, when choosing the most energy-efficient CPU and are wasting energy. They are inefficient. Hence, add support for such OPPs to the Energy Model. The table can now be read skipping inefficient performance states (and by extension, inefficient OPPs).

Vincent Donnefort committed 5 years ago

Commit c8ed9951 parent aa1a4322 files · +15 −1Browse files

Unified · Split

2 files
  1. include/linux/energy_model.h +12 −0
  2. kernel/power/energy_model.c +3 −1
include/linux/energy_model.h+12−0
@@ -17,13 +17,25 @@ · 16 unmodified lines
17 * device). It can be a total power: static and dynamic.17 * device). It can be a total power: static and dynamic.
18 * @cost: The cost coefficient associated with this level, used during18 * @cost: The cost coefficient associated with this level, used during
19 * energy calculation. Equal to: power * max_frequency / frequency19 * energy calculation. Equal to: power * max_frequency / frequency
20 * @flags: see "em_perf_state flags" description below.
20 */21 */
21struct em_perf_state {22struct em_perf_state {
22 unsigned long frequency;23 unsigned long frequency;
23 unsigned long power;24 unsigned long power;
24 unsigned long cost;25 unsigned long cost;
26 unsigned long flags;
25};27};
26 28
29/*
30 * em_perf_state flags:
31 *
32 * EM_PERF_STATE_INEFFICIENT: The performance state is inefficient. There is
33 * in this em_perf_domain, another performance state with a higher frequency
34 * but a lower or equal power cost. Such inefficient states are ignored when
35 * using em_pd_get_efficient_*() functions.
36 */
37#define EM_PERF_STATE_INEFFICIENT BIT(0)
38
27/**39/**
28 * struct em_perf_domain - Performance domain40 * struct em_perf_domain - Performance domain
29 * @table: List of performance states, in ascending order41 * @table: List of performance states, in ascending order
kernel/power/energy_model.c+3−1
@@ -2,7 +2,7 @@ · 1 unmodified line
2/*2/*
3 * Energy Model of devices3 * Energy Model of devices
4 *4 *
5 * Copyright (c) 2018-2020, Arm ltd.5 * Copyright (c) 2018-2021, Arm ltd.
6 * Written by: Quentin Perret, Arm ltd.6 * Written by: Quentin Perret, Arm ltd.
7 * Improvements provided by: Lukasz Luba, Arm ltd.7 * Improvements provided by: Lukasz Luba, Arm ltd.
8 */8 */
@@ -42,6 +42,7 @@ static void em_debug_create_ps(struct em_perf_state *ps, struct dentry *pd) · 33 unmodified lines
42 debugfs_create_ulong("frequency", 0444, d, &ps->frequency);42 debugfs_create_ulong("frequency", 0444, d, &ps->frequency);
43 debugfs_create_ulong("power", 0444, d, &ps->power);43 debugfs_create_ulong("power", 0444, d, &ps->power);
44 debugfs_create_ulong("cost", 0444, d, &ps->cost);44 debugfs_create_ulong("cost", 0444, d, &ps->cost);
45 debugfs_create_ulong("inefficient", 0444, d, &ps->flags);
45}46}
46 47
47static int em_debug_cpus_show(struct seq_file *s, void *unused)48static int em_debug_cpus_show(struct seq_file *s, void *unused)
@@ -162,6 +163,7 @@ static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd, · 114 unmodified lines
162 table[i].cost = div64_u64(fmax * power_res,163 table[i].cost = div64_u64(fmax * power_res,
163 table[i].frequency);164 table[i].frequency);
164 if (table[i].cost >= prev_cost) {165 if (table[i].cost >= prev_cost) {
166 table[i].flags = EM_PERF_STATE_INEFFICIENT;
165 dev_dbg(dev, "EM: OPP:%lu is inefficient\n",167 dev_dbg(dev, "EM: OPP:%lu is inefficient\n",
166 table[i].frequency);168 table[i].frequency);
167 } else {169 } else {