CPUFreq Intro

The file is based on http://blog.csdn.net/droidphone/article/details/9346981 , from section 1 to 3.

CPUFreq系统把一些公共的逻辑和接口代码抽象出来,这些代码与平台无关,也与具体调频策略无关,内核的文档把它称为CPUFreq Core(/Documents/cpufreq/core.txt)。另外一部分,与实际的调频策略相关的部分被称作cpufreq_policy,cpufreq_policy又是由频率信息和具体的governor组成,governor才是具体策略的实现者,当然governor需要我们提供必要的频率信息,governor的实现最好能做到平台无关,与平台相关的代码用cpufreq_driver表述,它完成实际的频率调节工作。最后,如果其他内核模块需要在频率调节的过程中得到通知消息,则可以通过cpufreq notifiers来完成。

policy 该变量可以取以下两个值:CPUFREQ_POLICY_POWERSAVE和CPUFREQ_POLICY_PERFORMANCE,该变量只有当调频驱动支持setpolicy回调函数的时候有效,这时候由驱动根据policy变量的值来决定系统的工作频率或状态。如果调频驱动(cpufreq_driver)支持target回调,则频率由相应的governor来决定。
governor 和governor_data 指向该policy当前使用的cpufreq_governor结构和它的上下文数据。governor是实现该policy的关键所在,调频策略的逻辑由governor实现。

cpufreq_driver_target是带锁的版本,而__cpufreq_driver_target是不带锁的版本,如果确定是在governor的上下文中,使用不带锁的版本,否则需要使用带锁的版本。

cpu_dbs_common_info  该结构把对计算cpu负载需要使用到的一些辅助变量整合在一起,通常,每个cpu都需要一个cpu_dbs_common_info结构体,该结构体中的成员会在governor的生命周期期间进行传递,以用于统计当前cpu的负载
(dbs缩写,实际是:demand based switching)

Odroid XU  Android default Ondemand code: https://github.com/hardkernel/linux/blob/odroidxu-3.4.y/drivers/cpufreq/cpufreq_ondemand.c

HotPlug In case: (Freq > 1.6GHz boost level count is over BOOST_LV_CNT)
static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq){
……
if ((consecutive_boost_level > BOOST_LV_CNT) &&(freq > HOTPLUG_TRANS_H)) {
freq = HOTPLUG_TRANS_H;
hotplug_in = true;
}
……
if (!cpumask_empty(&out_cpus) && hotplug_in) {
mutex_lock(&hotplug_mutex);
hotplug_out = false;
__do_hotplug();
mutex_unlock(&hotplug_mutex);
}
}

Check CPU Freq logic is in:
/*
* Every sampling_rate, we check, if current idle time is less
* than 20% (default), then we try to increase frequency
* Every sampling_rate, we look for a the lowest
* frequency which can sustain the load while keeping idle time over
* 30%. If such a frequency exist, we try to decrease to this frequency.
*
* Any frequency increase takes it to the maximum frequency.
* Frequency reduction happens at minimum steps of
* 5% (default) of current frequency
*/
static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info){
…..
//Calulate each CPU load, find the maximum
load = 100 * (wall_time idle_time) / wall_time;
…..
load_freq = load * freq_avg;/* Get Absolute Load – in terms of freq */
if (load_freq > max_load_freq)
      max_load_freq = load_freq;

/* Hotplug out case : Frequency stay over maximum quad level */

/*
* If policy->cur >= 1.6Ghz(HOTPLUG_TRANS_H) and next transition is
* ascending check cpu_util value for each online cpu.
* If cpu_util is less than 10%(HOTPLUG_OUT_LOAD) for
3(HOTPLUG_OUT_CNT_H)
* times sampling rate(100ms), plugged out on this cpu.
*/

//Increase Freq

/*
* If current freq is under 600MHz, and load freq is bigger than
* up_threshold 60, increase freq by step level 600MHz.
*/
/*
* If current freq is same or over 600MHz, and load freq is bigger than
* up_threshold 95, increase freq as below conditions.
* Condition 1: current freq is under 1.2GHz, apply step level to 1.2GHz
* Condition 2: current freq is same or over 1.2GHz, increase to max freq.
*/

/*
* Hotplug Out:
* – Frequency stay at lowest level
*/

//Descrease Freq

/*
* If current freq is over 800MHz, and load freq is smaller than
* 92(by 95-3), decrease freq as below condition.
* Condition: next freq is under 800MHz decrease to 800MHz
*/
/*
* If current freq is same or under 800MHz, and load freq is smaller than
* 40(by 60-20), decrease freq.
*/

 

 

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s