Skip to content

Commit bf56b90

Browse files
committed
Merge branches 'pm-em' and 'powercap'
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
3 parents 8e5b477 + 6215a5d + 3b4bd49 commit bf56b90

File tree

15 files changed

+473
-235
lines changed

15 files changed

+473
-235
lines changed

drivers/cpufreq/acpi-cpufreq.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,8 @@ static unsigned int acpi_cpufreq_fast_switch(struct cpufreq_policy *policy,
470470
if (policy->cached_target_freq == target_freq)
471471
index = policy->cached_resolved_idx;
472472
else
473-
index = cpufreq_table_find_index_dl(policy, target_freq);
473+
index = cpufreq_table_find_index_dl(policy, target_freq,
474+
false);
474475

475476
entry = &policy->freq_table[index];
476477
next_freq = entry->frequency;

drivers/cpufreq/amd_freq_sensitivity.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ static unsigned int amd_powersave_bias_target(struct cpufreq_policy *policy,
9191
unsigned int index;
9292

9393
index = cpufreq_table_find_index_h(policy,
94-
policy->cur - 1);
94+
policy->cur - 1,
95+
relation & CPUFREQ_RELATION_E);
9596
freq_next = policy->freq_table[index].frequency;
9697
}
9798

drivers/cpufreq/cpufreq.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ static unsigned int __resolve_freq(struct cpufreq_policy *policy,
554554
unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy,
555555
unsigned int target_freq)
556556
{
557-
return __resolve_freq(policy, target_freq, CPUFREQ_RELATION_L);
557+
return __resolve_freq(policy, target_freq, CPUFREQ_RELATION_LE);
558558
}
559559
EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq);
560560

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

2263-
if (cpufreq_driver->target)
2263+
if (cpufreq_driver->target) {
2264+
/*
2265+
* If the driver hasn't setup a single inefficient frequency,
2266+
* it's unlikely it knows how to decode CPUFREQ_RELATION_E.
2267+
*/
2268+
if (!policy->efficiencies_available)
2269+
relation &= ~CPUFREQ_RELATION_E;
2270+
22642271
return cpufreq_driver->target(policy, target_freq, relation);
2272+
}
22652273

22662274
if (!cpufreq_driver->target_index)
22672275
return -EINVAL;
@@ -2523,8 +2531,15 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
25232531
if (ret)
25242532
return ret;
25252533

2534+
/*
2535+
* Resolve policy min/max to available frequencies. It ensures
2536+
* no frequency resolution will neither overshoot the requested maximum
2537+
* nor undershoot the requested minimum.
2538+
*/
25262539
policy->min = new_data.min;
25272540
policy->max = new_data.max;
2541+
policy->min = __resolve_freq(policy, policy->min, CPUFREQ_RELATION_L);
2542+
policy->max = __resolve_freq(policy, policy->max, CPUFREQ_RELATION_H);
25282543
trace_cpu_frequency_limits(policy);
25292544

25302545
policy->cached_target_freq = UINT_MAX;

drivers/cpufreq/cpufreq_conservative.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
111111
if (requested_freq > policy->max)
112112
requested_freq = policy->max;
113113

114-
__cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_H);
114+
__cpufreq_driver_target(policy, requested_freq,
115+
CPUFREQ_RELATION_HE);
115116
dbs_info->requested_freq = requested_freq;
116117
goto out;
117118
}
@@ -134,7 +135,8 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
134135
else
135136
requested_freq = policy->min;
136137

137-
__cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_L);
138+
__cpufreq_driver_target(policy, requested_freq,
139+
CPUFREQ_RELATION_LE);
138140
dbs_info->requested_freq = requested_freq;
139141
}
140142

drivers/cpufreq/cpufreq_ondemand.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,11 @@ static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy,
8383
freq_avg = freq_req - freq_reduc;
8484

8585
/* Find freq bounds for freq_avg in freq_table */
86-
index = cpufreq_table_find_index_h(policy, freq_avg);
86+
index = cpufreq_table_find_index_h(policy, freq_avg,
87+
relation & CPUFREQ_RELATION_E);
8788
freq_lo = freq_table[index].frequency;
88-
index = cpufreq_table_find_index_l(policy, freq_avg);
89+
index = cpufreq_table_find_index_l(policy, freq_avg,
90+
relation & CPUFREQ_RELATION_E);
8991
freq_hi = freq_table[index].frequency;
9092

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

119121
if (od_tuners->powersave_bias)
120122
freq = od_ops.powersave_bias_target(policy, freq,
121-
CPUFREQ_RELATION_H);
123+
CPUFREQ_RELATION_HE);
122124
else if (policy->cur == policy->max)
123125
return;
124126

125127
__cpufreq_driver_target(policy, freq, od_tuners->powersave_bias ?
126-
CPUFREQ_RELATION_L : CPUFREQ_RELATION_H);
128+
CPUFREQ_RELATION_LE : CPUFREQ_RELATION_HE);
127129
}
128130

129131
/*
@@ -161,9 +163,9 @@ static void od_update(struct cpufreq_policy *policy)
161163
if (od_tuners->powersave_bias)
162164
freq_next = od_ops.powersave_bias_target(policy,
163165
freq_next,
164-
CPUFREQ_RELATION_L);
166+
CPUFREQ_RELATION_LE);
165167

166-
__cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_C);
168+
__cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_CE);
167169
}
168170
}
169171

@@ -182,7 +184,7 @@ static unsigned int od_dbs_update(struct cpufreq_policy *policy)
182184
*/
183185
if (sample_type == OD_SUB_SAMPLE && policy_dbs->sample_delay_ns > 0) {
184186
__cpufreq_driver_target(policy, dbs_info->freq_lo,
185-
CPUFREQ_RELATION_H);
187+
CPUFREQ_RELATION_HE);
186188
return dbs_info->freq_lo_delay_us;
187189
}
188190

drivers/cpufreq/mediatek-cpufreq-hw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
109109
struct mtk_cpufreq_data *data = policy->driver_data;
110110
unsigned int index;
111111

112-
index = cpufreq_table_find_index_dl(policy, target_freq);
112+
index = cpufreq_table_find_index_dl(policy, target_freq, false);
113113

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

drivers/cpufreq/powernv-cpufreq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ static void powernv_cpufreq_work_fn(struct work_struct *work)
934934
policy = cpufreq_cpu_get(cpu);
935935
if (!policy)
936936
continue;
937-
index = cpufreq_table_find_index_c(policy, policy->cur);
937+
index = cpufreq_table_find_index_c(policy, policy->cur, false);
938938
powernv_cpufreq_target_index(policy, index);
939939
cpumask_andnot(&mask, &mask, policy->cpus);
940940
cpufreq_cpu_put(policy);
@@ -1022,7 +1022,7 @@ static unsigned int powernv_fast_switch(struct cpufreq_policy *policy,
10221022
int index;
10231023
struct powernv_smp_call_data freq_data;
10241024

1025-
index = cpufreq_table_find_index_dl(policy, target_freq);
1025+
index = cpufreq_table_find_index_dl(policy, target_freq, false);
10261026
freq_data.pstate_id = powernv_freqs[index].driver_data;
10271027
freq_data.gpstate_id = powernv_freqs[index].driver_data;
10281028
set_pstate(&freq_data);

drivers/cpufreq/s5pv210-cpufreq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index)
243243
new_freq = s5pv210_freq_table[index].frequency;
244244

245245
/* Finding current running level index */
246-
priv_index = cpufreq_table_find_index_h(policy, old_freq);
246+
priv_index = cpufreq_table_find_index_h(policy, old_freq, false);
247247

248248
arm_volt = dvs_conf[index].arm_volt;
249249
int_volt = dvs_conf[index].int_volt;

drivers/powercap/dtpm.c

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@ static void __dtpm_sub_power(struct dtpm *dtpm)
116116
parent->power_limit -= dtpm->power_limit;
117117
parent = parent->parent;
118118
}
119-
120-
__dtpm_rebalance_weight(root);
121119
}
122120

