Skip to content

Commit

Permalink
Merge branches 'pm-em' and 'powercap'
Browse files Browse the repository at this point in the history
Merge Energy Model and power capping updates for 5.16-rc1:

 - Add support for inefficient operating performance points to the
   Energy Model and modify cpufreq to use them properly (Vincent
   Donnefort).

 - Rearrange the DTPM framework code to simplify it and make it easier
   to follow (Daniel Lezcano).

 - Fix power intialization in DTPM (Daniel Lezcano).

 - Add CPU load consideration when estimating the instaneous power
   consumption in DTPM (Daniel Lezcano).

* pm-em:
  cpufreq: mediatek-hw: Fix cpufreq_table_find_index_dl() call
  PM: EM: Mark inefficiencies in CPUFreq
  cpufreq: Use CPUFREQ_RELATION_E in DVFS governors
  cpufreq: Introducing CPUFREQ_RELATION_E
  cpufreq: Add an interface to mark inefficient frequencies
  cpufreq: Make policy min/max hard requirements
  PM: EM: Allow skipping inefficient states
  PM: EM: Extend em_perf_domain with a flag field
  PM: EM: Mark inefficient states
  PM: EM: Fix inefficient states detection

* powercap:
  powercap/drivers/dtpm: Fix power limit initialization
  powercap/drivers/dtpm: Scale the power with the load
  powercap/drivers/dtpm: Use container_of instead of a private data field
  powercap/drivers/dtpm: Simplify the dtpm table
  powercap/drivers/dtpm: Encapsulate even more the code
  • Loading branch information
rafaeljw committed Nov 2, 2021
3 parents 8e5b477 + 6215a5d + 3b4bd49 commit bf56b90
Show file tree
Hide file tree
Showing 15 changed files with 473 additions and 235 deletions.
3 changes: 2 additions & 1 deletion drivers/cpufreq/acpi-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,8 @@ static unsigned int acpi_cpufreq_fast_switch(struct cpufreq_policy *policy,
if (policy->cached_target_freq == target_freq)
index = policy->cached_resolved_idx;
else
index = cpufreq_table_find_index_dl(policy, target_freq);
index = cpufreq_table_find_index_dl(policy, target_freq,
false);

entry = &policy->freq_table[index];
next_freq = entry->frequency;
Expand Down
3 changes: 2 additions & 1 deletion drivers/cpufreq/amd_freq_sensitivity.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ static unsigned int amd_powersave_bias_target(struct cpufreq_policy *policy,
unsigned int index;

index = cpufreq_table_find_index_h(policy,
policy->cur - 1);
policy->cur - 1,
relation & CPUFREQ_RELATION_E);
freq_next = policy->freq_table[index].frequency;
}

Expand Down
19 changes: 17 additions & 2 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ static unsigned int __resolve_freq(struct cpufreq_policy *policy,
unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy,
unsigned int target_freq)
{
return __resolve_freq(policy, target_freq, CPUFREQ_RELATION_L);
return __resolve_freq(policy, target_freq, CPUFREQ_RELATION_LE);
}
EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq);

Expand Down Expand Up @@ -2260,8 +2260,16 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
!(cpufreq_driver->flags & CPUFREQ_NEED_UPDATE_LIMITS))
return 0;

if (cpufreq_driver->target)
if (cpufreq_driver->target) {
/*
* If the driver hasn't setup a single inefficient frequency,
* it's unlikely it knows how to decode CPUFREQ_RELATION_E.
*/
if (!policy->efficiencies_available)
relation &= ~CPUFREQ_RELATION_E;

return cpufreq_driver->target(policy, target_freq, relation);
}

if (!cpufreq_driver->target_index)
return -EINVAL;
Expand Down Expand Up @@ -2523,8 +2531,15 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
if (ret)
return ret;

/*
* Resolve policy min/max to available frequencies. It ensures
* no frequency resolution will neither overshoot the requested maximum
* nor undershoot the requested minimum.
*/
policy->min = new_data.min;
policy->max = new_data.max;
policy->min = __resolve_freq(policy, policy->min, CPUFREQ_RELATION_L);
policy->max = __resolve_freq(policy, policy->max, CPUFREQ_RELATION_H);
trace_cpu_frequency_limits(policy);

policy->cached_target_freq = UINT_MAX;
Expand Down
6 changes: 4 additions & 2 deletions drivers/cpufreq/cpufreq_conservative.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
if (requested_freq > policy->max)
requested_freq = policy->max;

__cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_H);
__cpufreq_driver_target(policy, requested_freq,
CPUFREQ_RELATION_HE);
dbs_info->requested_freq = requested_freq;
goto out;
}
Expand All @@ -134,7 +135,8 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
else
requested_freq = policy->min;

__cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_L);
__cpufreq_driver_target(policy, requested_freq,
CPUFREQ_RELATION_LE);
dbs_info->requested_freq = requested_freq;
}

Expand Down
16 changes: 9 additions & 7 deletions drivers/cpufreq/cpufreq_ondemand.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,11 @@ static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy,
freq_avg = freq_req - freq_reduc;

/* Find freq bounds for freq_avg in freq_table */
index = cpufreq_table_find_index_h(policy, freq_avg);
index = cpufreq_table_find_index_h(policy, freq_avg,
relation & CPUFREQ_RELATION_E);
freq_lo = freq_table[index].frequency;
index = cpufreq_table_find_index_l(policy, freq_avg);
index = cpufreq_table_find_index_l(policy, freq_avg,
relation & CPUFREQ_RELATION_E);
freq_hi = freq_table[index].frequency;

/* Find out how long we have to be in hi and lo freqs */
Expand Down Expand Up @@ -118,12 +120,12 @@ static void dbs_freq_increase(struct cpufreq_policy *policy, unsigned int freq)

if (od_tuners->powersave_bias)
freq = od_ops.powersave_bias_target(policy, freq,
CPUFREQ_RELATION_H);
CPUFREQ_RELATION_HE);
else if (policy->cur == policy->max)
return;

__cpufreq_driver_target(policy, freq, od_tuners->powersave_bias ?
CPUFREQ_RELATION_L : CPUFREQ_RELATION_H);
CPUFREQ_RELATION_LE : CPUFREQ_RELATION_HE);
}

/*
Expand Down Expand Up @@ -161,9 +163,9 @@ static void od_update(struct cpufreq_policy *policy)
if (od_tuners->powersave_bias)
freq_next = od_ops.powersave_bias_target(policy,
freq_next,
CPUFREQ_RELATION_L);
CPUFREQ_RELATION_LE);

__cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_C);
__cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_CE);
}
}

Expand All @@ -182,7 +184,7 @@ static unsigned int od_dbs_update(struct cpufreq_policy *policy)
*/
if (sample_type == OD_SUB_SAMPLE && policy_dbs->sample_delay_ns > 0) {
__cpufreq_driver_target(policy, dbs_info->freq_lo,
CPUFREQ_RELATION_H);
CPUFREQ_RELATION_HE);
return dbs_info->freq_lo_delay_us;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/cpufreq/mediatek-cpufreq-hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
struct mtk_cpufreq_data *data = policy->driver_data;
unsigned int index;

index = cpufreq_table_find_index_dl(policy, target_freq);
index = cpufreq_table_find_index_dl(policy, target_freq, false);

writel_relaxed(index, data->reg_bases[REG_FREQ_PERF_STATE]);

Expand Down
4 changes: 2 additions & 2 deletions drivers/cpufreq/powernv-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ static void powernv_cpufreq_work_fn(struct work_struct *work)
policy = cpufreq_cpu_get(cpu);
if (!policy)
continue;
index = cpufreq_table_find_index_c(policy, policy->cur);
index = cpufreq_table_find_index_c(policy, policy->cur, false);
powernv_cpufreq_target_index(policy, index);
cpumask_andnot(&mask, &mask, policy->cpus);
cpufreq_cpu_put(policy);
Expand Down Expand Up @@ -1022,7 +1022,7 @@ static unsigned int powernv_fast_switch(struct cpufreq_policy *policy,
int index;
struct powernv_smp_call_data freq_data;

index = cpufreq_table_find_index_dl(policy, target_freq);
index = cpufreq_table_find_index_dl(policy, target_freq, false);
freq_data.pstate_id = powernv_freqs[index].driver_data;
freq_data.gpstate_id = powernv_freqs[index].driver_data;
set_pstate(&freq_data);
Expand Down
2 changes: 1 addition & 1 deletion drivers/cpufreq/s5pv210-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index)
new_freq = s5pv210_freq_table[index].frequency;

/* Finding current running level index */
priv_index = cpufreq_table_find_index_h(policy, old_freq);
priv_index = cpufreq_table_find_index_h(policy, old_freq, false);

arm_volt = dvs_conf[index].arm_volt;
int_volt = dvs_conf[index].int_volt;
Expand Down
78 changes: 37 additions & 41 deletions drivers/powercap/dtpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ static void __dtpm_sub_power(struct dtpm *dtpm)
parent->power_limit -= dtpm->power_limit;
parent = parent->parent;
}

