cpufreq 之conservative governe的实现

    xiaoxiao2026-04-08  3

    我们来看看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寄存器中.
    转载请注明原文地址: https://ju.6miu.com/read-1308617.html
    最新回复(0)