123121
static void __dtpm_add_power(struct dtpm *dtpm)
@@ -130,45 +128,45 @@ static void __dtpm_add_power(struct dtpm *dtpm)
130128
parent->power_limit += dtpm->power_limit;
131129
parent = parent->parent;
132130
}
131+
}
132+
133+
static int __dtpm_update_power(struct dtpm *dtpm)
134+
{
135+
int ret;
136+
137+
__dtpm_sub_power(dtpm);
138+
139+
ret = dtpm->ops->update_power_uw(dtpm);
140+
if (ret)
141+
pr_err("Failed to update power for '%s': %d\n",
142+
dtpm->zone.name, ret);
133143

134-
__dtpm_rebalance_weight(root);
144+
if (!test_bit(DTPM_POWER_LIMIT_FLAG, &dtpm->flags))
145+
dtpm->power_limit = dtpm->power_max;
146+
147+
__dtpm_add_power(dtpm);
148+
149+
if (root)
150+
__dtpm_rebalance_weight(root);
151+
152+
return ret;
135153
}
136154

137155
/**
138156
* dtpm_update_power - Update the power on the dtpm
139157
* @dtpm: a pointer to a dtpm structure to update
140-
* @power_min: a u64 representing the new power_min value
141-
* @power_max: a u64 representing the new power_max value
142158
*
143159
* Function to update the power values of the dtpm node specified in
144160
* parameter. These new values will be propagated to the tree.
145161
*
146162
* Return: zero on success, -EINVAL if the values are inconsistent
147163
*/
148-
int dtpm_update_power(struct dtpm *dtpm, u64 power_min, u64 power_max)
164+
int dtpm_update_power(struct dtpm *dtpm)
149165
{
150-
int ret = 0;
166+
int ret;
151167

152168
mutex_lock(&dtpm_lock);
153-
154-
if (power_min == dtpm->power_min && power_max == dtpm->power_max)
155-
goto unlock;
156-
157-
if (power_max < power_min) {
158-
ret = -EINVAL;
159-
goto unlock;
160-
}
161-
162-
__dtpm_sub_power(dtpm);
163-
164-
dtpm->power_min = power_min;
165-
dtpm->power_max = power_max;
166-
if (!test_bit(DTPM_POWER_LIMIT_FLAG, &dtpm->flags))
167-
dtpm->power_limit = power_max;
168-
169-
__dtpm_add_power(dtpm);
170-
171-
unlock:
169+
ret = __dtpm_update_power(dtpm);
172170
mutex_unlock(&dtpm_lock);
173171

174172
return ret;
@@ -359,24 +357,18 @@ static struct powercap_zone_ops zone_ops = {
359357
};
360358

361359
/**
362-
* dtpm_alloc - Allocate and initialize a dtpm struct
363-
* @name: a string specifying the name of the node
364-
*
365-
* Return: a struct dtpm pointer, NULL in case of error
360+
* dtpm_init - Allocate and initialize a dtpm struct
361+
* @dtpm: The dtpm struct pointer to be initialized
362+
* @ops: The dtpm device specific ops, NULL for a virtual node
366363
*/
367-
struct dtpm *dtpm_alloc(struct dtpm_ops *ops)
364+
void dtpm_init(struct dtpm *dtpm, struct dtpm_ops *ops)
368365
{
369-
struct dtpm *dtpm;
370-
371-
dtpm = kzalloc(sizeof(*dtpm), GFP_KERNEL);
372366
if (dtpm) {
373367
INIT_LIST_HEAD(&dtpm->children);
374368
INIT_LIST_HEAD(&dtpm->sibling);
375369
dtpm->weight = 1024;
376370
dtpm->ops = ops;
377371
}
378-
379-
return dtpm;
380372
}
381373

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

437429
if (dtpm->ops && !(dtpm->ops->set_power_uw &&
438430
dtpm->ops->get_power_uw &&
431+
dtpm->ops->update_power_uw &&
439432
dtpm->ops->release))
440433
return -EINVAL;
441434

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

458-
__dtpm_add_power(dtpm);
451+
if (dtpm->ops && !dtpm->ops->update_power_uw(dtpm)) {
452+
__dtpm_add_power(dtpm);
453+
dtpm->power_limit = dtpm->power_max;
454+
}
459455

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

468-
static int __init dtpm_init(void)
464+
static int __init init_dtpm(void)
469465
{
470-
struct dtpm_descr **dtpm_descr;
466+
struct dtpm_descr *dtpm_descr;
471467

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

478474
for_each_dtpm_table(dtpm_descr)
479-
(*dtpm_descr)->init(*dtpm_descr);
475+
dtpm_descr->init();
480476

481477
return 0;
482478
}
483-
late_initcall(dtpm_init);
479+
late_initcall(init_dtpm);

0 commit comments

Comments
 (0)