cpufreq 之userspace governe的实现

    xiaoxiao2026-03-15  9

    userspace governer 是用户空间设定cpu freq频率来运行,因此提供了show_setspeed和store_setspeed 两个函数用于现实当前的cpu freq 和设置当前cpu freq 125 static struct cpufreq_governor cpufreq_gov_userspace = { 126         .name           = "userspace", 127         .governor       = cpufreq_governor_userspace, 128         .store_setspeed = cpufreq_set, 129         .show_setspeed  = show_speed, 130         .owner          = THIS_MODULE, 131 }; 我们看看store_setspeed的实现cpufreq_set。 就是把freq通过__cpufreq_driver_target设定到寄存器中  32 static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq)  33 {  34         int ret = -EINVAL;  35         unsigned int *setspeed = policy->governor_data;  36   37         pr_debug("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);  38   39         mutex_lock(&userspace_mutex);  40         if (!per_cpu(cpu_is_managed, policy->cpu))  41                 goto err;  42   43         *setspeed = freq;  44   45         ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);  46  err:  47         mutex_unlock(&userspace_mutex);  48         return ret;  49 } 而show_setspeed的实现show_speed就是显示当前的freq.  51 static ssize_t show_speed(struct cpufreq_policy *policy, char *buf)  52 {  53         return sprintf(buf, "%u\n", policy->cur);  54 } 需要注意的是set 和show的freq有可能不同. 我们再来看看governor的实现函数cpufreq_governor_userspace 主要处理CPUFREQ_GOV_POLICY_INIT/CPUFREQ_GOV_START event 。 其中CPUFREQ_GOV_START只是将percpu中的当前cpu 置1表示当前cpu已经设定过freq。并保存这个频率. static int cpufreq_governor_userspace(struct cpufreq_policy *policy,  69                                    unsigned int event)  70 {  71         unsigned int *setspeed = policy->governor_data;  72         unsigned int cpu = policy->cpu;  73         int rc = 0;  74   75         if (event == CPUFREQ_GOV_POLICY_INIT)  76                 return cpufreq_userspace_policy_init(policy);  77   78         if (!setspeed)  79                 return -EINVAL;  80   81         switch (event) {  82         case CPUFREQ_GOV_POLICY_EXIT:  83                 mutex_lock(&userspace_mutex);  84                 policy->governor_data = NULL;  85                 kfree(setspeed);  86                 mutex_unlock(&userspace_mutex);  87                 break;  88         case CPUFREQ_GOV_START:  89                 BUG_ON(!policy->cur);  90                 pr_debug("started managing cpu %u\n", cpu);  91   92                 mutex_lock(&userspace_mutex);  93                 per_cpu(cpu_is_managed, cpu) = 1;  94                 *setspeed = policy->cur;  95                 mutex_unlock(&userspace_mutex);  96                 break;  97         case CPUFREQ_GOV_STOP:  98                 pr_debug("managing cpu %u stopped\n", cpu);  99  100                 mutex_lock(&userspace_mutex); 101                 per_cpu(cpu_is_managed, cpu) = 0; 102                 *setspeed = 0; 103                 mutex_unlock(&userspace_mutex); 104                 break; 105         case CPUFREQ_GOV_LIMITS: 106                 mutex_lock(&userspace_mutex); 107                 pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", 108                         cpu, policy->min, policy->max, policy->cur, *setspeed); 109  110                 if (policy->max < *setspeed) 111                         __cpufreq_driver_target(policy, policy->max, 112                                                 CPUFREQ_RELATION_H); 113                 else if (policy->min > *setspeed) 114                         __cpufreq_driver_target(policy, policy->min, 115                                                 CPUFREQ_RELATION_L); 116                 else 117                         __cpufreq_driver_target(policy, *setspeed, 118                                                 CPUFREQ_RELATION_L); 119                 mutex_unlock(&userspace_mutex); 120                 break; 121         } 122         return rc; 123 }
    转载请注明原文地址: https://ju.6miu.com/read-1307974.html
    最新回复(0)