Skip to content

Commit 0dd3c1d

Browse files
committed
cpufreq: governor: New data type for management part of dbs_data
In addition to fields representing governor tunables, struct dbs_data contains some fields needed for the management of objects of that type. As it turns out, that part of struct dbs_data may be shared with (future) governors that won't use the common code used by "ondemand" and "conservative", so move it to a separate struct type and modify the code using struct dbs_data to follow. Signed-off-by: Rafael J. Wysocki <[email protected]> Acked-by: Viresh Kumar <[email protected]>
1 parent 0bed612 commit 0dd3c1d

File tree

4 files changed

+107
-72
lines changed

4 files changed

+107
-72
lines changed

drivers/cpufreq/cpufreq_conservative.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,10 @@ static struct notifier_block cs_cpufreq_notifier_block = {
129129
/************************** sysfs interface ************************/
130130
static struct dbs_governor cs_dbs_gov;
131131

132-
static ssize_t store_sampling_down_factor(struct dbs_data *dbs_data,
133-
const char *buf, size_t count)
132+
static ssize_t store_sampling_down_factor(struct gov_attr_set *attr_set,
133+
const char *buf, size_t count)
134134
{
135+
struct dbs_data *dbs_data = to_dbs_data(attr_set);
135136
unsigned int input;
136137
int ret;
137138
ret = sscanf(buf, "%u", &input);
@@ -143,9 +144,10 @@ static ssize_t store_sampling_down_factor(struct dbs_data *dbs_data,
143144
return count;
144145
}
145146

146-
static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf,
147-
size_t count)
147+
static ssize_t store_up_threshold(struct gov_attr_set *attr_set,
148+
const char *buf, size_t count)
148149
{
150+
struct dbs_data *dbs_data = to_dbs_data(attr_set);
149151
struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
150152
unsigned int input;
151153
int ret;
@@ -158,9 +160,10 @@ static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf,
158160
return count;
159161
}
160162

161-
static ssize_t store_down_threshold(struct dbs_data *dbs_data, const char *buf,
162-
size_t count)
163+
static ssize_t store_down_threshold(struct gov_attr_set *attr_set,
164+
const char *buf, size_t count)
163165
{
166+
struct dbs_data *dbs_data = to_dbs_data(attr_set);
164167
struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
165168
unsigned int input;
166169
int ret;
@@ -175,9 +178,10 @@ static ssize_t store_down_threshold(struct dbs_data *dbs_data, const char *buf,
175178
return count;
176179
}
177180

178-
static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data,
179-
const char *buf, size_t count)
181+
static ssize_t store_ignore_nice_load(struct gov_attr_set *attr_set,
182+
const char *buf, size_t count)
180183
{
184+
struct dbs_data *dbs_data = to_dbs_data(attr_set);
181185
unsigned int input;
182186
int ret;
183187

@@ -199,9 +203,10 @@ static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data,
199203
return count;
200204
}
201205

202-
static ssize_t store_freq_step(struct dbs_data *dbs_data, const char *buf,
203-
size_t count)
206+
static ssize_t store_freq_step(struct gov_attr_set *attr_set, const char *buf,
207+
size_t count)
204208
{
209+
struct dbs_data *dbs_data = to_dbs_data(attr_set);
205210
struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
206211
unsigned int input;
207212
int ret;

drivers/cpufreq/cpufreq_governor.c

Lines changed: 55 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ static DEFINE_MUTEX(gov_dbs_data_mutex);
4343
* This must be called with dbs_data->mutex held, otherwise traversing
4444
* policy_dbs_list isn't safe.
4545
*/
46-
ssize_t store_sampling_rate(struct dbs_data *dbs_data, const char *buf,
46+
ssize_t store_sampling_rate(struct gov_attr_set *attr_set, const char *buf,
4747
size_t count)
4848
{
49+
struct dbs_data *dbs_data = to_dbs_data(attr_set);
4950
struct policy_dbs_info *policy_dbs;
5051
unsigned int rate;
5152
int ret;
@@ -59,7 +60,7 @@ ssize_t store_sampling_rate(struct dbs_data *dbs_data, const char *buf,
5960
* We are operating under dbs_data->mutex and so the list and its
6061
* entries can't be freed concurrently.
6162
*/
62-
list_for_each_entry(policy_dbs, &dbs_data->policy_dbs_list, list) {
63+
list_for_each_entry(policy_dbs, &attr_set->policy_list, list) {
6364
mutex_lock(&policy_dbs->timer_mutex);
6465
/*
6566
* On 32-bit architectures this may race with the
@@ -96,7 +97,7 @@ void gov_update_cpu_data(struct dbs_data *dbs_data)
9697
{
9798
struct policy_dbs_info *policy_dbs;
9899

99-
list_for_each_entry(policy_dbs, &dbs_data->policy_dbs_list, list) {
100+
list_for_each_entry(policy_dbs, &dbs_data->attr_set.policy_list, list) {
100101
unsigned int j;
101102

102103
for_each_cpu(j, policy_dbs->policy->cpus) {
@@ -111,9 +112,9 @@ void gov_update_cpu_data(struct dbs_data *dbs_data)
111112
}
112113
EXPORT_SYMBOL_GPL(gov_update_cpu_data);
113114

114-
static inline struct dbs_data *to_dbs_data(struct kobject *kobj)
115+
static inline struct gov_attr_set *to_gov_attr_set(struct kobject *kobj)
115116
{
116-
return container_of(kobj, struct dbs_data, kobj);
117+
return container_of(kobj, struct gov_attr_set, kobj);
117118
}
118119

119120
static inline struct governor_attr *to_gov_attr(struct attribute *attr)
@@ -124,25 +125,24 @@ static inline struct governor_attr *to_gov_attr(struct attribute *attr)
124125
static ssize_t governor_show(struct kobject *kobj, struct attribute *attr,
125126
char *buf)
126127
{
127-
struct dbs_data *dbs_data = to_dbs_data(kobj);
128128
struct governor_attr *gattr = to_gov_attr(attr);
129129

130-
return gattr->show(dbs_data, buf);
130+
return gattr->show(to_gov_attr_set(kobj), buf);
131131
}
132132

133133
static ssize_t governor_store(struct kobject *kobj, struct attribute *attr,
134134
const char *buf, size_t count)
135135
{
136-
struct dbs_data *dbs_data = to_dbs_data(kobj);
136+
struct gov_attr_set *attr_set = to_gov_attr_set(kobj);
137137
struct governor_attr *gattr = to_gov_attr(attr);
138138
int ret = -EBUSY;
139139

140-
mutex_lock(&dbs_data->mutex);
140+
mutex_lock(&attr_set->update_lock);
141141

142-
if (dbs_data->usage_count)
143-
ret = gattr->store(dbs_data, buf, count);
142+
if (attr_set->usage_count)
143+
ret = gattr->store(attr_set, buf, count);
144144

145-
mutex_unlock(&dbs_data->mutex);
145+
mutex_unlock(&attr_set->update_lock);
146146

147147
return ret;
148148
}
@@ -425,6 +425,41 @@ static void free_policy_dbs_info(struct policy_dbs_info *policy_dbs,
425425
gov->free(policy_dbs);
426426
}
427427

428+
static void gov_attr_set_init(struct gov_attr_set *attr_set,
429+
struct list_head *list_node)
430+
{
431+
INIT_LIST_HEAD(&attr_set->policy_list);
432+
mutex_init(&attr_set->update_lock);
433+
attr_set->usage_count = 1;
434+
list_add(list_node, &attr_set->policy_list);
435+
}
436+
437+
static void gov_attr_set_get(struct gov_attr_set *attr_set,
438+
struct list_head *list_node)
439+
{
440+
mutex_lock(&attr_set->update_lock);
441+
attr_set->usage_count++;
442+
list_add(list_node, &attr_set->policy_list);
443+
mutex_unlock(&attr_set->update_lock);
444+
}
445+
446+
static unsigned int gov_attr_set_put(struct gov_attr_set *attr_set,
447+
struct list_head *list_node)
448+
{
449+
unsigned int count;
450+
451+
mutex_lock(&attr_set->update_lock);
452+
list_del(list_node);
453+
count = --attr_set->usage_count;
454+
mutex_unlock(&attr_set->update_lock);
455+
if (count)
456+
return count;
457+
458+
kobject_put(&attr_set->kobj);
459+
mutex_destroy(&attr_set->update_lock);
460+
return 0;
461+
}
462+
428463
static int cpufreq_governor_init(struct cpufreq_policy *policy)
429464
{
430465
struct dbs_governor *gov = dbs_governor_of(policy);
@@ -453,10 +488,7 @@ static int cpufreq_governor_init(struct cpufreq_policy *policy)
453488
policy_dbs->dbs_data = dbs_data;
454489
policy->governor_data = policy_dbs;
455490

456-
mutex_lock(&dbs_data->mutex);
457-
dbs_data->usage_count++;
458-
list_add(&policy_dbs->list, &dbs_data->policy_dbs_list);
459-
mutex_unlock(&dbs_data->mutex);
491+
gov_attr_set_get(&dbs_data->attr_set, &policy_dbs->list);
460492
goto out;
461493
}
462494

@@ -466,8 +498,7 @@ static int cpufreq_governor_init(struct cpufreq_policy *policy)
466498
goto free_policy_dbs_info;
467499
}
468500

469-
INIT_LIST_HEAD(&dbs_data->policy_dbs_list);
470-
mutex_init(&dbs_data->mutex);
501+
gov_attr_set_init(&dbs_data->attr_set, &policy_dbs->list);
471502

472503
ret = gov->init(dbs_data, !policy->governor->initialized);
473504
if (ret)
@@ -487,14 +518,11 @@ static int cpufreq_governor_init(struct cpufreq_policy *policy)
487518
if (!have_governor_per_policy())
488519
gov->gdbs_data = dbs_data;
489520

490-
policy->governor_data = policy_dbs;
491-
492521
policy_dbs->dbs_data = dbs_data;
493-
dbs_data->usage_count = 1;
494-
list_add(&policy_dbs->list, &dbs_data->policy_dbs_list);
522+
policy->governor_data = policy_dbs;
495523

496524
gov->kobj_type.sysfs_ops = &governor_sysfs_ops;
497-
ret = kobject_init_and_add(&dbs_data->kobj, &gov->kobj_type,
525+
ret = kobject_init_and_add(&dbs_data->attr_set.kobj, &gov->kobj_type,
498526
get_governor_parent_kobj(policy),
499527
"%s", gov->gov.name);
500528
if (!ret)
@@ -523,29 +551,21 @@ static int cpufreq_governor_exit(struct cpufreq_policy *policy)
523551
struct dbs_governor *gov = dbs_governor_of(policy);
524552
struct policy_dbs_info *policy_dbs = policy->governor_data;
525553
struct dbs_data *dbs_data = policy_dbs->dbs_data;
526-
int count;
554+
unsigned int count;
527555

528556
/* Protect gov->gdbs_data against concurrent updates. */
529557
mutex_lock(&gov_dbs_data_mutex);
530558

531-
mutex_lock(&dbs_data->mutex);
532-
list_del(&policy_dbs->list);
533-
count = --dbs_data->usage_count;
534-
mutex_unlock(&dbs_data->mutex);
559+
count = gov_attr_set_put(&dbs_data->attr_set, &policy_dbs->list);
535560

536-
if (!count) {
537-
kobject_put(&dbs_data->kobj);
538-
539-
policy->governor_data = NULL;
561+
policy->governor_data = NULL;
540562

563+
if (!count) {
541564
if (!have_governor_per_policy())
542565
gov->gdbs_data = NULL;
543566

544567
gov->exit(dbs_data, policy->governor->initialized == 1);
545-
mutex_destroy(&dbs_data->mutex);
546568
kfree(dbs_data);
547-
} else {
548-
policy->governor_data = NULL;
549569
}
550570

551571
free_policy_dbs_info(policy_dbs, gov);

drivers/cpufreq/cpufreq_governor.h

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@
4141
/* Ondemand Sampling types */
4242
enum {OD_NORMAL_SAMPLE, OD_SUB_SAMPLE};
4343

44+
struct gov_attr_set {
45+
struct kobject kobj;
46+
struct list_head policy_list;
47+
struct mutex update_lock;
48+
int usage_count;
49+
};
50+
4451
/*
4552
* Abbreviations:
4653
* dbs: used as a shortform for demand based switching It helps to keep variable
@@ -52,45 +59,43 @@ enum {OD_NORMAL_SAMPLE, OD_SUB_SAMPLE};
5259

5360
/* Governor demand based switching data (per-policy or global). */
5461
struct dbs_data {
55-
int usage_count;
62+
struct gov_attr_set attr_set;
5663
void *tuners;
5764
unsigned int min_sampling_rate;
5865
unsigned int ignore_nice_load;
5966
unsigned int sampling_rate;
6067
unsigned int sampling_down_factor;
6168
unsigned int up_threshold;
6269
unsigned int io_is_busy;
63-
64-
struct kobject kobj;
65-
struct list_head policy_dbs_list;
66-
/*
67-
* Protect concurrent updates to governor tunables from sysfs,
68-
* policy_dbs_list and usage_count.
69-
*/
70-
struct mutex mutex;
7170
};
7271

72+
static inline struct dbs_data *to_dbs_data(struct gov_attr_set *attr_set)
73+
{
74+
return container_of(attr_set, struct dbs_data, attr_set);
75+
}
76+
7377
/* Governor's specific attributes */
74-
struct dbs_data;
7578
struct governor_attr {
7679
struct attribute attr;
77-
ssize_t (*show)(struct dbs_data *dbs_data, char *buf);
78-
ssize_t (*store)(struct dbs_data *dbs_data, const char *buf,
80+
ssize_t (*show)(struct gov_attr_set *attr_set, char *buf);
81+
ssize_t (*store)(struct gov_attr_set *attr_set, const char *buf,
7982
size_t count);
8083
};
8184

8285
#define gov_show_one(_gov, file_name) \
8386
static ssize_t show_##file_name \
84-
(struct dbs_data *dbs_data, char *buf) \
87+
(struct gov_attr_set *attr_set, char *buf) \
8588
{ \
89+
struct dbs_data *dbs_data = to_dbs_data(attr_set); \
8690
struct _gov##_dbs_tuners *tuners = dbs_data->tuners; \
8791
return sprintf(buf, "%u\n", tuners->file_name); \
8892
}
8993

9094
#define gov_show_one_common(file_name) \
9195
static ssize_t show_##file_name \
92-
(struct dbs_data *dbs_data, char *buf) \
96+
(struct gov_attr_set *attr_set, char *buf) \
9397
{ \
98+
struct dbs_data *dbs_data = to_dbs_data(attr_set); \
9499
return sprintf(buf, "%u\n", dbs_data->file_name); \
95100
}
96101

@@ -184,7 +189,7 @@ void od_register_powersave_bias_handler(unsigned int (*f)
184189
(struct cpufreq_policy *, unsigned int, unsigned int),
185190
unsigned int powersave_bias);
186191
void od_unregister_powersave_bias_handler(void);
187-
ssize_t store_sampling_rate(struct dbs_data *dbs_data, const char *buf,
192+
ssize_t store_sampling_rate(struct gov_attr_set *attr_set, const char *buf,
188193
size_t count);
189194
void gov_update_cpu_data(struct dbs_data *dbs_data);
190195
#endif /* _CPUFREQ_GOVERNOR_H */

0 commit comments

Comments
 (0)