forked from mirrors/linux
- Manage sysfs attributes and boost frequencies efficiently from
cpufreq core to reduce boilerplate code in drivers (Viresh Kumar).
- Minor cleanups to cpufreq drivers (Aaron Kling, Benjamin Schneider,
Dhananjay Ugwekar, Imran Shaik, zuoqian).
- Migrate some cpufreq drivers to using for_each_present_cpu() (Jacky
Bai).
- cpufreq-qcom-hw DT binding fixes (Krzysztof Kozlowski).
- Use str_enable_disable() helper in cpufreq_online() (Lifeng Zheng).
- Optimize the amd-pstate driver to avoid cases where call paths end
up calling the same writes multiple times and needlessly caching
variables through code reorganization, locking overhaul and tracing
adjustments (Mario Limonciello, Dhananjay Ugwekar).
- Make it possible to avoid enabling capacity-aware scheduling (CAS) in
the intel_pstate driver and relocate a check for out-of-band (OOB)
platform handling in it to make it detect OOB before checking HWP
availability (Rafael Wysocki).
- Fix dbs_update() to avoid inadvertent conversions of negative integer
values to unsigned int which causes CPU frequency selection to be
inaccurate in some cases when the "conservative" cpufreq governor is
in use (Jie Zhan).
- Update the handling of the most recent idle intervals in the menu
cpuidle governor to prevent useful information from being discarded
by it in some cases and improve the prediction accuracy (Rafael
Wysocki).
- Make it possible to tell the intel_idle driver to ignore its built-in
table of idle states for the given processor, clean up the handling
of auto-demotion disabling on Baytrail and Cherrytrail chips in it,
and update its MAINTAINERS entry (David Arcari, Artem Bityutskiy,
Rafael Wysocki).
- Make some cpuidle drivers use for_each_present_cpu() instead of
for_each_possible_cpu() during initialization to avoid issues
occurring when nosmp or maxcpus=0 are used (Jacky Bai).
- Clean up the Energy Model handling code somewhat (Rafael Wysocki).
- Use kfree_rcu() to simplify the handling of runtime Energy Model
updates (Li RongQing).
- Add an entry for the Energy Model framework to MAINTAINERS as
properly maintained (Lukasz Luba).
- Address RCU-related sparse warnings in the Energy Model code (Rafael
Wysocki).
- Remove ENERGY_MODEL dependency on SMP and allow it to be selected
when DEVFREQ is set without CPUFREQ so it can be used on a wider
range of systems (Jeson Gao).
- Unify error handling during runtime suspend and runtime resume in the
core to help drivers to implement more consistent runtime PM error
handling (Rafael Wysocki).
- Drop a redundant check from pm_runtime_force_resume() and rearrange
documentation related to __pm_runtime_disable() (Rafael Wysocki).
- Rework the handling of the "smart suspend" driver flag in the PM core
to avoid issues hat may occur when drivers using it depend on some
other drivers and clean up the related PM core code (Rafael Wysocki,
Colin Ian King).
- Fix the handling of devices with the power.direct_complete flag set
if device_suspend() returns an error for at least one device to avoid
situations in which some of them may not be resumed (Rafael Wysocki).
- Use mutex_trylock() in hibernate_compressor_param_set() to avoid a
possible deadlock that may occur if the "compressor" hibernation
module parameter is accessed during the registration of a new
ieee80211 device (Lizhi Xu).
- Suppress sleeping parent warning in device_pm_add() in the case when
new children are added under a device with the power.direct_complete
set after it has been processed by device_resume() (Xu Yang).
- Remove needless return in three void functions related to system
wakeup (Zijun Hu).
- Replace deprecated kmap_atomic() with kmap_local_page() in the
hibernation core code (David Reaver).
- Remove unused helper functions related to system sleep (David Alan
Gilbert).
- Clean up s2idle_enter() so it does not lock and unlock CPU offline
in vain and update comments in it (Ulf Hansson).
- Clean up broken white space in dpm_wait_for_children() (Geert
Uytterhoeven).
- Update the cpupower utility to fix lib version-ing in it and memory
leaks in error legs, remove hard-coded values, and implement CPU
physical core querying (Thomas Renninger, John B. Wyatt IV, Shuah
Khan, Yiwei Lin, Zhongqiu Han).
-----BEGIN PGP SIGNATURE-----
iQFGBAABCAAwFiEEcM8Aw/RY0dgsiRUR7l+9nS/U47UFAmfhhTYSHHJqd0Byand5
c29ja2kubmV0AAoJEO5fvZ0v1OO16/gIAKuRiG1fFgUcUSXC1iFu42vrB/1i4wpA
02GICACqM3K6/5jd3ct/WOU28GUgDs+xcmqH7CnMaM6y9nXEWjWarmSfFekAO+0q
TPtQ7xTy0hBCB3he1P2uLKBJBin4Wn47U9/rvs4J7mQd5zDxTINKIiVoHg2lEE+s
HAeSoNRb2sp5IZDm9+/LfhHNYRP1mJ97cbZlymqctGB3xgDL7qMLid/1+gFPHAQS
4/LXj3IgyU8DpA/j5nhtpaAqjN5g2QxIUfQgADRIcESK99Y/7aAMs1/G0WhJKaay
9yx+4/xmkGvVCZQx1DphksFLISEzltY0SFWLsoppPzBTGVEW2GQQsNI=
=LqVy
-----END PGP SIGNATURE-----
Merge tag 'pm-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki:
"These are dominated by cpufreq updates which in turn are dominated by
updates related to boost support in the core and drivers and
amd-pstate driver optimizations.
Apart from the above, there are some cpuidle updates including a
rework of the most recent idle intervals handling in the venerable
menu governor that leads to significant improvements in some
performance benchmarks, as the governor is now more likely to predict
a shorter idle duration in some cases, and there are updates of the
core device power management code, mostly related to system suspend
and resume, that should help to avoid potential issues arising when
the drivers of devices depending on one another want to use different
optimizations.
There is also a usual collection of assorted fixes and cleanups,
including removal of some unused code.
Specifics:
- Manage sysfs attributes and boost frequencies efficiently from
cpufreq core to reduce boilerplate code in drivers (Viresh Kumar)
- Minor cleanups to cpufreq drivers (Aaron Kling, Benjamin Schneider,
Dhananjay Ugwekar, Imran Shaik, zuoqian)
- Migrate some cpufreq drivers to using for_each_present_cpu() (Jacky
Bai)
- cpufreq-qcom-hw DT binding fixes (Krzysztof Kozlowski)
- Use str_enable_disable() helper in cpufreq_online() (Lifeng Zheng)
- Optimize the amd-pstate driver to avoid cases where call paths end
up calling the same writes multiple times and needlessly caching
variables through code reorganization, locking overhaul and tracing
adjustments (Mario Limonciello, Dhananjay Ugwekar)
- Make it possible to avoid enabling capacity-aware scheduling (CAS)
in the intel_pstate driver and relocate a check for out-of-band
(OOB) platform handling in it to make it detect OOB before checking
HWP availability (Rafael Wysocki)
- Fix dbs_update() to avoid inadvertent conversions of negative
integer values to unsigned int which causes CPU frequency selection
to be inaccurate in some cases when the "conservative" cpufreq
governor is in use (Jie Zhan)
- Update the handling of the most recent idle intervals in the menu
cpuidle governor to prevent useful information from being discarded
by it in some cases and improve the prediction accuracy (Rafael
Wysocki)
- Make it possible to tell the intel_idle driver to ignore its
built-in table of idle states for the given processor, clean up the
handling of auto-demotion disabling on Baytrail and Cherrytrail
chips in it, and update its MAINTAINERS entry (David Arcari, Artem
Bityutskiy, Rafael Wysocki)
- Make some cpuidle drivers use for_each_present_cpu() instead of
for_each_possible_cpu() during initialization to avoid issues
occurring when nosmp or maxcpus=0 are used (Jacky Bai)
- Clean up the Energy Model handling code somewhat (Rafael Wysocki)
- Use kfree_rcu() to simplify the handling of runtime Energy Model
updates (Li RongQing)
- Add an entry for the Energy Model framework to MAINTAINERS as
properly maintained (Lukasz Luba)
- Address RCU-related sparse warnings in the Energy Model code
(Rafael Wysocki)
- Remove ENERGY_MODEL dependency on SMP and allow it to be selected
when DEVFREQ is set without CPUFREQ so it can be used on a wider
range of systems (Jeson Gao)
- Unify error handling during runtime suspend and runtime resume in
the core to help drivers to implement more consistent runtime PM
error handling (Rafael Wysocki)
- Drop a redundant check from pm_runtime_force_resume() and rearrange
documentation related to __pm_runtime_disable() (Rafael Wysocki)
- Rework the handling of the "smart suspend" driver flag in the PM
core to avoid issues hat may occur when drivers using it depend on
some other drivers and clean up the related PM core code (Rafael
Wysocki, Colin Ian King)
- Fix the handling of devices with the power.direct_complete flag set
if device_suspend() returns an error for at least one device to
avoid situations in which some of them may not be resumed (Rafael
Wysocki)
- Use mutex_trylock() in hibernate_compressor_param_set() to avoid a
possible deadlock that may occur if the "compressor" hibernation
module parameter is accessed during the registration of a new
ieee80211 device (Lizhi Xu)
- Suppress sleeping parent warning in device_pm_add() in the case
when new children are added under a device with the
power.direct_complete set after it has been processed by
device_resume() (Xu Yang)
- Remove needless return in three void functions related to system
wakeup (Zijun Hu)
- Replace deprecated kmap_atomic() with kmap_local_page() in the
hibernation core code (David Reaver)
- Remove unused helper functions related to system sleep (David Alan
Gilbert)
- Clean up s2idle_enter() so it does not lock and unlock CPU offline
in vain and update comments in it (Ulf Hansson)
- Clean up broken white space in dpm_wait_for_children() (Geert
Uytterhoeven)
- Update the cpupower utility to fix lib version-ing in it and memory
leaks in error legs, remove hard-coded values, and implement CPU
physical core querying (Thomas Renninger, John B. Wyatt IV, Shuah
Khan, Yiwei Lin, Zhongqiu Han)"
* tag 'pm-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (139 commits)
PM: sleep: Fix bit masking operation
dt-bindings: cpufreq: cpufreq-qcom-hw: Narrow properties on SDX75, SA8775p and SM8650
dt-bindings: cpufreq: cpufreq-qcom-hw: Drop redundant minItems:1
dt-bindings: cpufreq: cpufreq-qcom-hw: Add missing constraint for interrupt-names
dt-bindings: cpufreq: cpufreq-qcom-hw: Add QCS8300 compatible
cpufreq: Init cpufreq only for present CPUs
PM: sleep: Fix handling devices with direct_complete set on errors
cpuidle: Init cpuidle only for present CPUs
PM: clk: Remove unused pm_clk_remove()
PM: sleep: core: Fix indentation in dpm_wait_for_children()
PM: s2idle: Extend comment in s2idle_enter()
PM: s2idle: Drop redundant locks when entering s2idle
PM: sleep: Remove unused pm_generic_ wrappers
cpufreq: tegra186: Share policy per cluster
cpupower: Make lib versioning scheme more obvious and fix version link
PM: EM: Rework the depends on for CONFIG_ENERGY_MODEL
PM: EM: Address RCU-related sparse warnings
cpupower: Implement CPU physical core querying
pm: cpupower: remove hard-coded topology depth values
pm: cpupower: Fix cmd_monitor() error legs to free cpu_topology
...
409 lines
13 KiB
C
409 lines
13 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LINUX_ENERGY_MODEL_H
|
|
#define _LINUX_ENERGY_MODEL_H
|
|
#include <linux/cpumask.h>
|
|
#include <linux/device.h>
|
|
#include <linux/jump_label.h>
|
|
#include <linux/kobject.h>
|
|
#include <linux/kref.h>
|
|
#include <linux/rcupdate.h>
|
|
#include <linux/sched/cpufreq.h>
|
|
#include <linux/sched/topology.h>
|
|
#include <linux/types.h>
|
|
|
|
/**
|
|
* struct em_perf_state - Performance state of a performance domain
|
|
* @performance: CPU performance (capacity) at a given frequency
|
|
* @frequency: The frequency in KHz, for consistency with CPUFreq
|
|
* @power: The power consumed at this level (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
|
|
* @flags: see "em_perf_state flags" description below.
|
|
*/
|
|
struct em_perf_state {
|
|
unsigned long performance;
|
|
unsigned long frequency;
|
|
unsigned long power;
|
|
unsigned long cost;
|
|
unsigned long flags;
|
|
};
|
|
|
|
/*
|
|
* em_perf_state flags:
|
|
*
|
|
* EM_PERF_STATE_INEFFICIENT: The performance state is inefficient. There is
|
|
* in this em_perf_domain, another performance state with a higher frequency
|
|
* but a lower or equal power cost. Such inefficient states are ignored when
|
|
* using em_pd_get_efficient_*() functions.
|
|
*/
|
|
#define EM_PERF_STATE_INEFFICIENT BIT(0)
|
|
|
|
/**
|
|
* struct em_perf_table - Performance states table
|
|
* @rcu: RCU used for safe access and destruction
|
|
* @kref: Reference counter to track the users
|
|
* @state: List of performance states, in ascending order
|
|
*/
|
|
struct em_perf_table {
|
|
struct rcu_head rcu;
|
|
struct kref kref;
|
|
struct em_perf_state state[];
|
|
};
|
|
|
|
/**
|
|
* struct em_perf_domain - Performance domain
|
|
* @em_table: Pointer to the runtime modifiable em_perf_table
|
|
* @nr_perf_states: Number of performance states
|
|
* @min_perf_state: Minimum allowed Performance State index
|
|
* @max_perf_state: Maximum allowed Performance State index
|
|
* @flags: See "em_perf_domain flags"
|
|
* @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.
|
|
*
|
|
* 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_table __rcu *em_table;
|
|
int nr_perf_states;
|
|
int min_perf_state;
|
|
int max_perf_state;
|
|
unsigned long flags;
|
|
unsigned long cpus[];
|
|
};
|
|
|
|
/*
|
|
* em_perf_domain flags:
|
|
*
|
|
* EM_PERF_DOMAIN_MICROWATTS: The power values are in micro-Watts or some
|
|
* other scale.
|
|
*
|
|
* EM_PERF_DOMAIN_SKIP_INEFFICIENCIES: Skip inefficient states when estimating
|
|
* energy consumption.
|
|
*
|
|
* EM_PERF_DOMAIN_ARTIFICIAL: The power values are artificial and might be
|
|
* created by platform missing real power information
|
|
*/
|
|
#define EM_PERF_DOMAIN_MICROWATTS BIT(0)
|
|
#define EM_PERF_DOMAIN_SKIP_INEFFICIENCIES BIT(1)
|
|
#define EM_PERF_DOMAIN_ARTIFICIAL BIT(2)
|
|
|
|
#define em_span_cpus(em) (to_cpumask((em)->cpus))
|
|
#define em_is_artificial(em) ((em)->flags & EM_PERF_DOMAIN_ARTIFICIAL)
|
|
|
|
#ifdef CONFIG_ENERGY_MODEL
|
|
/*
|
|
* The max power value in micro-Watts. The limit of 64 Watts is set as
|
|
* a safety net to not overflow multiplications on 32bit platforms. The
|
|
* 32bit value limit for total Perf Domain power implies a limit of
|
|
* maximum CPUs in such domain to 64.
|
|
*/
|
|
#define EM_MAX_POWER (64000000) /* 64 Watts */
|
|
|
|
/*
|
|
* To avoid possible energy estimation overflow on 32bit machines add
|
|
* limits to number of CPUs in the Perf. Domain.
|
|
* We are safe on 64bit machine, thus some big number.
|
|
*/
|
|
#ifdef CONFIG_64BIT
|
|
#define EM_MAX_NUM_CPUS 4096
|
|
#else
|
|
#define EM_MAX_NUM_CPUS 16
|
|
#endif
|
|
|
|
struct em_data_callback {
|
|
/**
|
|
* active_power() - Provide power at the next performance state of
|
|
* a device
|
|
* @dev : Device for which we do this operation (can be a CPU)
|
|
* @power : Active power at the performance state
|
|
* (modified)
|
|
* @freq : Frequency at the performance state in kHz
|
|
* (modified)
|
|
*
|
|
* active_power() must find the lowest performance state of 'dev' above
|
|
* 'freq' and update 'power' and 'freq' to the matching active power
|
|
* and frequency.
|
|
*
|
|
* In case of CPUs, the power is the one of a single CPU in the domain,
|
|
* expressed in micro-Watts or an abstract scale. It is expected to
|
|
* fit in the [0, EM_MAX_POWER] range.
|
|
*
|
|
* Return 0 on success.
|
|
*/
|
|
int (*active_power)(struct device *dev, unsigned long *power,
|
|
unsigned long *freq);
|
|
|
|
/**
|
|
* get_cost() - Provide the cost at the given performance state of
|
|
* a device
|
|
* @dev : Device for which we do this operation (can be a CPU)
|
|
* @freq : Frequency at the performance state in kHz
|
|
* @cost : The cost value for the performance state
|
|
* (modified)
|
|
*
|
|
* In case of CPUs, the cost is the one of a single CPU in the domain.
|
|
* It is expected to fit in the [0, EM_MAX_POWER] range due to internal
|
|
* usage in EAS calculation.
|
|
*
|
|
* Return 0 on success, or appropriate error value in case of failure.
|
|
*/
|
|
int (*get_cost)(struct device *dev, unsigned long freq,
|
|
unsigned long *cost);
|
|
};
|
|
#define EM_SET_ACTIVE_POWER_CB(em_cb, cb) ((em_cb).active_power = cb)
|
|
#define EM_ADV_DATA_CB(_active_power_cb, _cost_cb) \
|
|
{ .active_power = _active_power_cb, \
|
|
.get_cost = _cost_cb }
|
|
#define EM_DATA_CB(_active_power_cb) \
|
|
EM_ADV_DATA_CB(_active_power_cb, NULL)
|
|
|
|
struct em_perf_domain *em_cpu_get(int cpu);
|
|
struct em_perf_domain *em_pd_get(struct device *dev);
|
|
int em_dev_update_perf_domain(struct device *dev,
|
|
struct em_perf_table *new_table);
|
|
int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
|
|
const struct em_data_callback *cb,
|
|
const cpumask_t *cpus, bool microwatts);
|
|
void em_dev_unregister_perf_domain(struct device *dev);
|
|
struct em_perf_table *em_table_alloc(struct em_perf_domain *pd);
|
|
void em_table_free(struct em_perf_table *table);
|
|
int em_dev_compute_costs(struct device *dev, struct em_perf_state *table,
|
|
int nr_states);
|
|
int em_dev_update_chip_binning(struct device *dev);
|
|
int em_update_performance_limits(struct em_perf_domain *pd,
|
|
unsigned long freq_min_khz, unsigned long freq_max_khz);
|
|
void em_rebuild_sched_domains(void);
|
|
|
|
/**
|
|
* em_pd_get_efficient_state() - Get an efficient performance state from the EM
|
|
* @table: List of performance states, in ascending order
|
|
* @pd: performance domain for which this must be done
|
|
* @max_util: Max utilization to map with the EM
|
|
*
|
|
* It is called from the scheduler code quite frequently and as a consequence
|
|
* doesn't implement any check.
|
|
*
|
|
* Return: An efficient performance state id, high enough to meet @max_util
|
|
* requirement.
|
|
*/
|
|
static inline int
|
|
em_pd_get_efficient_state(struct em_perf_state *table,
|
|
struct em_perf_domain *pd, unsigned long max_util)
|
|
{
|
|
unsigned long pd_flags = pd->flags;
|
|
int min_ps = pd->min_perf_state;
|
|
int max_ps = pd->max_perf_state;
|
|
struct em_perf_state *ps;
|
|
int i;
|
|
|
|
for (i = min_ps; i <= max_ps; i++) {
|
|
ps = &table[i];
|
|
if (ps->performance >= max_util) {
|
|
if (pd_flags & EM_PERF_DOMAIN_SKIP_INEFFICIENCIES &&
|
|
ps->flags & EM_PERF_STATE_INEFFICIENT)
|
|
continue;
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return max_ps;
|
|
}
|
|
|
|
/**
|
|
* em_cpu_energy() - Estimates the energy consumed by the CPUs of a
|
|
* performance domain
|
|
* @pd : performance domain for which energy has to be estimated
|
|
* @max_util : highest utilization among CPUs of the domain
|
|
* @sum_util : sum of the utilization of all CPUs in the domain
|
|
* @allowed_cpu_cap : maximum allowed CPU capacity for the @pd, which
|
|
* might reflect reduced frequency (due to thermal)
|
|
*
|
|
* This function must be used only for CPU devices. There is no validation,
|
|
* i.e. if the EM is a CPU type and has cpumask allocated. It is called from
|
|
* the scheduler code quite frequently and that is why there is not checks.
|
|
*
|
|
* Return: the sum of the energy consumed by the CPUs of the domain assuming
|
|
* a capacity state satisfying the max utilization of the domain.
|
|
*/
|
|
static inline unsigned long em_cpu_energy(struct em_perf_domain *pd,
|
|
unsigned long max_util, unsigned long sum_util,
|
|
unsigned long allowed_cpu_cap)
|
|
{
|
|
struct em_perf_table *em_table;
|
|
struct em_perf_state *ps;
|
|
int i;
|
|
|
|
WARN_ONCE(!rcu_read_lock_held(), "EM: rcu read lock needed\n");
|
|
|
|
if (!sum_util)
|
|
return 0;
|
|
|
|
/*
|
|
* In order to predict the performance state, map the utilization of
|
|
* the most utilized CPU of the performance domain to a requested
|
|
* performance, like schedutil. Take also into account that the real
|
|
* performance might be set lower (due to thermal capping). Thus, clamp
|
|
* max utilization to the allowed CPU capacity before calculating
|
|
* effective performance.
|
|
*/
|
|
max_util = min(max_util, allowed_cpu_cap);
|
|
|
|
/*
|
|
* Find the lowest performance state of the Energy Model above the
|
|
* requested performance.
|
|
*/
|
|
em_table = rcu_dereference(pd->em_table);
|
|
i = em_pd_get_efficient_state(em_table->state, pd, max_util);
|
|
ps = &em_table->state[i];
|
|
|
|
/*
|
|
* The performance (capacity) of a CPU in the domain at the performance
|
|
* state (ps) can be computed as:
|
|
*
|
|
* ps->freq * scale_cpu
|
|
* ps->performance = -------------------- (1)
|
|
* cpu_max_freq
|
|
*
|
|
* So, ignoring the costs of idle states (which are not available in
|
|
* the EM), the energy consumed by this CPU at that performance state
|
|
* is estimated as:
|
|
*
|
|
* ps->power * cpu_util
|
|
* cpu_nrg = -------------------- (2)
|
|
* ps->performance
|
|
*
|
|
* since 'cpu_util / ps->performance' represents its percentage of busy
|
|
* time.
|
|
*
|
|
* NOTE: Although the result of this computation actually is in
|
|
* units of power, it can be manipulated as an energy value
|
|
* over a scheduling period, since it is assumed to be
|
|
* constant during that interval.
|
|
*
|
|
* By injecting (1) in (2), 'cpu_nrg' can be re-expressed as a product
|
|
* of two terms:
|
|
*
|
|
* ps->power * cpu_max_freq
|
|
* cpu_nrg = ------------------------ * cpu_util (3)
|
|
* ps->freq * scale_cpu
|
|
*
|
|
* The first term is static, and is stored in the em_perf_state struct
|
|
* as 'ps->cost'.
|
|
*
|
|
* Since all CPUs of the domain have the same micro-architecture, they
|
|
* share the same 'ps->cost', and the same CPU capacity. Hence, the
|
|
* total energy of the domain (which is the simple sum of the energy of
|
|
* all of its CPUs) can be factorized as:
|
|
*
|
|
* pd_nrg = ps->cost * \Sum cpu_util (4)
|
|
*/
|
|
return ps->cost * sum_util;
|
|
}
|
|
|
|
/**
|
|
* em_pd_nr_perf_states() - Get the number of performance states of a perf.
|
|
* domain
|
|
* @pd : performance domain for which this must be done
|
|
*
|
|
* Return: the number of performance states in the performance domain table
|
|
*/
|
|
static inline int em_pd_nr_perf_states(struct em_perf_domain *pd)
|
|
{
|
|
return pd->nr_perf_states;
|
|
}
|
|
|
|
/**
|
|
* em_perf_state_from_pd() - Get the performance states table of perf.
|
|
* domain
|
|
* @pd : performance domain for which this must be done
|
|
*
|
|
* To use this function the rcu_read_lock() should be hold. After the usage
|
|
* of the performance states table is finished, the rcu_read_unlock() should
|
|
* be called.
|
|
*
|
|
* Return: the pointer to performance states table of the performance domain
|
|
*/
|
|
static inline
|
|
struct em_perf_state *em_perf_state_from_pd(struct em_perf_domain *pd)
|
|
{
|
|
return rcu_dereference(pd->em_table)->state;
|
|
}
|
|
|
|
#else
|
|
struct em_data_callback {};
|
|
#define EM_ADV_DATA_CB(_active_power_cb, _cost_cb) { }
|
|
#define EM_DATA_CB(_active_power_cb) { }
|
|
#define EM_SET_ACTIVE_POWER_CB(em_cb, cb) do { } while (0)
|
|
|
|
static inline
|
|
int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
|
|
const struct em_data_callback *cb,
|
|
const cpumask_t *cpus, bool microwatts)
|
|
{
|
|
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_cpu_energy(struct em_perf_domain *pd,
|
|
unsigned long max_util, unsigned long sum_util,
|
|
unsigned long allowed_cpu_cap)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int em_pd_nr_perf_states(struct em_perf_domain *pd)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline
|
|
struct em_perf_table *em_table_alloc(struct em_perf_domain *pd)
|
|
{
|
|
return NULL;
|
|
}
|
|
static inline void em_table_free(struct em_perf_table *table) {}
|
|
static inline
|
|
int em_dev_update_perf_domain(struct device *dev,
|
|
struct em_perf_table *new_table)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
static inline
|
|
struct em_perf_state *em_perf_state_from_pd(struct em_perf_domain *pd)
|
|
{
|
|
return NULL;
|
|
}
|
|
static inline
|
|
int em_dev_compute_costs(struct device *dev, struct em_perf_state *table,
|
|
int nr_states)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
static inline int em_dev_update_chip_binning(struct device *dev)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
static inline
|
|
int em_update_performance_limits(struct em_perf_domain *pd,
|
|
unsigned long freq_min_khz, unsigned long freq_max_khz)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
static inline void em_rebuild_sched_domains(void) {}
|
|
#endif
|
|
|
|
#endif
|