CPUFREQ(9) | Kernel Developer's Manual | CPUFREQ(9) |
cpufreq
, cpufreq_register
,
cpufreq_deregister
,
cpufreq_suspend
,
cpufreq_resume
, cpufreq_get
,
cpufreq_get_backend
,
cpufreq_get_state
,
cpufreq_get_state_index
,
cpufreq_set
, cpufreq_set_all
—
#include <sys/cpufreq.h>
int
cpufreq_register
(struct
cpufreq *cf);
void
cpufreq_deregister
(void);
void
cpufreq_suspend
(struct
cpu_info *ci);
void
cpufreq_resume
(struct
cpu_info *ci);
uint32_t
cpufreq_get
(struct
cpu_info *ci);
int
cpufreq_get_backend
(struct
cpufreq *cf);
int
cpufreq_get_state
(uint32_t
freq, struct
cpufreq_state *cfs);
int
cpufreq_get_state_index
(uint32_t
index, struct
cpufreq_state *cfs);
void
cpufreq_set
(struct
cpu_info *ci, uint32_t
freq);
void
cpufreq_set_all
(uint32_t
freq);
cpufreq
interface provides a
framework for CPU frequency scaling done by a machine-dependent backend
implementation.
The cpufreq
interface is a per-CPU
framework. It is implicitly 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.
It is possible to use cpufreq
with frequency scaling
implemented via pci(4). In
addition, it assumed that the available frequency levels are shared
uniformly by all processors in the system, even when it is possible to
control the frequency of individual processors.
It should be noted that the cpufreq
interface is generally stateless. This implies for instance that possible
caching should be done in the machine-dependent backend. The
cpufreq_suspend
() and
cpufreq_resume
() functions are exceptions. These can
be integrated with pmf(9).
cpufreq_register
(cf)cpufreq_register
() function initializes the
interface by associating a machine-dependent backend with the framework.
Only one backend can be registered. Upon successful completion,
cpufreq_register
() returns 0 and sets the
frequency of all processors to the maximum available level. Note that the
registration can be done only after interrupts have been enabled; cf.
config_interrupts(9).
The following elements in struct cpufreq should be filled prior to the call:
char cf_name[CPUFREQ_NAME_MAX]; struct cpufreq_state cf_state[CPUFREQ_STATE_MAX]; uint32_t cf_state_count; bool cf_mp; void *cf_cookie; xcfunc_t cf_get_freq; xcfunc_t cf_set_freq;
uint32_t cfs_freq; uint32_t cfs_power;
From these cfs_freq (the clock frequency in MHz) is mandatory, whereas the optional cfs_power can be filled to describe the power consumption (in mW) of each state. The cf_state array must be filled in descending order, that is, the highest frequency should be at the zero index.
If the backend operates with a simple boolean switch
without knowing the clock frequencies, the
cfs_freq field should be set to
CPUFREQ_STATE_ENABLED
or
CPUFREQ_STATE_DISABLED
. The first constant
should precede the latter one in cf_state.
cpufreq_get
(),
cpufreq_set
(), or
cpufreq_set_all
() is called.cpufreq
,
the first parameter is always the cf_cookie and
the second parameter is the frequency, defined as
uint32_t *.cpufreq_deregister
()cpufreq_suspend
(ci)cpufreq_suspend
() can be called when the
processor suspends. The function saves the current frequency of
ci and sets the minimum available frequency.cpufreq_resume
(ci)cpufreq_get
(ci)cpufreq_get_backend
(cf)cpufreq_get_backend
()
returns 0 and fills cf with the data related to the
currently used backend.cpufreq_get_state
(freq,
cfs)cpufreq_get_state
() function looks for the
given frequency from the array of known frequency states. If
freq is not found, the closest match is returned.
Upon successful completion, the function returns zero and stores the state
information to cfs.cpufreq_get_state_index
(index,
cfs)cpufreq_set
(ci,
freq)cpufreq_set
() function sets the frequency of
ci to freq.cpufreq_set_all
(freq)The three functions cpufreq_get
(),
cpufreq_set
(), and
cpufreq_set_all
() guarantee that the call will be
made in curcpu(9). The
interface holds a mutex(9)
while calling the functions. This, and the use of
xcall(9), implies that no
memory can be allocated in the backend during the calls. Nor should the
functions be called from interrupt context.
cpufreq
interface is implemented within
sys/kern/subr_cpufreq.c.
Venkatesh Pallipadi and Alexey Starikovskiy, The Ondemand Governor. Past, Present, and Future, Intel Open Source Technology Center, http://www.kernel.org/doc/ols/2006/ols2006v2-pages-223-238.pdf, July, 2006, Proceedings of the Linux Symposium.
cpufreq
interface first appeared in
NetBSD 6.0.
December 1, 2015 | NetBSD 9.0 |