您的位置:首页 > 编程语言 > Go语言

cpufreq 之conservative governe的实现

2016-08-16 11:29 344 查看
我们来看看conservative governer。这个governer会在cpu loadding 超过向上阈值是一点一点的增加cpu freq.

如果低于向下的阈值,则会减小频率.

最重要的common_dbs_data如下。

358 static struct common_dbs_data cs_dbs_cdata = {

359         .governor = GOV_CONSERVATIVE,

360         .attr_group_gov_sys = &cs_attr_group_gov_sys,

361         .attr_group_gov_pol = &cs_attr_group_gov_pol,

362         .get_cpu_cdbs = get_cpu_cdbs,

363         .get_cpu_dbs_info_s = get_cpu_dbs_info_s,

364         .gov_dbs_timer = cs_dbs_timer,

365         .gov_check_cpu = cs_check_cpu,

366         .gov_ops = &cs_ops,

367         .init = cs_init,

368         .exit = cs_exit,

369 };

这个governer 和ondemand governer一样也是通过cs_dbs_timer中调用cs_check_cup 来切换频率.

105 static void cs_dbs_timer(struct work_struct *work)

106 {

107         struct cs_cpu_dbs_info_s *dbs_info = container_of(work,

108                         struct cs_cpu_dbs_info_s, cdbs.work.work);

109         unsigned int cpu = dbs_info->cdbs.cur_policy->cpu;

110         struct cs_cpu_dbs_info_s *core_dbs_info = &per_cpu(cs_cpu_dbs_info,

111                         cpu);

112         struct dbs_data *dbs_data = dbs_info->cdbs.cur_policy->governor_data;

113         struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;

114         int delay = delay_for_sampling_rate(cs_tuners->sampling_rate);

115         bool modify_all = true;

116 

117         mutex_lock(&core_dbs_info->cdbs.timer_mutex);

118         if (!need_load_eval(&core_dbs_info->cdbs, cs_tuners->sampling_rate))

119                 modify_all = false;

120         else

121                 dbs_check_cpu(dbs_data, cpu);

122 

123         gov_queue_work(dbs_data, dbs_info->cdbs.cur_policy, delay, modify_all);

124         mutex_unlock(&core_dbs_info->cdbs.timer_mutex);

125 }

这个函数123行每过delay 时间运行cs_dbs_timer,121行调用dbs_check_cpu 来check cpu freq.

dbs_check_cpu最后会调用cs_check_cpu

47 static void cs_check_cpu(int cpu, unsigned int load)

 48 {

 49         struct cs_cpu_dbs_info_s *dbs_info = &per_cpu(cs_cpu_dbs_info, cpu);

 50         struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;

 51         struct dbs_data *dbs_data = policy->governor_data;

 52         struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;

 53 

 54         /*

 55          * break out if we 'cannot' reduce the speed as the user might

 56          * want freq_step to be zero

 57          */

 58         if (cs_tuners->freq_step == 0)

 59                 return;

 60 

 61         /* Check for frequency increase */

 62         if (load > cs_tuners->up_threshold) {

 63                 dbs_info->down_skip = 0;

 64 

 65                 /* if we are already at full speed then break out early */

 66                 if (dbs_info->requested_freq == policy->max)

 67                         return;

 68 

 69                 dbs_info->requested_freq += get_freq_target(cs_tuners, policy);

 70 

 71                 if (dbs_info->requested_freq > policy->max)

 72                         dbs_info->requested_freq = policy->max;

 73 

 74                 __cpufreq_driver_target(policy, dbs_info->requested_freq,

 75                         CPUFREQ_RELATION_H);

 76                 return;

 77         }

 78 

 79         /* if sampling_down_factor is active break out early */

 80         if (++dbs_info->down_skip < cs_tuners->sampling_down_factor)

 81                 return;

 82         dbs_info->down_skip = 0;

 83 

 84         /* Check for frequency decrease */

 85         if (load < cs_tuners->down_threshold) {

 86                 unsigned int freq_target;

 87                 /*

 88                  * if we cannot reduce the frequency anymore, break out early

 89                  */

 90                 if (policy->cur == policy->min)

 91                         return;

 92 

 93                 freq_target = get_freq_target(cs_tuners, policy);

 94                 if (dbs_info->requested_freq > freq_target)

 95                         dbs_info->requested_freq -= freq_target;

 96                 else

 97                         dbs_info->requested_freq = policy->min;

 98 

 99                 __cpufreq_driver_target(policy, dbs_info->requested_freq,

100                                 CPUFREQ_RELATION_L);

101                 return;

102         }

103 }

这个函数的63 行发现如果cpu loadding大于阈值的话,就69行增加freq,在74行将频率设定到cpu的寄存器中。

85行,如果loadding小于向下的阈值,95行减小频率,99行将减小后的频率设定的cpu寄存器中.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: