Skip to content

Commit

Permalink
Merge tag 'pm-5.16-rc2' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
 "These fix a system-wide suspend issue in the DTPM framework and
  improve the Energy Model documentation.

  Specifics:

   - Fix system suspend handling in DTPM when it is enabled, but not
     actually used (Daniel Lezcano)

   - Describe the new cpufreq callback for Energy Model registration and
     explain the "advanced" and "simple" EM variants in the EM
     documentation (Lukasz Luba)"

* tag 'pm-5.16-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  Documentation: power: Describe 'advanced' and 'simple' EM models
  Documentation: power: Add description about new callback for EM registration
  powercap: DTPM: Fix suspend failure and kernel warning
  • Loading branch information
torvalds committed Nov 18, 2021
2 parents 17e1070 + 47b577a commit 18e2bef
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 21 deletions.
53 changes: 38 additions & 15 deletions Documentation/power/energy-model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ CONFIG_ENERGY_MODEL must be enabled to use the EM framework.
2.2 Registration of performance domains
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Registration of 'advanced' EM
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The 'advanced' EM gets it's name due to the fact that the driver is allowed
to provide more precised power model. It's not limited to some implemented math
formula in the framework (like it's in 'simple' EM case). It can better reflect
the real power measurements performed for each performance state. Thus, this
registration method should be preferred in case considering EM static power
(leakage) is important.

Drivers are expected to register performance domains into the EM framework by
calling the following API::

Expand All @@ -103,6 +113,18 @@ to: return warning/error, stop working or panic.
See Section 3. for an example of driver implementing this
callback, or Section 2.4 for further documentation on this API

Registration of 'simple' EM
~~~~~~~~~~~~~~~~~~~~~~~~~~~

The 'simple' EM is registered using the framework helper function
cpufreq_register_em_with_opp(). It implements a power model which is tight to
math formula::

Power = C * V^2 * f

The EM which is registered using this method might not reflect correctly the
physics of a real device, e.g. when static power (leakage) is important.


2.3 Accessing performance domains
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -138,6 +160,10 @@ or in Section 2.4
3. Example driver
-----------------

The CPUFreq framework supports dedicated callback for registering
the EM for a given CPU(s) 'policy' object: cpufreq_driver::register_em().
That callback has to be implemented properly for a given driver,
because the framework would call it at the right time during setup.
This section provides a simple example of a CPUFreq driver registering a
performance domain in the Energy Model framework using the (fake) 'foo'
protocol. The driver implements an est_power() function to be provided to the
Expand Down Expand Up @@ -167,25 +193,22 @@ EM framework::
20 return 0;
21 }
22
23 static int foo_cpufreq_init(struct cpufreq_policy *policy)
23 static void foo_cpufreq_register_em(struct cpufreq_policy *policy)
24 {
25 struct em_data_callback em_cb = EM_DATA_CB(est_power);
26 struct device *cpu_dev;
27 int nr_opp, ret;
27 int nr_opp;
28
29 cpu_dev = get_cpu_device(cpumask_first(policy->cpus));
30
31 /* Do the actual CPUFreq init work ... */
32 ret = do_foo_cpufreq_init(policy);
33 if (ret)
34 return ret;
35
36 /* Find the number of OPPs for this policy */
37 nr_opp = foo_get_nr_opp(policy);
31 /* Find the number of OPPs for this policy */
32 nr_opp = foo_get_nr_opp(policy);
33
34 /* And register the new performance domain */
35 em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb, policy->cpus,
36 true);
37 }
38
39 /* And register the new performance domain */
40 em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb, policy->cpus,
41 true);
42
43 return 0;
44 }
39 static struct cpufreq_driver foo_cpufreq_driver = {
40 .register_em = foo_cpufreq_register_em,
41 };
9 changes: 3 additions & 6 deletions drivers/powercap/dtpm_cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,16 +166,13 @@ static struct dtpm_ops dtpm_ops = {

static int cpuhp_dtpm_cpu_offline(unsigned int cpu)
{
struct em_perf_domain *pd;
struct dtpm_cpu *dtpm_cpu;

pd = em_cpu_get(cpu);
if (!pd)
return -EINVAL;

dtpm_cpu = per_cpu(dtpm_per_cpu, cpu);
if (dtpm_cpu)
dtpm_update_power(&dtpm_cpu->dtpm);

return dtpm_update_power(&dtpm_cpu->dtpm);
return 0;
}

static int cpuhp_dtpm_cpu_online(unsigned int cpu)
Expand Down

0 comments on commit 18e2bef

Please sign in to comment.