__dtpm_rebalance_weight(root);
}

static void __dtpm_add_power(struct dtpm *dtpm)
Expand All @@ -130,45 +128,45 @@ static void __dtpm_add_power(struct dtpm *dtpm)
parent->power_limit += dtpm->power_limit;
parent = parent->parent;
}
}

static int __dtpm_update_power(struct dtpm *dtpm)
{
int ret;

__dtpm_sub_power(dtpm);

ret = dtpm->ops->update_power_uw(dtpm);
if (ret)
pr_err("Failed to update power for '%s': %d\n",
dtpm->zone.name, ret);

__dtpm_rebalance_weight(root);
if (!test_bit(DTPM_POWER_LIMIT_FLAG, &dtpm->flags))
dtpm->power_limit = dtpm->power_max;

__dtpm_add_power(dtpm);

if (root)
__dtpm_rebalance_weight(root);

return ret;
}

/**
* dtpm_update_power - Update the power on the dtpm
* @dtpm: a pointer to a dtpm structure to update
* @power_min: a u64 representing the new power_min value
* @power_max: a u64 representing the new power_max value
*
* Function to update the power values of the dtpm node specified in
* parameter. These new values will be propagated to the tree.
*
* Return: zero on success, -EINVAL if the values are inconsistent
*/
int dtpm_update_power(struct dtpm *dtpm, u64 power_min, u64 power_max)
int dtpm_update_power(struct dtpm *dtpm)
{
int ret = 0;
int ret;

mutex_lock(&dtpm_lock);

if (power_min == dtpm->power_min && power_max == dtpm->power_max)
goto unlock;

if (power_max < power_min) {
ret = -EINVAL;
goto unlock;
}

__dtpm_sub_power(dtpm);

dtpm->power_min = power_min;
dtpm->power_max = power_max;
if (!test_bit(DTPM_POWER_LIMIT_FLAG, &dtpm->flags))
dtpm->power_limit = power_max;

__dtpm_add_power(dtpm);

unlock:
ret = __dtpm_update_power(dtpm);
mutex_unlock(&dtpm_lock);

return ret;
Expand Down Expand Up @@ -359,24 +357,18 @@ static struct powercap_zone_ops zone_ops = {
};

/**
* dtpm_alloc - Allocate and initialize a dtpm struct
* @name: a string specifying the name of the node
*
* Return: a struct dtpm pointer, NULL in case of error
* dtpm_init - Allocate and initialize a dtpm struct
* @dtpm: The dtpm struct pointer to be initialized
* @ops: The dtpm device specific ops, NULL for a virtual node
*/
struct dtpm *dtpm_alloc(struct dtpm_ops *ops)
void dtpm_init(struct dtpm *dtpm, struct dtpm_ops *ops)
{
struct dtpm *dtpm;

dtpm = kzalloc(sizeof(*dtpm), GFP_KERNEL);
if (dtpm) {
INIT_LIST_HEAD(&dtpm->children);
INIT_LIST_HEAD(&dtpm->sibling);
dtpm->weight = 1024;
dtpm->ops = ops;
}

return dtpm;
}

/**
Expand Down Expand Up @@ -436,6 +428,7 @@ int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent)

if (dtpm->ops && !(dtpm->ops->set_power_uw &&
dtpm->ops->get_power_uw &&
dtpm->ops->update_power_uw &&
dtpm->ops->release))
return -EINVAL;

Expand All @@ -455,7 +448,10 @@ int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent)
root = dtpm;
}

__dtpm_add_power(dtpm);
if (dtpm->ops && !dtpm->ops->update_power_uw(dtpm)) {
__dtpm_add_power(dtpm);
dtpm->power_limit = dtpm->power_max;
}

pr_info("Registered dtpm node '%s' / %llu-%llu uW, \n",
dtpm->zone.name, dtpm->power_min, dtpm->power_max);
Expand All @@ -465,9 +461,9 @@ int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent)
return 0;
}

static int __init dtpm_init(void)
static int __init init_dtpm(void)
{
struct dtpm_descr **dtpm_descr;
struct dtpm_descr *dtpm_descr;

pct = powercap_register_control_type(NULL, "dtpm", NULL);
if (IS_ERR(pct)) {
Expand All @@ -476,8 +472,8 @@ static int __init dtpm_init(void)
}

for_each_dtpm_table(dtpm_descr)
(*dtpm_descr)->init(*dtpm_descr);
dtpm_descr->init();

return 0;
}
late_initcall(dtpm_init);
late_initcall(init_dtpm);
Loading

0 comments on commit bf56b90

Please sign in to comment.