Skip to content

Commit

Permalink
drivers/thermal/cpufreq_cooling: Use new Energy Model interface
Browse files Browse the repository at this point in the history
Energy Model framework support modifications at runtime of the power
values. Use the new EM table which is protected with RCU. Align the
code so that this RCU read section is short.

This change is not expected to alter the general functionality.

Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Lukasz Luba authored and Rafael J. Wysocki committed Feb 8, 2024
1 parent 27d2c37 commit 207472b
Showing 1 changed file with 37 additions and 8 deletions.
45 changes: 37 additions & 8 deletions drivers/thermal/cpufreq_cooling.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,48 +91,62 @@ struct cpufreq_cooling_device {
static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_cdev,
unsigned int freq)
{
struct em_perf_state *table;
int i;

rcu_read_lock();
table = em_perf_state_from_pd(cpufreq_cdev->em);
for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
if (freq > cpufreq_cdev->em->table[i].frequency)
if (freq > table[i].frequency)
break;
}
rcu_read_unlock();

return cpufreq_cdev->max_level - i - 1;
}

static u32 cpu_freq_to_power(struct cpufreq_cooling_device *cpufreq_cdev,
u32 freq)
{
struct em_perf_state *table;
unsigned long power_mw;
int i;

rcu_read_lock();
table = em_perf_state_from_pd(cpufreq_cdev->em);
for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
if (freq > cpufreq_cdev->em->table[i].frequency)
if (freq > table[i].frequency)
break;
}

power_mw = cpufreq_cdev->em->table[i + 1].power;
power_mw = table[i + 1].power;
power_mw /= MICROWATT_PER_MILLIWATT;
rcu_read_unlock();

return power_mw;
}

static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev,
u32 power)
{
struct em_perf_state *table;
unsigned long em_power_mw;
u32 freq;
int i;

rcu_read_lock();
table = em_perf_state_from_pd(cpufreq_cdev->em);
for (i = cpufreq_cdev->max_level; i > 0; i--) {
/* Convert EM power to milli-Watts to make safe comparison */
em_power_mw = cpufreq_cdev->em->table[i].power;
em_power_mw = table[i].power;
em_power_mw /= MICROWATT_PER_MILLIWATT;
if (power >= em_power_mw)
break;
}
freq = table[i].frequency;
rcu_read_unlock();

return cpufreq_cdev->em->table[i].frequency;
return freq;
}

/**
Expand Down Expand Up @@ -262,8 +276,9 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
static int cpufreq_state2power(struct thermal_cooling_device *cdev,
unsigned long state, u32 *power)
{
unsigned int freq, num_cpus, idx;
struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
unsigned int freq, num_cpus, idx;
struct em_perf_state *table;

/* Request state should be less than max_level */
if (state > cpufreq_cdev->max_level)
Expand All @@ -272,7 +287,12 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev,
num_cpus = cpumask_weight(cpufreq_cdev->policy->cpus);

idx = cpufreq_cdev->max_level - state;
freq = cpufreq_cdev->em->table[idx].frequency;

rcu_read_lock();
table = em_perf_state_from_pd(cpufreq_cdev->em);
freq = table[idx].frequency;
rcu_read_unlock();

*power = cpu_freq_to_power(cpufreq_cdev, freq) * num_cpus;

return 0;
Expand Down Expand Up @@ -378,8 +398,17 @@ static unsigned int get_state_freq(struct cpufreq_cooling_device *cpufreq_cdev,
#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
/* Use the Energy Model table if available */
if (cpufreq_cdev->em) {
struct em_perf_state *table;
unsigned int freq;

idx = cpufreq_cdev->max_level - state;
return cpufreq_cdev->em->table[idx].frequency;

rcu_read_lock();
table = em_perf_state_from_pd(cpufreq_cdev->em);
freq = table[idx].frequency;
rcu_read_unlock();

return freq;
}
#endif

Expand Down

0 comments on commit 207472b

Please sign in to comment.