Skip to content

Commit bdc21a4

Browse files
lukaszluba-armrafaeljw
authored andcommitted
PM: EM: Add .get_cost() callback
The Energy Model (EM) supports devices which report abstract power scale, not only real Watts. The primary goal for EM is to enable the Energy Aware Scheduler (EAS) for a given platform. Some of the platforms might not be able to deliver proper power values. The only information that they might have is the relative efficiency between CPU types. Thus, it makes sense to remove some restrictions in the EM framework and introduce a mechanism which would support those platforms. What is crucial for EAS to operate is the 'cost' field in the EM. The 'cost' is calculated internally in EM framework based on knowledge from 'power' values. The 'cost' values must be strictly increasing. The existing API with its 'power' value size restrictions cannot guarantee that the 'cost' will meet this requirement. Since the platform is missing this detailed information, but has only efficiency details, introduce a new custom callback in the EM framework. The new callback would allow to provide the 'cost' values which reflect efficiency of the CPUs. This would allow to provide EAS information which has different relation than what would be forced by the EM internal formulas calculating 'cost' values. Thanks to this new callback it is possible to create a system view for EAS which has no overlapping performance states across many Performance Domains. Signed-off-by: Lukasz Luba <lukasz.luba@arm.com> Reviewed-by: Ionela Voinescu <ionela.voinescu@arm.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent ce522ba commit bdc21a4

1 file changed

Lines changed: 23 additions & 1 deletion

File tree

include/linux/energy_model.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,30 @@ struct em_data_callback {
114114
*/
115115
int (*active_power)(unsigned long *power, unsigned long *freq,
116116
struct device *dev);
117+
118+
/**
119+
* get_cost() - Provide the cost at the given performance state of
120+
* a device
121+
* @dev : Device for which we do this operation (can be a CPU)
122+
* @freq : Frequency at the performance state in kHz
123+
* @cost : The cost value for the performance state
124+
* (modified)
125+
*
126+
* In case of CPUs, the cost is the one of a single CPU in the domain.
127+
* It is expected to fit in the [0, EM_MAX_POWER] range due to internal
128+
* usage in EAS calculation.
129+
*
130+
* Return 0 on success, or appropriate error value in case of failure.
131+
*/
132+
int (*get_cost)(struct device *dev, unsigned long freq,
133+
unsigned long *cost);
117134
};
118-
#define EM_DATA_CB(_active_power_cb) { .active_power = &_active_power_cb }
119135
#define EM_SET_ACTIVE_POWER_CB(em_cb, cb) ((em_cb).active_power = cb)
136+
#define EM_ADV_DATA_CB(_active_power_cb, _cost_cb) \
137+
{ .active_power = _active_power_cb, \
138+
.get_cost = _cost_cb }
139+
#define EM_DATA_CB(_active_power_cb) \
140+
EM_ADV_DATA_CB(_active_power_cb, NULL)
120141

121142
struct em_perf_domain *em_cpu_get(int cpu);
122143
struct em_perf_domain *em_pd_get(struct device *dev);
@@ -264,6 +285,7 @@ static inline int em_pd_nr_perf_states(struct em_perf_domain *pd)
264285

265286
#else
266287
struct em_data_callback {};
288+
#define EM_ADV_DATA_CB(_active_power_cb, _cost_cb) { }
267289
#define EM_DATA_CB(_active_power_cb) { }
268290
#define EM_SET_ACTIVE_POWER_CB(em_cb, cb) do { } while (0)
269291

0 commit comments

Comments
 (0)