tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

A simple cpufreq(9)


The kernel needs a MI interface for CPU frequency scaling. Below is a draft
that is deliberately as simple as possible.

This is NOT about frequency scaling done by the kernel as a "governor"
(although the long-term goal should point to that direction). The present
goal is just to add a simple MI "interface" (or rather, wrapper) and abstract
away machine- and platform-dependent code and user interfaces.

As far as the implementation goes, this would add two simple MD callback
functions to cpu_info. All ugly MD sysctls would be deprecated and setting
the frequency would be done by cpuctl(8) via these callbacks.[1]

The only interesting detail is that the term "CPU frequency" is defined as
a percentage value: 100 % implies "full performance" and 0 % denotes the
"lowest performance". This follows OpenBSD, being also one of the few
possible ways to define "CPU frequency levels" independently from the
machine. All details are left to the MD implementations, including how to
translate the percentage to actual frequency (and/or voltage, etc.). For
instance, for systems with only two states, all values higher than zero would
set the "high performance mode".[2]


- Jukka.

[1] The currently known users would include x86 (with five (!) different
    implementations) and PowerPC, but frequency scaling is nowadays widely
    used also in the ARM realm.

[2] Note that even in the x86 land it is no longer necessarily known which
    is the exact MHz at which the CPU currently runs (cf. TurboBoost, etc.).

* * *

CPUFREQ(9)             NetBSD Kernel Developer's Manual              CPUFREQ(9)

     cpufreq -- interface for CPU frequency scaling

     #include <sys/cpufreq.h>

     cpufreq_register(cpufreq_get_cb *get, cpufreq_set_cb *set, void *aux);

     cpufreq_get(struct cpu_info *ci, uint8_t *valp);

     cpufreq_set(struct cpu_info *ci, const uint8_t val);

     The machine-independent cpufreq interface provides a simple framework for
     CPU frequency scaling.

           1.   The cpufreq interface uses percentage values in place of
                actual frequencies.  Thus, values 100 % and 0 % denote the
                highest and lowest frequency supported by the CPU. It is the
                responsibility of machine-dependent implementations to trans-
                late the percentage values to actual frequencies or other
                related performance levels.

           2.   The cpufreq interface is stateless and does no locking while
                calling the machine-dependent callbacks.

           3.   The cpufreq interface is a per-CPU framework.  It is implic-
                itly assumed that the frequency can be set independently for
                all processors in the system.  However, cpufreq does not imply
                any restrictions upon whether this information is utilized by
                the actual machine-dependent implementation.

     cpufreq_register(get, set)
              The cpufreq_register() function initializes the subsystem by
              associating the machine-dependent callback functions get and set
              with the machine-independent cpufreq_get() and cpufreq_set(),
              respectively.  The cpufreq_set_cb and cpufreq_get_cb types are
              function pointers defined as:

               bool (*get)(struct cpuinfo_t *ci, void *aux, uint8_t *valp)
               bool (*set)(struct cpuinfo_t *ci, void *aux, const uint8_t val)

              Note that cpufreq does not keep track of the registered call-
              backs.  Each call to cpufreq_register() will override any exist-
              ing callbacks.

     cpufreq_get(ci, valp)
              The cpufreq_get() function obtains the current frequency level
              of the CPU pointed by ci in the parameter valp.

     cpufreq_set(ci, val)
              The cpufreq_set() function sets the performance level of ci to
              val.  The value val is guaranteed to be in the range [0, 100].

     The cpufreq subsystem is implemented within sys/kern/subr_cpufreq.c.


     The cpufreq subsystem first appeared in NetBSD 6.0.

Home | Main Index | Thread Index | Old Index