Re: [RESEND][PATCH v8 4/8] PM / EM: add support for other devices than CPUs in Energy Model
On 6/24/20 4:21 PM, Rafael J. Wysocki wrote: On Wed, Jun 10, 2020 at 12:12 PM Lukasz Luba wrote: Add support for other devices than CPUs. The registration function does not require a valid cpumask pointer and is ready to handle new devices. Some of the internal structures has been reorganized in order to keep consistent view (like removing per_cpu pd pointers). Signed-off-by: Lukasz Luba --- Hi all, This is just a small change compared to v8 addressing Rafael's comments an Dan's static analyzes. Here are the changes: - added comment about mutex usage in the unregister function - changed 'dev' into @dev in the kerneldoc comments - removed 'else' statement from em_create_pd() to calm down static analizers I've applied the series as 5.9 material with patch [4/8] replaced with this one. Sorry for the delays in handling this! No worries. Thank you very much! Regards, Lukasz Thanks! include/linux/device.h | 5 + include/linux/energy_model.h | 29 - kernel/power/energy_model.c | 244 --- 3 files changed, 194 insertions(+), 84 deletions(-) diff --git a/include/linux/device.h b/include/linux/device.h index ac8e37cd716a..7023d3ea189b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -13,6 +13,7 @@ #define _DEVICE_H_ #include +#include #include #include #include @@ -559,6 +560,10 @@ struct device { struct dev_pm_info power; struct dev_pm_domain*pm_domain; +#ifdef CONFIG_ENERGY_MODEL + struct em_perf_domain *em_pd; +#endif + #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN struct irq_domain *msi_domain; #endif diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h index 7076cb22b247..2d4689964029 100644 --- a/include/linux/energy_model.h +++ b/include/linux/energy_model.h @@ -12,8 +12,10 @@ /** * em_perf_state - Performance state of a performance domain - * @frequency: The CPU frequency in KHz, for consistency with CPUFreq - * @power: The power consumed by 1 CPU at this level, in milli-watts + * @frequency: The frequency in KHz, for consistency with CPUFreq + * @power: The power consumed at this level, in milli-watts (by 1 CPU or + by a registered device). It can be a total power: static and + dynamic. * @cost: The cost coefficient associated with this level, used during * energy calculation. Equal to: power * max_frequency / frequency */ @@ -27,12 +29,16 @@ struct em_perf_state { * em_perf_domain - Performance domain * @table: List of performance states, in ascending order * @nr_perf_states:Number of performance states - * @cpus: Cpumask covering the CPUs of the domain + * @cpus: Cpumask covering the CPUs of the domain. It's here + * for performance reasons to avoid potential cache + * misses during energy calculations in the scheduler + * and simplifies allocating/freeing that memory region. * - * A "performance domain" represents a group of CPUs whose performance is - * scaled together. All CPUs of a performance domain must have the same - * micro-architecture. Performance domains often have a 1-to-1 mapping with - * CPUFreq policies. + * In case of CPU device, a "performance domain" represents a group of CPUs + * whose performance is scaled together. All CPUs of a performance domain + * must have the same micro-architecture. Performance domains often have + * a 1-to-1 mapping with CPUFreq policies. In case of other devices the @cpus + * field is unused. */ struct em_perf_domain { struct em_perf_state *table; @@ -71,10 +77,12 @@ struct em_data_callback { #define EM_DATA_CB(_active_power_cb) { .active_power = &_active_power_cb } struct em_perf_domain *em_cpu_get(int cpu); +struct em_perf_domain *em_pd_get(struct device *dev); int em_register_perf_domain(cpumask_t *span, unsigned int nr_states, struct em_data_callback *cb); int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, struct em_data_callback *cb, cpumask_t *span); +void em_dev_unregister_perf_domain(struct device *dev); /** * em_pd_energy() - Estimates the energy consumed by the CPUs of a perf. domain @@ -184,10 +192,17 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, { return -EINVAL; } +static inline void em_dev_unregister_perf_domain(struct device *dev) +{ +} static inline struct em_perf_domain *em_cpu_get(int cpu) { return NULL; } +static inline struct em_perf_domain *em_pd_get(struct device *dev) +{ + return NULL; +} static inline unsigned long em_pd_energy(struct em_perf_domain *pd, unsigned long max_util, unsigned long sum_util) { diff --git a/kernel/power/energy_model.c b/kernel/pow
Re: [RESEND][PATCH v8 4/8] PM / EM: add support for other devices than CPUs in Energy Model
On Wed, Jun 10, 2020 at 12:12 PM Lukasz Luba wrote: > > Add support for other devices than CPUs. The registration function > does not require a valid cpumask pointer and is ready to handle new > devices. Some of the internal structures has been reorganized in order to > keep consistent view (like removing per_cpu pd pointers). > > Signed-off-by: Lukasz Luba > --- > Hi all, > > This is just a small change compared to v8 addressing Rafael's > comments an Dan's static analyzes. > Here are the changes: > - added comment about mutex usage in the unregister function > - changed 'dev' into @dev in the kerneldoc comments > - removed 'else' statement from em_create_pd() to calm down static analizers I've applied the series as 5.9 material with patch [4/8] replaced with this one. Sorry for the delays in handling this! Thanks! > include/linux/device.h | 5 + > include/linux/energy_model.h | 29 - > kernel/power/energy_model.c | 244 --- > 3 files changed, 194 insertions(+), 84 deletions(-) > > diff --git a/include/linux/device.h b/include/linux/device.h > index ac8e37cd716a..7023d3ea189b 100644 > --- a/include/linux/device.h > +++ b/include/linux/device.h > @@ -13,6 +13,7 @@ > #define _DEVICE_H_ > > #include > +#include > #include > #include > #include > @@ -559,6 +560,10 @@ struct device { > struct dev_pm_info power; > struct dev_pm_domain*pm_domain; > > +#ifdef CONFIG_ENERGY_MODEL > + struct em_perf_domain *em_pd; > +#endif > + > #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN > struct irq_domain *msi_domain; > #endif > diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h > index 7076cb22b247..2d4689964029 100644 > --- a/include/linux/energy_model.h > +++ b/include/linux/energy_model.h > @@ -12,8 +12,10 @@ > > /** > * em_perf_state - Performance state of a performance domain > - * @frequency: The CPU frequency in KHz, for consistency with CPUFreq > - * @power: The power consumed by 1 CPU at this level, in milli-watts > + * @frequency: The frequency in KHz, for consistency with CPUFreq > + * @power: The power consumed at this level, in milli-watts (by 1 CPU or > + by a registered device). It can be a total power: static and > + dynamic. > * @cost: The cost coefficient associated with this level, used during > * energy calculation. Equal to: power * max_frequency / > frequency > */ > @@ -27,12 +29,16 @@ struct em_perf_state { > * em_perf_domain - Performance domain > * @table: List of performance states, in ascending order > * @nr_perf_states:Number of performance states > - * @cpus: Cpumask covering the CPUs of the domain > + * @cpus: Cpumask covering the CPUs of the domain. It's here > + * for performance reasons to avoid potential cache > + * misses during energy calculations in the scheduler > + * and simplifies allocating/freeing that memory region. > * > - * A "performance domain" represents a group of CPUs whose performance is > - * scaled together. All CPUs of a performance domain must have the same > - * micro-architecture. Performance domains often have a 1-to-1 mapping with > - * CPUFreq policies. > + * In case of CPU device, a "performance domain" represents a group of CPUs > + * whose performance is scaled together. All CPUs of a performance domain > + * must have the same micro-architecture. Performance domains often have > + * a 1-to-1 mapping with CPUFreq policies. In case of other devices the @cpus > + * field is unused. > */ > struct em_perf_domain { > struct em_perf_state *table; > @@ -71,10 +77,12 @@ struct em_data_callback { > #define EM_DATA_CB(_active_power_cb) { .active_power = &_active_power_cb } > > struct em_perf_domain *em_cpu_get(int cpu); > +struct em_perf_domain *em_pd_get(struct device *dev); > int em_register_perf_domain(cpumask_t *span, unsigned int nr_states, > struct em_data_callback *cb); > int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, > struct em_data_callback *cb, cpumask_t *span); > +void em_dev_unregister_perf_domain(struct device *dev); > > /** > * em_pd_energy() - Estimates the energy consumed by the CPUs of a perf. > domain > @@ -184,10 +192,17 @@ int em_dev_register_perf_domain(struct device *dev, > unsigned int nr_states, > { > return -EINVAL; > } > +static inline void em_dev_unregister_perf_domain(struct device *dev) > +{ > +} > static inline struct em_perf_domain *em_cpu_get(int cpu) > { > return NULL; > } > +static inline struct em_perf_domain *em_pd_get(struct device *dev) > +{ > + return NULL; > +} > static inline unsigned long em_pd_energy(struct em_perf_domain *pd, > unsigned long max_util, unsigne