16
16
#include <linux/slab.h>
17
17
18
18
static DEFINE_PER_CPU (unsigned int , cpu_is_managed ) ;
19
- static DEFINE_MUTEX (userspace_mutex );
19
+
20
+ struct userspace_policy {
21
+ unsigned int setspeed ;
22
+ struct mutex mutex ;
23
+ };
20
24
21
25
/**
22
26
* cpufreq_set - set the CPU frequency
@@ -28,19 +32,19 @@ static DEFINE_MUTEX(userspace_mutex);
28
32
static int cpufreq_set (struct cpufreq_policy * policy , unsigned int freq )
29
33
{
30
34
int ret = - EINVAL ;
31
- unsigned int * setspeed = policy -> governor_data ;
35
+ struct userspace_policy * userspace = policy -> governor_data ;
32
36
33
37
pr_debug ("cpufreq_set for cpu %u, freq %u kHz\n" , policy -> cpu , freq );
34
38
35
- mutex_lock (& userspace_mutex );
39
+ mutex_lock (& userspace -> mutex );
36
40
if (!per_cpu (cpu_is_managed , policy -> cpu ))
37
41
goto err ;
38
42
39
- * setspeed = freq ;
43
+ userspace -> setspeed = freq ;
40
44
41
45
ret = __cpufreq_driver_target (policy , freq , CPUFREQ_RELATION_L );
42
46
err :
43
- mutex_unlock (& userspace_mutex );
47
+ mutex_unlock (& userspace -> mutex );
44
48
return ret ;
45
49
}
46
50
@@ -51,67 +55,74 @@ static ssize_t show_speed(struct cpufreq_policy *policy, char *buf)
51
55
52
56
static int cpufreq_userspace_policy_init (struct cpufreq_policy * policy )
53
57
{
54
- unsigned int * setspeed ;
58
+ struct userspace_policy * userspace ;
55
59
56
- setspeed = kzalloc (sizeof (* setspeed ), GFP_KERNEL );
57
- if (!setspeed )
60
+ userspace = kzalloc (sizeof (* userspace ), GFP_KERNEL );
61
+ if (!userspace )
58
62
return - ENOMEM ;
59
63
60
- policy -> governor_data = setspeed ;
64
+ mutex_init (& userspace -> mutex );
65
+
66
+ policy -> governor_data = userspace ;
61
67
return 0 ;
62
68
}
63
69
70
+ /*
71
+ * Any routine that writes to the policy struct will hold the "rwsem" of
72
+ * policy struct that means it is free to free "governor_data" here.
73
+ */
64
74
static void cpufreq_userspace_policy_exit (struct cpufreq_policy * policy )
65
75
{
66
- mutex_lock (& userspace_mutex );
67
76
kfree (policy -> governor_data );
68
77
policy -> governor_data = NULL ;
69
- mutex_unlock (& userspace_mutex );
70
78
}
71
79
72
80
static int cpufreq_userspace_policy_start (struct cpufreq_policy * policy )
73
81
{
74
- unsigned int * setspeed = policy -> governor_data ;
82
+ struct userspace_policy * userspace = policy -> governor_data ;
75
83
76
84
BUG_ON (!policy -> cur );
77
85
pr_debug ("started managing cpu %u\n" , policy -> cpu );
78
86
79
- mutex_lock (& userspace_mutex );
87
+ mutex_lock (& userspace -> mutex );
80
88
per_cpu (cpu_is_managed , policy -> cpu ) = 1 ;
81
- * setspeed = policy -> cur ;
82
- mutex_unlock (& userspace_mutex );
89
+ userspace -> setspeed = policy -> cur ;
90
+ mutex_unlock (& userspace -> mutex );
83
91
return 0 ;
84
92
}
85
93
86
94
static void cpufreq_userspace_policy_stop (struct cpufreq_policy * policy )
87
95
{
88
- unsigned int * setspeed = policy -> governor_data ;
96
+ struct userspace_policy * userspace = policy -> governor_data ;
89
97
90
98
pr_debug ("managing cpu %u stopped\n" , policy -> cpu );
91
99
92
- mutex_lock (& userspace_mutex );
100
+ mutex_lock (& userspace -> mutex );
93
101
per_cpu (cpu_is_managed , policy -> cpu ) = 0 ;
94
- * setspeed = 0 ;
95
- mutex_unlock (& userspace_mutex );
102
+ userspace -> setspeed = 0 ;
103
+ mutex_unlock (& userspace -> mutex );
96
104
}
97
105
98
106
static void cpufreq_userspace_policy_limits (struct cpufreq_policy * policy )
99
107
{
100
- unsigned int * setspeed = policy -> governor_data ;
108
+ struct userspace_policy * userspace = policy -> governor_data ;
101
109
102
- mutex_lock (& userspace_mutex );
110
+ mutex_lock (& userspace -> mutex );
103
111
104
112
pr_debug ("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n" ,
105
- policy -> cpu , policy -> min , policy -> max , policy -> cur , * setspeed );
106
-
107
- if (policy -> max < * setspeed )
108
- __cpufreq_driver_target (policy , policy -> max , CPUFREQ_RELATION_H );
109
- else if (policy -> min > * setspeed )
110
- __cpufreq_driver_target (policy , policy -> min , CPUFREQ_RELATION_L );
113
+ policy -> cpu , policy -> min , policy -> max , policy -> cur , userspace -> setspeed );
114
+
115
+ if (policy -> max < userspace -> setspeed )
116
+ __cpufreq_driver_target (policy , policy -> max ,
117
+ CPUFREQ_RELATION_H );
118
+ else if (policy -> min > userspace -> setspeed )
119
+ __cpufreq_driver_target (policy , policy -> min ,
120
+ CPUFREQ_RELATION_L );
111
121
else
112
- __cpufreq_driver_target (policy , * setspeed , CPUFREQ_RELATION_L );
122
+ __cpufreq_driver_target (policy , userspace -> setspeed ,
123
+ CPUFREQ_RELATION_L );
113
124
114
- mutex_unlock (& userspace_mutex );
125
+ mutex_unlock (& userspace -> mutex );
115
126
}
116
127
117
128
static struct cpufreq_governor cpufreq_gov_userspace = {
0 commit comments