1616#include <linux/slab.h>
1717
1818static 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+ };
2024
2125/**
2226 * cpufreq_set - set the CPU frequency
@@ -28,19 +32,19 @@ static DEFINE_MUTEX(userspace_mutex);
2832static int cpufreq_set (struct cpufreq_policy * policy , unsigned int freq )
2933{
3034 int ret = - EINVAL ;
31- unsigned int * setspeed = policy -> governor_data ;
35+ struct userspace_policy * userspace = policy -> governor_data ;
3236
3337 pr_debug ("cpufreq_set for cpu %u, freq %u kHz\n" , policy -> cpu , freq );
3438
35- mutex_lock (& userspace_mutex );
39+ mutex_lock (& userspace -> mutex );
3640 if (!per_cpu (cpu_is_managed , policy -> cpu ))
3741 goto err ;
3842
39- * setspeed = freq ;
43+ userspace -> setspeed = freq ;
4044
4145 ret = __cpufreq_driver_target (policy , freq , CPUFREQ_RELATION_L );
4246 err :
43- mutex_unlock (& userspace_mutex );
47+ mutex_unlock (& userspace -> mutex );
4448 return ret ;
4549}
4650
@@ -51,67 +55,74 @@ static ssize_t show_speed(struct cpufreq_policy *policy, char *buf)
5155
5256static int cpufreq_userspace_policy_init (struct cpufreq_policy * policy )
5357{
54- unsigned int * setspeed ;
58+ struct userspace_policy * userspace ;
5559
56- setspeed = kzalloc (sizeof (* setspeed ), GFP_KERNEL );
57- if (!setspeed )
60+ userspace = kzalloc (sizeof (* userspace ), GFP_KERNEL );
61+ if (!userspace )
5862 return - ENOMEM ;
5963
60- policy -> governor_data = setspeed ;
64+ mutex_init (& userspace -> mutex );
65+
66+ policy -> governor_data = userspace ;
6167 return 0 ;
6268}
6369
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+ */
6474static void cpufreq_userspace_policy_exit (struct cpufreq_policy * policy )
6575{
66- mutex_lock (& userspace_mutex );
6776 kfree (policy -> governor_data );
6877 policy -> governor_data = NULL ;
69- mutex_unlock (& userspace_mutex );
7078}
7179
7280static int cpufreq_userspace_policy_start (struct cpufreq_policy * policy )
7381{
74- unsigned int * setspeed = policy -> governor_data ;
82+ struct userspace_policy * userspace = policy -> governor_data ;
7583
7684 BUG_ON (!policy -> cur );
7785 pr_debug ("started managing cpu %u\n" , policy -> cpu );
7886
79- mutex_lock (& userspace_mutex );
87+ mutex_lock (& userspace -> mutex );
8088 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 );
8391 return 0 ;
8492}
8593
8694static void cpufreq_userspace_policy_stop (struct cpufreq_policy * policy )
8795{
88- unsigned int * setspeed = policy -> governor_data ;
96+ struct userspace_policy * userspace = policy -> governor_data ;
8997
9098 pr_debug ("managing cpu %u stopped\n" , policy -> cpu );
9199
92- mutex_lock (& userspace_mutex );
100+ mutex_lock (& userspace -> mutex );
93101 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 );
96104}
97105
98106static void cpufreq_userspace_policy_limits (struct cpufreq_policy * policy )
99107{
100- unsigned int * setspeed = policy -> governor_data ;
108+ struct userspace_policy * userspace = policy -> governor_data ;
101109
102- mutex_lock (& userspace_mutex );
110+ mutex_lock (& userspace -> mutex );
103111
104112 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 );
111121 else
112- __cpufreq_driver_target (policy , * setspeed , CPUFREQ_RELATION_L );
122+ __cpufreq_driver_target (policy , userspace -> setspeed ,
123+ CPUFREQ_RELATION_L );
113124
114- mutex_unlock (& userspace_mutex );
125+ mutex_unlock (& userspace -> mutex );
115126}
116127
117128static struct cpufreq_governor cpufreq_gov_userspace = {
0 commit comments