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

cpufreq 之userspace governe的实现

2016-08-16 11:16 239 查看
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 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: