Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <rafael.j.wysocki@intel.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

+107 -72
+15 -10
drivers/cpufreq/cpufreq_conservative.c
··· 129 129 /************************** sysfs interface ************************/ 130 130 static struct dbs_governor cs_dbs_gov; 131 131 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) 134 134 { 135 + struct dbs_data *dbs_data = to_dbs_data(attr_set); 135 136 unsigned int input; 136 137 int ret; 137 138 ret = sscanf(buf, "%u", &input); ··· 144 143 return count; 145 144 } 146 145 147 - static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf, 148 - size_t count) 146 + static ssize_t store_up_threshold(struct gov_attr_set *attr_set, 147 + const char *buf, size_t count) 149 148 { 149 + struct dbs_data *dbs_data = to_dbs_data(attr_set); 150 150 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; 151 151 unsigned int input; 152 152 int ret; ··· 160 158 return count; 161 159 } 162 160 163 - static ssize_t store_down_threshold(struct dbs_data *dbs_data, const char *buf, 164 - size_t count) 161 + static ssize_t store_down_threshold(struct gov_attr_set *attr_set, 162 + const char *buf, size_t count) 165 163 { 164 + struct dbs_data *dbs_data = to_dbs_data(attr_set); 166 165 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; 167 166 unsigned int input; 168 167 int ret; ··· 178 175 return count; 179 176 } 180 177 181 - static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data, 182 - const char *buf, size_t count) 178 + static ssize_t store_ignore_nice_load(struct gov_attr_set *attr_set, 179 + const char *buf, size_t count) 183 180 { 181 + struct dbs_data *dbs_data = to_dbs_data(attr_set); 184 182 unsigned int input; 185 183 int ret; 186 184 ··· 203 199 return count; 204 200 } 205 201 206 - static ssize_t store_freq_step(struct dbs_data *dbs_data, const char *buf, 207 - size_t count) 202 + static ssize_t store_freq_step(struct gov_attr_set *attr_set, const char *buf, 203 + size_t count) 208 204 { 205 + struct dbs_data *dbs_data = to_dbs_data(attr_set); 209 206 struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; 210 207 unsigned int input; 211 208 int ret;
+55 -35
drivers/cpufreq/cpufreq_governor.c
··· 43 43 * This must be called with dbs_data->mutex held, otherwise traversing 44 44 * policy_dbs_list isn't safe. 45 45 */ 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, 47 47 size_t count) 48 48 { 49 + struct dbs_data *dbs_data = to_dbs_data(attr_set); 49 50 struct policy_dbs_info *policy_dbs; 50 51 unsigned int rate; 51 52 int ret; ··· 60 59 * We are operating under dbs_data->mutex and so the list and its 61 60 * entries can't be freed concurrently. 62 61 */ 63 - list_for_each_entry(policy_dbs, &dbs_data->policy_dbs_list, list) { 62 + list_for_each_entry(policy_dbs, &attr_set->policy_list, list) { 64 63 mutex_lock(&policy_dbs->timer_mutex); 65 64 /* 66 65 * On 32-bit architectures this may race with the ··· 97 96 { 98 97 struct policy_dbs_info *policy_dbs; 99 98 100 - list_for_each_entry(policy_dbs, &dbs_data->policy_dbs_list, list) { 99 + list_for_each_entry(policy_dbs, &dbs_data->attr_set.policy_list, list) { 101 100 unsigned int j; 102 101 103 102 for_each_cpu(j, policy_dbs->policy->cpus) { ··· 112 111 } 113 112 EXPORT_SYMBOL_GPL(gov_update_cpu_data); 114 113 115 - static inline struct dbs_data *to_dbs_data(struct kobject *kobj) 114 + static inline struct gov_attr_set *to_gov_attr_set(struct kobject *kobj) 116 115 { 117 - return container_of(kobj, struct dbs_data, kobj); 116 + return container_of(kobj, struct gov_attr_set, kobj); 118 117 } 119 118 120 119 static inline struct governor_attr *to_gov_attr(struct attribute *attr) ··· 125 124 static ssize_t governor_show(struct kobject *kobj, struct attribute *attr, 126 125 char *buf) 127 126 { 128 - struct dbs_data *dbs_data = to_dbs_data(kobj); 129 127 struct governor_attr *gattr = to_gov_attr(attr); 130 128 131 - return gattr->show(dbs_data, buf); 129 + return gattr->show(to_gov_attr_set(kobj), buf); 132 130 } 133 131 134 132 static ssize_t governor_store(struct kobject *kobj, struct attribute *attr, 135 133 const char *buf, size_t count) 136 134 { 137 - struct dbs_data *dbs_data = to_dbs_data(kobj); 135 + struct gov_attr_set *attr_set = to_gov_attr_set(kobj); 138 136 struct governor_attr *gattr = to_gov_attr(attr); 139 137 int ret = -EBUSY; 140 138 141 - mutex_lock(&dbs_data->mutex); 139 + mutex_lock(&attr_set->update_lock); 142 140 143 - if (dbs_data->usage_count) 144 - ret = gattr->store(dbs_data, buf, count); 141 + if (attr_set->usage_count) 142 + ret = gattr->store(attr_set, buf, count); 145 143 146 - mutex_unlock(&dbs_data->mutex); 144 + mutex_unlock(&attr_set->update_lock); 147 145 148 146 return ret; 149 147 } ··· 425 425 gov->free(policy_dbs); 426 426 } 427 427 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 + 428 463 static int cpufreq_governor_init(struct cpufreq_policy *policy) 429 464 { 430 465 struct dbs_governor *gov = dbs_governor_of(policy); ··· 488 453 policy_dbs->dbs_data = dbs_data; 489 454 policy->governor_data = policy_dbs; 490 455 491 - mutex_lock(&dbs_data->mutex); 492 - dbs_data->usage_count++; 493 - list_add(&policy_dbs->list, &dbs_data->policy_dbs_list); 494 - mutex_unlock(&dbs_data->mutex); 456 + gov_attr_set_get(&dbs_data->attr_set, &policy_dbs->list); 495 457 goto out; 496 458 } 497 459 ··· 498 466 goto free_policy_dbs_info; 499 467 } 500 468 501 - INIT_LIST_HEAD(&dbs_data->policy_dbs_list); 502 - mutex_init(&dbs_data->mutex); 469 + gov_attr_set_init(&dbs_data->attr_set, &policy_dbs->list); 503 470 504 471 ret = gov->init(dbs_data, !policy->governor->initialized); 505 472 if (ret) ··· 518 487 if (!have_governor_per_policy()) 519 488 gov->gdbs_data = dbs_data; 520 489 490 + policy_dbs->dbs_data = dbs_data; 521 491 policy->governor_data = policy_dbs; 522 492 523 - policy_dbs->dbs_data = dbs_data; 524 - dbs_data->usage_count = 1; 525 - list_add(&policy_dbs->list, &dbs_data->policy_dbs_list); 526 - 527 493 gov->kobj_type.sysfs_ops = &governor_sysfs_ops; 528 - ret = kobject_init_and_add(&dbs_data->kobj, &gov->kobj_type, 494 + ret = kobject_init_and_add(&dbs_data->attr_set.kobj, &gov->kobj_type, 529 495 get_governor_parent_kobj(policy), 530 496 "%s", gov->gov.name); 531 497 if (!ret) ··· 551 523 struct dbs_governor *gov = dbs_governor_of(policy); 552 524 struct policy_dbs_info *policy_dbs = policy->governor_data; 553 525 struct dbs_data *dbs_data = policy_dbs->dbs_data; 554 - int count; 526 + unsigned int count; 555 527 556 528 /* Protect gov->gdbs_data against concurrent updates. */ 557 529 mutex_lock(&gov_dbs_data_mutex); 558 530 559 - mutex_lock(&dbs_data->mutex); 560 - list_del(&policy_dbs->list); 561 - count = --dbs_data->usage_count; 562 - mutex_unlock(&dbs_data->mutex); 531 + count = gov_attr_set_put(&dbs_data->attr_set, &policy_dbs->list); 532 + 533 + policy->governor_data = NULL; 563 534 564 535 if (!count) { 565 - kobject_put(&dbs_data->kobj); 566 - 567 - policy->governor_data = NULL; 568 - 569 536 if (!have_governor_per_policy()) 570 537 gov->gdbs_data = NULL; 571 538 572 539 gov->exit(dbs_data, policy->governor->initialized == 1); 573 - mutex_destroy(&dbs_data->mutex); 574 540 kfree(dbs_data); 575 - } else { 576 - policy->governor_data = NULL; 577 541 } 578 542 579 543 free_policy_dbs_info(policy_dbs, gov);
+20 -15
drivers/cpufreq/cpufreq_governor.h
··· 41 41 /* Ondemand Sampling types */ 42 42 enum {OD_NORMAL_SAMPLE, OD_SUB_SAMPLE}; 43 43 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 + 44 51 /* 45 52 * Abbreviations: 46 53 * dbs: used as a shortform for demand based switching It helps to keep variable ··· 59 52 60 53 /* Governor demand based switching data (per-policy or global). */ 61 54 struct dbs_data { 62 - int usage_count; 55 + struct gov_attr_set attr_set; 63 56 void *tuners; 64 57 unsigned int min_sampling_rate; 65 58 unsigned int ignore_nice_load; ··· 67 60 unsigned int sampling_down_factor; 68 61 unsigned int up_threshold; 69 62 unsigned int io_is_busy; 70 - 71 - struct kobject kobj; 72 - struct list_head policy_dbs_list; 73 - /* 74 - * Protect concurrent updates to governor tunables from sysfs, 75 - * policy_dbs_list and usage_count. 76 - */ 77 - struct mutex mutex; 78 63 }; 79 64 65 + static inline struct dbs_data *to_dbs_data(struct gov_attr_set *attr_set) 66 + { 67 + return container_of(attr_set, struct dbs_data, attr_set); 68 + } 69 + 80 70 /* Governor's specific attributes */ 81 - struct dbs_data; 82 71 struct governor_attr { 83 72 struct attribute attr; 84 - ssize_t (*show)(struct dbs_data *dbs_data, char *buf); 85 - ssize_t (*store)(struct dbs_data *dbs_data, const char *buf, 73 + ssize_t (*show)(struct gov_attr_set *attr_set, char *buf); 74 + ssize_t (*store)(struct gov_attr_set *attr_set, const char *buf, 86 75 size_t count); 87 76 }; 88 77 89 78 #define gov_show_one(_gov, file_name) \ 90 79 static ssize_t show_##file_name \ 91 - (struct dbs_data *dbs_data, char *buf) \ 80 + (struct gov_attr_set *attr_set, char *buf) \ 92 81 { \ 82 + struct dbs_data *dbs_data = to_dbs_data(attr_set); \ 93 83 struct _gov##_dbs_tuners *tuners = dbs_data->tuners; \ 94 84 return sprintf(buf, "%u\n", tuners->file_name); \ 95 85 } 96 86 97 87 #define gov_show_one_common(file_name) \ 98 88 static ssize_t show_##file_name \ 99 - (struct dbs_data *dbs_data, char *buf) \ 89 + (struct gov_attr_set *attr_set, char *buf) \ 100 90 { \ 91 + struct dbs_data *dbs_data = to_dbs_data(attr_set); \ 101 92 return sprintf(buf, "%u\n", dbs_data->file_name); \ 102 93 } 103 94 ··· 189 184 (struct cpufreq_policy *, unsigned int, unsigned int), 190 185 unsigned int powersave_bias); 191 186 void od_unregister_powersave_bias_handler(void); 192 - ssize_t store_sampling_rate(struct dbs_data *dbs_data, const char *buf, 187 + ssize_t store_sampling_rate(struct gov_attr_set *attr_set, const char *buf, 193 188 size_t count); 194 189 void gov_update_cpu_data(struct dbs_data *dbs_data); 195 190 #endif /* _CPUFREQ_GOVERNOR_H */
+17 -12
drivers/cpufreq/cpufreq_ondemand.c
··· 207 207 /************************** sysfs interface ************************/ 208 208 static struct dbs_governor od_dbs_gov; 209 209 210 - static ssize_t store_io_is_busy(struct dbs_data *dbs_data, const char *buf, 211 - size_t count) 210 + static ssize_t store_io_is_busy(struct gov_attr_set *attr_set, const char *buf, 211 + size_t count) 212 212 { 213 + struct dbs_data *dbs_data = to_dbs_data(attr_set); 213 214 unsigned int input; 214 215 int ret; 215 216 ··· 225 224 return count; 226 225 } 227 226 228 - static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf, 229 - size_t count) 227 + static ssize_t store_up_threshold(struct gov_attr_set *attr_set, 228 + const char *buf, size_t count) 230 229 { 230 + struct dbs_data *dbs_data = to_dbs_data(attr_set); 231 231 unsigned int input; 232 232 int ret; 233 233 ret = sscanf(buf, "%u", &input); ··· 242 240 return count; 243 241 } 244 242 245 - static ssize_t store_sampling_down_factor(struct dbs_data *dbs_data, 246 - const char *buf, size_t count) 243 + static ssize_t store_sampling_down_factor(struct gov_attr_set *attr_set, 244 + const char *buf, size_t count) 247 245 { 246 + struct dbs_data *dbs_data = to_dbs_data(attr_set); 248 247 struct policy_dbs_info *policy_dbs; 249 248 unsigned int input; 250 249 int ret; ··· 257 254 dbs_data->sampling_down_factor = input; 258 255 259 256 /* Reset down sampling multiplier in case it was active */ 260 - list_for_each_entry(policy_dbs, &dbs_data->policy_dbs_list, list) { 257 + list_for_each_entry(policy_dbs, &attr_set->policy_list, list) { 261 258 /* 262 259 * Doing this without locking might lead to using different 263 260 * rate_mult values in od_update() and od_dbs_timer(). ··· 270 267 return count; 271 268 } 272 269 273 - static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data, 274 - const char *buf, size_t count) 270 + static ssize_t store_ignore_nice_load(struct gov_attr_set *attr_set, 271 + const char *buf, size_t count) 275 272 { 273 + struct dbs_data *dbs_data = to_dbs_data(attr_set); 276 274 unsigned int input; 277 275 int ret; 278 276 ··· 295 291 return count; 296 292 } 297 293 298 - static ssize_t store_powersave_bias(struct dbs_data *dbs_data, const char *buf, 299 - size_t count) 294 + static ssize_t store_powersave_bias(struct gov_attr_set *attr_set, 295 + const char *buf, size_t count) 300 296 { 297 + struct dbs_data *dbs_data = to_dbs_data(attr_set); 301 298 struct od_dbs_tuners *od_tuners = dbs_data->tuners; 302 299 struct policy_dbs_info *policy_dbs; 303 300 unsigned int input; ··· 313 308 314 309 od_tuners->powersave_bias = input; 315 310 316 - list_for_each_entry(policy_dbs, &dbs_data->policy_dbs_list, list) 311 + list_for_each_entry(policy_dbs, &attr_set->policy_list, list) 317 312 ondemand_powersave_bias_init(policy_dbs->policy); 318 313 319 314 return count;