tech-kern archive

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

Re: A simple cpufreq(9)



On Mon, Sep 26, 2011 at 10:03:06AM -0500, David Young wrote:
> Instead, provide an API routine for finding out the number of states
> (nstates) and a routine for selecting a state [0, nstates - 1].

The code is ready and it is available in [1]. However, I can not complete it
because when trying to upgrade, I encounter PR kern/45361.

All existing drivers were converted, expect ichlpcib(4) and piixpcib(4)
(for these, I think first the SpeedStep should be splitted as a child
device of the bridge).

This breaks COMPAT_50 of cpuctl(8). How to handle that? #ifdefs?

- Jukka.

[1] ftp://ftp.NetBSD.org/pub/NetBSD/misc/jruoho/codeanddiff

* * *

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

NAME
     cpufreq, cpufreq_register, cpufreq_deregister, cpufreq_suspend,
     cpufreq_resume, cpufreq_get, cpufreq_set, cpufreq_set_all -- interface
     for CPU frequency scaling

SYNOPSIS
     #include <sys/cpufreq.h>

     int
     cpufreq_register(struct cpufreq_if *cif);

     void
     cpufreq_deregister(void);

     void
     cpufreq_suspend(struct cpu_info *ci);

     void
     cpufreq_resume(struct cpu_info *ci);

     void
     cpufreq_get(struct cpu_info *ci, uint16_t *freq);

     int
     cpufreq_get_if(struct cpufreq_if *cif);

     void
     cpufreq_set(struct cpu_info *ci, uint16_t freq);

     void
     cpufreq_set_all(uint16_t freq);

DESCRIPTION
     The machine-independent cpufreq interface provides a framework for CPU
     frequency scaling done by a machine-dependent backend implementation.
     User space control is available via cpuctl(8).

     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
     implementa-
     tion.  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).

FUNCTIONS
     cpufreq_register(cif)
              The 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 to the maxi-
              mum available level.

              The following elements in the cpufreq_if structure should be
              filled prior to the call:

                    char                     name[CPUFREQ_NAME_MAX];
                    struct cpufreq_state     state[CPUFREQ_STATE_MAX];
                    uint16_t                 state_count;
                    bool                     mp;
                    void                    *cookie;
                    xcfunc_t                 get_freq;
                    xcfunc_t                 set_freq;

              ·   The name of the backend is required.

              ·   The cpufreq_state structure conveys descriptive information
                  about the frequency states.  The following fields can be
                  used for the registration:

                    uint16_t                 freq;
                    uint16_t                 power;

                  From these freq (the clock frequency in MHz) is mandatory,
                  whereas the optional power can be filled to describe the
                  power consumption (in mW) of each state.

              ·   The state_count defines the number of states that the back-
                  end has filled in the state array.

              ·   The mp boolean should be set to false if it is known that
                  the backend can not handle per-CPU frequency states; changes
                  should always be propagated to all processors in the system.

              ·   The cookie field is an opaque pointer passed to the backend
                  when cpufreq_get() cpufreq_set(), or cpufreq_set_all() is
                  called.

              ·   The get_freq and set_freq are function pointers that should
                  be associated with the machine-dependent functions to get
                  and set a frequency, respectively.  The xcfunc_t type con-
                  forms to xcall(9).  When the function pointers are invoked
                  by cpufreq, the first parameter is always the cookie and
                  the second parameter is the frequency, defined as uint16_t *.

     cpufreq_deregister()
              Deregisters any possible backend in use.

     cpufreq_suspend(ci)
              The cpufreq_suspend() can be called when the processor suspends.
              The function saves the current frequency of ci and sets the min-
              imum available frequency.

     cpufreq_resume(ci)
              Resumes the frequency of ci that was used before suspend.

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

     cpufreq_get_if(cif)
              Upon successful completion, cpufreq_get_if() returns 0 and fills
              cif with the information of the currently used backend.

     cpufreq_set(ci, freq)
              The cpufreq_set() function sets the frequency of ci to freq.

     cpufreq_set_all(freq)
              Sets freq for all processors in the system.

     The three functions cpufreq_get(), cpufreq_set(), and cpufreq_set_all()
     guarantee that the call will be made in curcpu(9).  The interface holds
     cpu_lock while calling the functions.  This, and the use of xcall(9),
     implies that no memory can be allocated in the backend during the calls.

CODE REFERENCES
     The cpufreq interface is implemented within sys/kern/subr_cpufreq.c.

SEE ALSO
     cpuctl(8), pmf(9), xcall(9)

HISTORY
     The cpufreq interface first appeared in NetBSD 6.0.

BUGS
     The interface does not support different ``governors'' and policies.


Home | Main Index | Thread Index | Old Index