Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/drivers/cpufreq/cpufreq_misc_governors.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *  xen/drivers/cpufreq/cpufreq_misc_gov.c
3
 *
4
 *  Copyright (C)  2001 Russell King
5
 *            (C)  2002 - 2004 Dominik Brodowski <linux@brodo.de>
6
 *
7
 *     Nov 2008 Liu Jinsong <jinsong.liu@intel.com>
8
 *     Porting cpufreq_userspace.c, cpufreq_performance.c, and 
9
 *     cpufreq_powersave.c from Liunx 2.6.23 to Xen hypervisor
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License version 2 as
13
 * published by the Free Software Foundation.
14
 *
15
 */
16
17
#include <xen/cpu.h>
18
#include <xen/init.h>
19
#include <xen/percpu.h>
20
#include <xen/sched.h>
21
#include <acpi/cpufreq/cpufreq.h>
22
23
/*
24
 * cpufreq userspace governor
25
 */
26
static unsigned int __read_mostly userspace_cmdline_freq;
27
static DEFINE_PER_CPU(unsigned int, cpu_set_freq);
28
29
static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
30
                                      unsigned int event)
31
0
{
32
0
    int ret = 0;
33
0
    unsigned int cpu;
34
0
35
0
    if (unlikely(!policy) || 
36
0
        unlikely(!cpu_online(cpu = policy->cpu)))
37
0
        return -EINVAL;
38
0
39
0
    switch (event) {
40
0
    case CPUFREQ_GOV_START:
41
0
        if (!per_cpu(cpu_set_freq, cpu))
42
0
            per_cpu(cpu_set_freq, cpu) = policy->cur;
43
0
        break;
44
0
    case CPUFREQ_GOV_STOP:
45
0
        per_cpu(cpu_set_freq, cpu) = 0;
46
0
        break;
47
0
    case CPUFREQ_GOV_LIMITS:
48
0
        if (policy->max < per_cpu(cpu_set_freq, cpu))
49
0
            ret = __cpufreq_driver_target(policy, policy->max,
50
0
                        CPUFREQ_RELATION_H);
51
0
        else if (policy->min > per_cpu(cpu_set_freq, cpu))
52
0
            ret = __cpufreq_driver_target(policy, policy->min,
53
0
                        CPUFREQ_RELATION_L);
54
0
        else
55
0
            ret = __cpufreq_driver_target(policy, per_cpu(cpu_set_freq, cpu),
56
0
                        CPUFREQ_RELATION_L);
57
0
58
0
        break;
59
0
    default:
60
0
        ret = -EINVAL;
61
0
        break;
62
0
    }
63
0
64
0
    return ret;
65
0
}
66
67
int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq)
68
0
{
69
0
    struct cpufreq_policy *policy;
70
0
71
0
    if (!cpu_online(cpu) || !(policy = per_cpu(cpufreq_cpu_policy, cpu)))
72
0
        return -EINVAL;
73
0
74
0
    per_cpu(cpu_set_freq, cpu) = freq;
75
0
76
0
    if (freq < policy->min)
77
0
        freq = policy->min;
78
0
    if (freq > policy->max)
79
0
        freq = policy->max;
80
0
81
0
    return __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
82
0
}
83
84
static bool_t __init
85
cpufreq_userspace_handle_option(const char *name, const char *val)
86
0
{
87
0
    if (!strcmp(name, "speed") && val) {
88
0
        userspace_cmdline_freq = simple_strtoul(val, NULL, 0);
89
0
        return 1;
90
0
    }
91
0
    return 0;
92
0
}
93
94
static int cpufreq_userspace_cpu_callback(
95
    struct notifier_block *nfb, unsigned long action, void *hcpu)
96
0
{
97
0
    unsigned int cpu = (unsigned long)hcpu;
98
0
99
0
    switch (action)
100
0
    {
101
0
    case CPU_UP_PREPARE:
102
0
        per_cpu(cpu_set_freq, cpu) = userspace_cmdline_freq;
103
0
        break;
104
0
    }
105
0
106
0
    return NOTIFY_DONE;
107
0
}
108
109
static struct notifier_block cpufreq_userspace_cpu_nfb = {
110
    .notifier_call = cpufreq_userspace_cpu_callback
111
};
112
113
struct cpufreq_governor cpufreq_gov_userspace = {
114
    .name = "userspace",
115
    .governor = cpufreq_governor_userspace,
116
    .handle_option = cpufreq_userspace_handle_option
117
};
118
119
static int __init cpufreq_gov_userspace_init(void)
120
1
{
121
1
    unsigned int cpu;
122
1
123
1
    for_each_online_cpu(cpu)
124
12
        per_cpu(cpu_set_freq, cpu) = userspace_cmdline_freq;
125
1
    register_cpu_notifier(&cpufreq_userspace_cpu_nfb);
126
1
    return cpufreq_register_governor(&cpufreq_gov_userspace);
127
1
}
128
__initcall(cpufreq_gov_userspace_init);
129
130
131
/*
132
 * cpufreq performance governor
133
 */
134
static int cpufreq_governor_performance(struct cpufreq_policy *policy,
135
                                      unsigned int event)
136
0
{
137
0
    int ret = 0;
138
0
139
0
    if (!policy)
140
0
        return -EINVAL;
141
0
142
0
    switch (event) {
143
0
    case CPUFREQ_GOV_START:
144
0
    case CPUFREQ_GOV_STOP:
145
0
        break;
146
0
    case CPUFREQ_GOV_LIMITS:
147
0
        ret = __cpufreq_driver_target(policy, policy->max,
148
0
                        CPUFREQ_RELATION_H);
149
0
        break;
150
0
    default:
151
0
        ret = -EINVAL;
152
0
        break;
153
0
    }
154
0
155
0
    return ret;
156
0
}
157
158
struct cpufreq_governor cpufreq_gov_performance = {
159
    .name = "performance",
160
    .governor = cpufreq_governor_performance,
161
};
162
163
static int __init cpufreq_gov_performance_init(void)
164
1
{
165
1
    return cpufreq_register_governor(&cpufreq_gov_performance);
166
1
}
167
__initcall(cpufreq_gov_performance_init);
168
169
170
/*
171
 * cpufreq powersave governor
172
 */
173
static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
174
                                      unsigned int event)
175
0
{
176
0
    int ret = 0;
177
0
178
0
    if (!policy)
179
0
        return -EINVAL;
180
0
181
0
    switch (event) {
182
0
    case CPUFREQ_GOV_START:
183
0
    case CPUFREQ_GOV_STOP:
184
0
        break;
185
0
    case CPUFREQ_GOV_LIMITS:
186
0
        ret = __cpufreq_driver_target(policy, policy->min,
187
0
                        CPUFREQ_RELATION_L);
188
0
        break;
189
0
    default:
190
0
        ret = -EINVAL;
191
0
        break;
192
0
    }
193
0
194
0
    return ret;
195
0
}
196
197
struct cpufreq_governor cpufreq_gov_powersave = {
198
    .name = "powersave",
199
    .governor = cpufreq_governor_powersave,
200
};
201
202
static int __init cpufreq_gov_powersave_init(void)
203
1
{
204
1
    return cpufreq_register_governor(&cpufreq_gov_powersave);
205
1
}
206
__initcall(cpufreq_gov_powersave_init);