Loading drivers/cpufreq/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ config CPU_FREQ if CPU_FREQ config CPU_FREQ_GOV_COMMON select IRQ_WORK bool config CPU_FREQ_BOOST_SW Loading drivers/cpufreq/amd_freq_sensitivity.c +4 −4 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ #include <asm/msr.h> #include <asm/cpufeature.h> #include "cpufreq_governor.h" #include "cpufreq_ondemand.h" #define MSR_AMD64_FREQ_SENSITIVITY_ACTUAL 0xc0010080 #define MSR_AMD64_FREQ_SENSITIVITY_REFERENCE 0xc0010081 Loading @@ -45,10 +45,10 @@ static unsigned int amd_powersave_bias_target(struct cpufreq_policy *policy, long d_actual, d_reference; struct msr actual, reference; struct cpu_data_t *data = &per_cpu(cpu_data, policy->cpu); struct dbs_data *od_data = policy->governor_data; struct policy_dbs_info *policy_dbs = policy->governor_data; struct dbs_data *od_data = policy_dbs->dbs_data; struct od_dbs_tuners *od_tuners = od_data->tuners; struct od_cpu_dbs_info_s *od_info = od_data->cdata->get_cpu_dbs_info_s(policy->cpu); struct od_policy_dbs_info *od_info = to_dbs_info(policy_dbs); if (!od_info->freq_table) return freq_next; Loading drivers/cpufreq/cpufreq.c +67 −98 Original line number Diff line number Diff line Loading @@ -64,7 +64,6 @@ static LIST_HEAD(cpufreq_governor_list); static struct cpufreq_driver *cpufreq_driver; static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); static DEFINE_RWLOCK(cpufreq_driver_lock); DEFINE_MUTEX(cpufreq_governor_lock); /* Flag to suspend/resume CPUFreq governors */ static bool cpufreq_suspended; Loading @@ -75,10 +74,8 @@ static inline bool has_target(void) } /* internal prototypes */ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); static unsigned int __cpufreq_get(struct cpufreq_policy *policy); static void handle_update(struct work_struct *work); /** * Two notifier lists: the "policy" list is involved in the Loading Loading @@ -955,30 +952,38 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cp if (cpumask_test_cpu(cpu, policy->cpus)) return 0; down_write(&policy->rwsem); if (has_target()) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); if (ret) { pr_err("%s: Failed to stop governor\n", __func__); return ret; goto unlock; } } down_write(&policy->rwsem); cpumask_set_cpu(cpu, policy->cpus); up_write(&policy->rwsem); if (has_target()) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_START); ret = cpufreq_governor(policy, CPUFREQ_GOV_START); if (!ret) ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); ret = cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); if (ret) { if (ret) pr_err("%s: Failed to start governor\n", __func__); return ret; } unlock: up_write(&policy->rwsem); return ret; } return 0; static void handle_update(struct work_struct *work) { struct cpufreq_policy *policy = container_of(work, struct cpufreq_policy, update); unsigned int cpu = policy->cpu; pr_debug("handle_update for cpu %u called\n", cpu); cpufreq_update_policy(cpu); } static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) Loading Loading @@ -1267,9 +1272,10 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) return ret; } static void cpufreq_offline_prepare(unsigned int cpu) static void cpufreq_offline(unsigned int cpu) { struct cpufreq_policy *policy; int ret; pr_debug("%s: unregistering CPU %u\n", __func__, cpu); Loading @@ -1279,13 +1285,13 @@ static void cpufreq_offline_prepare(unsigned int cpu) return; } down_write(&policy->rwsem); if (has_target()) { int ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); if (ret) pr_err("%s: Failed to stop governor\n", __func__); } down_write(&policy->rwsem); cpumask_clear_cpu(cpu, policy->cpus); if (policy_is_inactive(policy)) { Loading @@ -1298,39 +1304,27 @@ static void cpufreq_offline_prepare(unsigned int cpu) /* Nominate new CPU */ policy->cpu = cpumask_any(policy->cpus); } up_write(&policy->rwsem); /* Start governor again for active policy */ if (!policy_is_inactive(policy)) { if (has_target()) { int ret = __cpufreq_governor(policy, CPUFREQ_GOV_START); ret = cpufreq_governor(policy, CPUFREQ_GOV_START); if (!ret) ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); ret = cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); if (ret) pr_err("%s: Failed to start governor\n", __func__); } } else if (cpufreq_driver->stop_cpu) { cpufreq_driver->stop_cpu(policy); } } static void cpufreq_offline_finish(unsigned int cpu) { struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); if (!policy) { pr_debug("%s: No cpu_data found\n", __func__); return; goto unlock; } /* Only proceed for inactive policies */ if (!policy_is_inactive(policy)) return; if (cpufreq_driver->stop_cpu) cpufreq_driver->stop_cpu(policy); /* If cpu is last user of policy, free policy */ if (has_target()) { int ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); if (ret) pr_err("%s: Failed to exit governor\n", __func__); } Loading @@ -1344,6 +1338,9 @@ static void cpufreq_offline_finish(unsigned int cpu) cpufreq_driver->exit(policy); policy->freq_table = NULL; } unlock: up_write(&policy->rwsem); } /** Loading @@ -1359,10 +1356,8 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) if (!policy) return; if (cpu_online(cpu)) { cpufreq_offline_prepare(cpu); cpufreq_offline_finish(cpu); } if (cpu_online(cpu)) cpufreq_offline(cpu); cpumask_clear_cpu(cpu, policy->real_cpus); remove_cpu_dev_symlink(policy, cpu); Loading @@ -1371,15 +1366,6 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) cpufreq_policy_free(policy, true); } static void handle_update(struct work_struct *work) { struct cpufreq_policy *policy = container_of(work, struct cpufreq_policy, update); unsigned int cpu = policy->cpu; pr_debug("handle_update for cpu %u called\n", cpu); cpufreq_update_policy(cpu); } /** * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're * in deep trouble. Loading Loading @@ -1542,6 +1528,7 @@ EXPORT_SYMBOL(cpufreq_generic_suspend); void cpufreq_suspend(void) { struct cpufreq_policy *policy; int ret; if (!cpufreq_driver) return; Loading @@ -1552,7 +1539,11 @@ void cpufreq_suspend(void) pr_debug("%s: Suspending Governors\n", __func__); for_each_active_policy(policy) { if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP)) down_write(&policy->rwsem); ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); up_write(&policy->rwsem); if (ret) pr_err("%s: Failed to stop governor for policy: %p\n", __func__, policy); else if (cpufreq_driver->suspend Loading @@ -1574,6 +1565,7 @@ void cpufreq_suspend(void) void cpufreq_resume(void) { struct cpufreq_policy *policy; int ret; if (!cpufreq_driver) return; Loading @@ -1586,14 +1578,21 @@ void cpufreq_resume(void) pr_debug("%s: Resuming Governors\n", __func__); for_each_active_policy(policy) { if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) { pr_err("%s: Failed to resume driver: %p\n", __func__, policy); else if (__cpufreq_governor(policy, CPUFREQ_GOV_START) || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS)) } else { down_write(&policy->rwsem); ret = cpufreq_governor(policy, CPUFREQ_GOV_START); if (!ret) cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); up_write(&policy->rwsem); if (ret) pr_err("%s: Failed to start governor for policy: %p\n", __func__, policy); } } /* * schedule call cpufreq_update_policy() for first-online CPU, as that Loading Loading @@ -1878,8 +1877,7 @@ __weak struct cpufreq_governor *cpufreq_fallback_governor(void) return NULL; } static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) { int ret; Loading Loading @@ -1913,21 +1911,6 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, pr_debug("%s: for CPU %u, event %u\n", __func__, policy->cpu, event); mutex_lock(&cpufreq_governor_lock); if ((policy->governor_enabled && event == CPUFREQ_GOV_START) || (!policy->governor_enabled && (event == CPUFREQ_GOV_LIMITS || event == CPUFREQ_GOV_STOP))) { mutex_unlock(&cpufreq_governor_lock); return -EBUSY; } if (event == CPUFREQ_GOV_STOP) policy->governor_enabled = false; else if (event == CPUFREQ_GOV_START) policy->governor_enabled = true; mutex_unlock(&cpufreq_governor_lock); ret = policy->governor->governor(policy, event); if (!ret) { Loading @@ -1935,14 +1918,6 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, policy->governor->initialized++; else if (event == CPUFREQ_GOV_POLICY_EXIT) policy->governor->initialized--; } else { /* Restore original values */ mutex_lock(&cpufreq_governor_lock); if (event == CPUFREQ_GOV_STOP) policy->governor_enabled = true; else if (event == CPUFREQ_GOV_START) policy->governor_enabled = false; mutex_unlock(&cpufreq_governor_lock); } if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) || Loading Loading @@ -2097,7 +2072,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, old_gov = policy->governor; /* end old governor */ if (old_gov) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); if (ret) { /* This can happen due to race with other operations */ pr_debug("%s: Failed to Stop Governor: %s (%d)\n", Loading @@ -2105,10 +2080,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, return ret; } up_write(&policy->rwsem); ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); down_write(&policy->rwsem); ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); if (ret) { pr_err("%s: Failed to Exit Governor: %s (%d)\n", __func__, old_gov->name, ret); Loading @@ -2118,32 +2090,30 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, /* start new governor */ policy->governor = new_policy->governor; ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); if (!ret) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_START); ret = cpufreq_governor(policy, CPUFREQ_GOV_START); if (!ret) goto out; up_write(&policy->rwsem); __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); down_write(&policy->rwsem); cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); } /* new governor failed, so re-start old one */ pr_debug("starting governor %s failed\n", policy->governor->name); if (old_gov) { policy->governor = old_gov; if (__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) if (cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) policy->governor = NULL; else __cpufreq_governor(policy, CPUFREQ_GOV_START); cpufreq_governor(policy, CPUFREQ_GOV_START); } return ret; out: pr_debug("governor: change or update limits\n"); return __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); return cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); } /** Loading Loading @@ -2210,11 +2180,7 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, break; case CPU_DOWN_PREPARE: cpufreq_offline_prepare(cpu); break; case CPU_POST_DEAD: cpufreq_offline_finish(cpu); cpufreq_offline(cpu); break; case CPU_DOWN_FAILED: Loading Loading @@ -2247,8 +2213,11 @@ static int cpufreq_boost_set_sw(int state) __func__); break; } down_write(&policy->rwsem); policy->user_policy.max = policy->max; __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); up_write(&policy->rwsem); } } Loading drivers/cpufreq/cpufreq_conservative.c +124 −152 Original line number Diff line number Diff line Loading @@ -14,6 +14,22 @@ #include <linux/slab.h> #include "cpufreq_governor.h" struct cs_policy_dbs_info { struct policy_dbs_info policy_dbs; unsigned int down_skip; unsigned int requested_freq; }; static inline struct cs_policy_dbs_info *to_dbs_info(struct policy_dbs_info *policy_dbs) { return container_of(policy_dbs, struct cs_policy_dbs_info, policy_dbs); } struct cs_dbs_tuners { unsigned int down_threshold; unsigned int freq_step; }; /* Conservative governor macros */ #define DEF_FREQUENCY_UP_THRESHOLD (80) #define DEF_FREQUENCY_DOWN_THRESHOLD (20) Loading @@ -21,18 +37,6 @@ #define DEF_SAMPLING_DOWN_FACTOR (1) #define MAX_SAMPLING_DOWN_FACTOR (10) static DEFINE_PER_CPU(struct cs_cpu_dbs_info_s, cs_cpu_dbs_info); static int cs_cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event); static struct cpufreq_governor cpufreq_gov_conservative = { .name = "conservative", .governor = cs_cpufreq_governor_dbs, .max_transition_latency = TRANSITION_LATENCY_LIMIT, .owner = THIS_MODULE, }; static inline unsigned int get_freq_target(struct cs_dbs_tuners *cs_tuners, struct cpufreq_policy *policy) { Loading @@ -54,27 +58,28 @@ static inline unsigned int get_freq_target(struct cs_dbs_tuners *cs_tuners, * Any frequency increase takes it to the maximum frequency. Frequency reduction * happens at minimum steps of 5% (default) of maximum frequency */ static void cs_check_cpu(int cpu, unsigned int load) static unsigned int cs_dbs_timer(struct cpufreq_policy *policy) { struct cs_cpu_dbs_info_s *dbs_info = &per_cpu(cs_cpu_dbs_info, cpu); struct cpufreq_policy *policy = dbs_info->cdbs.shared->policy; struct dbs_data *dbs_data = policy->governor_data; struct policy_dbs_info *policy_dbs = policy->governor_data; struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs); struct dbs_data *dbs_data = policy_dbs->dbs_data; struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; unsigned int load = dbs_update(policy); /* * break out if we 'cannot' reduce the speed as the user might * want freq_step to be zero */ if (cs_tuners->freq_step == 0) return; goto out; /* Check for frequency increase */ if (load > cs_tuners->up_threshold) { if (load > dbs_data->up_threshold) { dbs_info->down_skip = 0; /* if we are already at full speed then break out early */ if (dbs_info->requested_freq == policy->max) return; goto out; dbs_info->requested_freq += get_freq_target(cs_tuners, policy); Loading @@ -83,12 +88,12 @@ static void cs_check_cpu(int cpu, unsigned int load) __cpufreq_driver_target(policy, dbs_info->requested_freq, CPUFREQ_RELATION_H); return; goto out; } /* if sampling_down_factor is active break out early */ if (++dbs_info->down_skip < cs_tuners->sampling_down_factor) return; if (++dbs_info->down_skip < dbs_data->sampling_down_factor) goto out; dbs_info->down_skip = 0; /* Check for frequency decrease */ Loading @@ -98,7 +103,7 @@ static void cs_check_cpu(int cpu, unsigned int load) * if we cannot reduce the frequency anymore, break out early */ if (policy->cur == policy->min) return; goto out; freq_target = get_freq_target(cs_tuners, policy); if (dbs_info->requested_freq > freq_target) Loading @@ -108,58 +113,25 @@ static void cs_check_cpu(int cpu, unsigned int load) __cpufreq_driver_target(policy, dbs_info->requested_freq, CPUFREQ_RELATION_L); return; } } static unsigned int cs_dbs_timer(struct cpufreq_policy *policy, bool modify_all) { struct dbs_data *dbs_data = policy->governor_data; struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; if (modify_all) dbs_check_cpu(dbs_data, policy->cpu); return delay_for_sampling_rate(cs_tuners->sampling_rate); out: return dbs_data->sampling_rate; } static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) { struct cpufreq_freqs *freq = data; struct cs_cpu_dbs_info_s *dbs_info = &per_cpu(cs_cpu_dbs_info, freq->cpu); struct cpufreq_policy *policy = cpufreq_cpu_get_raw(freq->cpu); if (!policy) return 0; /* policy isn't governed by conservative governor */ if (policy->governor != &cpufreq_gov_conservative) return 0; /* * we only care if our internally tracked freq moves outside the 'valid' * ranges of frequency available to us otherwise we do not change it */ if (dbs_info->requested_freq > policy->max || dbs_info->requested_freq < policy->min) dbs_info->requested_freq = freq->new; return 0; } void *data); static struct notifier_block cs_cpufreq_notifier_block = { .notifier_call = dbs_cpufreq_notifier, }; /************************** sysfs interface ************************/ static struct common_dbs_data cs_dbs_cdata; static struct dbs_governor cs_dbs_gov; static ssize_t store_sampling_down_factor(struct dbs_data *dbs_data, const char *buf, size_t count) { struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; unsigned int input; int ret; ret = sscanf(buf, "%u", &input); Loading @@ -167,22 +139,7 @@ static ssize_t store_sampling_down_factor(struct dbs_data *dbs_data, if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1) return -EINVAL; cs_tuners->sampling_down_factor = input; return count; } static ssize_t store_sampling_rate(struct dbs_data *dbs_data, const char *buf, size_t count) { struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; unsigned int input; int ret; ret = sscanf(buf, "%u", &input); if (ret != 1) return -EINVAL; cs_tuners->sampling_rate = max(input, dbs_data->min_sampling_rate); dbs_data->sampling_down_factor = input; return count; } Loading @@ -197,7 +154,7 @@ static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf, if (ret != 1 || input > 100 || input <= cs_tuners->down_threshold) return -EINVAL; cs_tuners->up_threshold = input; dbs_data->up_threshold = input; return count; } Loading @@ -211,7 +168,7 @@ static ssize_t store_down_threshold(struct dbs_data *dbs_data, const char *buf, /* cannot be lower than 11 otherwise freq will not fall */ if (ret != 1 || input < 11 || input > 100 || input >= cs_tuners->up_threshold) input >= dbs_data->up_threshold) return -EINVAL; cs_tuners->down_threshold = input; Loading @@ -221,8 +178,7 @@ static ssize_t store_down_threshold(struct dbs_data *dbs_data, const char *buf, static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data, const char *buf, size_t count) { struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; unsigned int input, j; unsigned int input; int ret; ret = sscanf(buf, "%u", &input); Loading @@ -232,21 +188,14 @@ static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data, if (input > 1) input = 1; if (input == cs_tuners->ignore_nice_load) /* nothing to do */ if (input == dbs_data->ignore_nice_load) /* nothing to do */ return count; cs_tuners->ignore_nice_load = input; dbs_data->ignore_nice_load = input; /* we need to re-evaluate prev_cpu_idle */ for_each_online_cpu(j) { struct cs_cpu_dbs_info_s *dbs_info; dbs_info = &per_cpu(cs_cpu_dbs_info, j); dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j, &dbs_info->cdbs.prev_cpu_wall, 0); if (cs_tuners->ignore_nice_load) dbs_info->cdbs.prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE]; } gov_update_cpu_data(dbs_data); return count; } Loading @@ -272,55 +221,47 @@ static ssize_t store_freq_step(struct dbs_data *dbs_data, const char *buf, return count; } show_store_one(cs, sampling_rate); show_store_one(cs, sampling_down_factor); show_store_one(cs, up_threshold); show_store_one(cs, down_threshold); show_store_one(cs, ignore_nice_load); show_store_one(cs, freq_step); declare_show_sampling_rate_min(cs); gov_sys_pol_attr_rw(sampling_rate); gov_sys_pol_attr_rw(sampling_down_factor); gov_sys_pol_attr_rw(up_threshold); gov_sys_pol_attr_rw(down_threshold); gov_sys_pol_attr_rw(ignore_nice_load); gov_sys_pol_attr_rw(freq_step); gov_sys_pol_attr_ro(sampling_rate_min); static struct attribute *dbs_attributes_gov_sys[] = { &sampling_rate_min_gov_sys.attr, &sampling_rate_gov_sys.attr, &sampling_down_factor_gov_sys.attr, &up_threshold_gov_sys.attr, &down_threshold_gov_sys.attr, &ignore_nice_load_gov_sys.attr, &freq_step_gov_sys.attr, gov_show_one_common(sampling_rate); gov_show_one_common(sampling_down_factor); gov_show_one_common(up_threshold); gov_show_one_common(ignore_nice_load); gov_show_one_common(min_sampling_rate); gov_show_one(cs, down_threshold); gov_show_one(cs, freq_step); gov_attr_rw(sampling_rate); gov_attr_rw(sampling_down_factor); gov_attr_rw(up_threshold); gov_attr_rw(ignore_nice_load); gov_attr_ro(min_sampling_rate); gov_attr_rw(down_threshold); gov_attr_rw(freq_step); static struct attribute *cs_attributes[] = { &min_sampling_rate.attr, &sampling_rate.attr, &sampling_down_factor.attr, &up_threshold.attr, &down_threshold.attr, &ignore_nice_load.attr, &freq_step.attr, NULL }; static struct attribute_group cs_attr_group_gov_sys = { .attrs = dbs_attributes_gov_sys, .name = "conservative", }; /************************** sysfs end ************************/ static struct attribute *dbs_attributes_gov_pol[] = { &sampling_rate_min_gov_pol.attr, &sampling_rate_gov_pol.attr, &sampling_down_factor_gov_pol.attr, &up_threshold_gov_pol.attr, &down_threshold_gov_pol.attr, &ignore_nice_load_gov_pol.attr, &freq_step_gov_pol.attr, NULL }; static struct policy_dbs_info *cs_alloc(void) { struct cs_policy_dbs_info *dbs_info; static struct attribute_group cs_attr_group_gov_pol = { .attrs = dbs_attributes_gov_pol, .name = "conservative", }; dbs_info = kzalloc(sizeof(*dbs_info), GFP_KERNEL); return dbs_info ? &dbs_info->policy_dbs : NULL; } /************************** sysfs end ************************/ static void cs_free(struct policy_dbs_info *policy_dbs) { kfree(to_dbs_info(policy_dbs)); } static int cs_init(struct dbs_data *dbs_data, bool notify) { Loading @@ -332,11 +273,11 @@ static int cs_init(struct dbs_data *dbs_data, bool notify) return -ENOMEM; } tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD; tuners->down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD; tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR; tuners->ignore_nice_load = 0; tuners->freq_step = DEF_FREQUENCY_STEP; dbs_data->up_threshold = DEF_FREQUENCY_UP_THRESHOLD; dbs_data->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR; dbs_data->ignore_nice_load = 0; dbs_data->tuners = tuners; dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * Loading @@ -358,35 +299,66 @@ static void cs_exit(struct dbs_data *dbs_data, bool notify) kfree(dbs_data->tuners); } define_get_cpu_dbs_routines(cs_cpu_dbs_info); static void cs_start(struct cpufreq_policy *policy) { struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy->governor_data); dbs_info->down_skip = 0; dbs_info->requested_freq = policy->cur; } static struct common_dbs_data cs_dbs_cdata = { .governor = GOV_CONSERVATIVE, .attr_group_gov_sys = &cs_attr_group_gov_sys, .attr_group_gov_pol = &cs_attr_group_gov_pol, .get_cpu_cdbs = get_cpu_cdbs, .get_cpu_dbs_info_s = get_cpu_dbs_info_s, static struct dbs_governor cs_dbs_gov = { .gov = { .name = "conservative", .governor = cpufreq_governor_dbs, .max_transition_latency = TRANSITION_LATENCY_LIMIT, .owner = THIS_MODULE, }, .kobj_type = { .default_attrs = cs_attributes }, .gov_dbs_timer = cs_dbs_timer, .gov_check_cpu = cs_check_cpu, .alloc = cs_alloc, .free = cs_free, .init = cs_init, .exit = cs_exit, .mutex = __MUTEX_INITIALIZER(cs_dbs_cdata.mutex), .start = cs_start, }; static int cs_cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event) #define CPU_FREQ_GOV_CONSERVATIVE (&cs_dbs_gov.gov) static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) { return cpufreq_governor_dbs(policy, &cs_dbs_cdata, event); struct cpufreq_freqs *freq = data; struct cpufreq_policy *policy = cpufreq_cpu_get_raw(freq->cpu); struct cs_policy_dbs_info *dbs_info; if (!policy) return 0; /* policy isn't governed by conservative governor */ if (policy->governor != CPU_FREQ_GOV_CONSERVATIVE) return 0; dbs_info = to_dbs_info(policy->governor_data); /* * we only care if our internally tracked freq moves outside the 'valid' * ranges of frequency available to us otherwise we do not change it */ if (dbs_info->requested_freq > policy->max || dbs_info->requested_freq < policy->min) dbs_info->requested_freq = freq->new; return 0; } static int __init cpufreq_gov_dbs_init(void) { return cpufreq_register_governor(&cpufreq_gov_conservative); return cpufreq_register_governor(CPU_FREQ_GOV_CONSERVATIVE); } static void __exit cpufreq_gov_dbs_exit(void) { cpufreq_unregister_governor(&cpufreq_gov_conservative); cpufreq_unregister_governor(CPU_FREQ_GOV_CONSERVATIVE); } MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>"); Loading @@ -398,7 +370,7 @@ MODULE_LICENSE("GPL"); #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE struct cpufreq_governor *cpufreq_default_governor(void) { return &cpufreq_gov_conservative; return CPU_FREQ_GOV_CONSERVATIVE; } fs_initcall(cpufreq_gov_dbs_init); Loading drivers/cpufreq/cpufreq_governor.c +403 −363 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
drivers/cpufreq/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ config CPU_FREQ if CPU_FREQ config CPU_FREQ_GOV_COMMON select IRQ_WORK bool config CPU_FREQ_BOOST_SW Loading
drivers/cpufreq/amd_freq_sensitivity.c +4 −4 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ #include <asm/msr.h> #include <asm/cpufeature.h> #include "cpufreq_governor.h" #include "cpufreq_ondemand.h" #define MSR_AMD64_FREQ_SENSITIVITY_ACTUAL 0xc0010080 #define MSR_AMD64_FREQ_SENSITIVITY_REFERENCE 0xc0010081 Loading @@ -45,10 +45,10 @@ static unsigned int amd_powersave_bias_target(struct cpufreq_policy *policy, long d_actual, d_reference; struct msr actual, reference; struct cpu_data_t *data = &per_cpu(cpu_data, policy->cpu); struct dbs_data *od_data = policy->governor_data; struct policy_dbs_info *policy_dbs = policy->governor_data; struct dbs_data *od_data = policy_dbs->dbs_data; struct od_dbs_tuners *od_tuners = od_data->tuners; struct od_cpu_dbs_info_s *od_info = od_data->cdata->get_cpu_dbs_info_s(policy->cpu); struct od_policy_dbs_info *od_info = to_dbs_info(policy_dbs); if (!od_info->freq_table) return freq_next; Loading
drivers/cpufreq/cpufreq.c +67 −98 Original line number Diff line number Diff line Loading @@ -64,7 +64,6 @@ static LIST_HEAD(cpufreq_governor_list); static struct cpufreq_driver *cpufreq_driver; static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); static DEFINE_RWLOCK(cpufreq_driver_lock); DEFINE_MUTEX(cpufreq_governor_lock); /* Flag to suspend/resume CPUFreq governors */ static bool cpufreq_suspended; Loading @@ -75,10 +74,8 @@ static inline bool has_target(void) } /* internal prototypes */ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); static unsigned int __cpufreq_get(struct cpufreq_policy *policy); static void handle_update(struct work_struct *work); /** * Two notifier lists: the "policy" list is involved in the Loading Loading @@ -955,30 +952,38 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cp if (cpumask_test_cpu(cpu, policy->cpus)) return 0; down_write(&policy->rwsem); if (has_target()) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); if (ret) { pr_err("%s: Failed to stop governor\n", __func__); return ret; goto unlock; } } down_write(&policy->rwsem); cpumask_set_cpu(cpu, policy->cpus); up_write(&policy->rwsem); if (has_target()) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_START); ret = cpufreq_governor(policy, CPUFREQ_GOV_START); if (!ret) ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); ret = cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); if (ret) { if (ret) pr_err("%s: Failed to start governor\n", __func__); return ret; } unlock: up_write(&policy->rwsem); return ret; } return 0; static void handle_update(struct work_struct *work) { struct cpufreq_policy *policy = container_of(work, struct cpufreq_policy, update); unsigned int cpu = policy->cpu; pr_debug("handle_update for cpu %u called\n", cpu); cpufreq_update_policy(cpu); } static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) Loading Loading @@ -1267,9 +1272,10 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) return ret; } static void cpufreq_offline_prepare(unsigned int cpu) static void cpufreq_offline(unsigned int cpu) { struct cpufreq_policy *policy; int ret; pr_debug("%s: unregistering CPU %u\n", __func__, cpu); Loading @@ -1279,13 +1285,13 @@ static void cpufreq_offline_prepare(unsigned int cpu) return; } down_write(&policy->rwsem); if (has_target()) { int ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); if (ret) pr_err("%s: Failed to stop governor\n", __func__); } down_write(&policy->rwsem); cpumask_clear_cpu(cpu, policy->cpus); if (policy_is_inactive(policy)) { Loading @@ -1298,39 +1304,27 @@ static void cpufreq_offline_prepare(unsigned int cpu) /* Nominate new CPU */ policy->cpu = cpumask_any(policy->cpus); } up_write(&policy->rwsem); /* Start governor again for active policy */ if (!policy_is_inactive(policy)) { if (has_target()) { int ret = __cpufreq_governor(policy, CPUFREQ_GOV_START); ret = cpufreq_governor(policy, CPUFREQ_GOV_START); if (!ret) ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); ret = cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); if (ret) pr_err("%s: Failed to start governor\n", __func__); } } else if (cpufreq_driver->stop_cpu) { cpufreq_driver->stop_cpu(policy); } } static void cpufreq_offline_finish(unsigned int cpu) { struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); if (!policy) { pr_debug("%s: No cpu_data found\n", __func__); return; goto unlock; } /* Only proceed for inactive policies */ if (!policy_is_inactive(policy)) return; if (cpufreq_driver->stop_cpu) cpufreq_driver->stop_cpu(policy); /* If cpu is last user of policy, free policy */ if (has_target()) { int ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); if (ret) pr_err("%s: Failed to exit governor\n", __func__); } Loading @@ -1344,6 +1338,9 @@ static void cpufreq_offline_finish(unsigned int cpu) cpufreq_driver->exit(policy); policy->freq_table = NULL; } unlock: up_write(&policy->rwsem); } /** Loading @@ -1359,10 +1356,8 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) if (!policy) return; if (cpu_online(cpu)) { cpufreq_offline_prepare(cpu); cpufreq_offline_finish(cpu); } if (cpu_online(cpu)) cpufreq_offline(cpu); cpumask_clear_cpu(cpu, policy->real_cpus); remove_cpu_dev_symlink(policy, cpu); Loading @@ -1371,15 +1366,6 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) cpufreq_policy_free(policy, true); } static void handle_update(struct work_struct *work) { struct cpufreq_policy *policy = container_of(work, struct cpufreq_policy, update); unsigned int cpu = policy->cpu; pr_debug("handle_update for cpu %u called\n", cpu); cpufreq_update_policy(cpu); } /** * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're * in deep trouble. Loading Loading @@ -1542,6 +1528,7 @@ EXPORT_SYMBOL(cpufreq_generic_suspend); void cpufreq_suspend(void) { struct cpufreq_policy *policy; int ret; if (!cpufreq_driver) return; Loading @@ -1552,7 +1539,11 @@ void cpufreq_suspend(void) pr_debug("%s: Suspending Governors\n", __func__); for_each_active_policy(policy) { if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP)) down_write(&policy->rwsem); ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); up_write(&policy->rwsem); if (ret) pr_err("%s: Failed to stop governor for policy: %p\n", __func__, policy); else if (cpufreq_driver->suspend Loading @@ -1574,6 +1565,7 @@ void cpufreq_suspend(void) void cpufreq_resume(void) { struct cpufreq_policy *policy; int ret; if (!cpufreq_driver) return; Loading @@ -1586,14 +1578,21 @@ void cpufreq_resume(void) pr_debug("%s: Resuming Governors\n", __func__); for_each_active_policy(policy) { if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) { pr_err("%s: Failed to resume driver: %p\n", __func__, policy); else if (__cpufreq_governor(policy, CPUFREQ_GOV_START) || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS)) } else { down_write(&policy->rwsem); ret = cpufreq_governor(policy, CPUFREQ_GOV_START); if (!ret) cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); up_write(&policy->rwsem); if (ret) pr_err("%s: Failed to start governor for policy: %p\n", __func__, policy); } } /* * schedule call cpufreq_update_policy() for first-online CPU, as that Loading Loading @@ -1878,8 +1877,7 @@ __weak struct cpufreq_governor *cpufreq_fallback_governor(void) return NULL; } static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) { int ret; Loading Loading @@ -1913,21 +1911,6 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, pr_debug("%s: for CPU %u, event %u\n", __func__, policy->cpu, event); mutex_lock(&cpufreq_governor_lock); if ((policy->governor_enabled && event == CPUFREQ_GOV_START) || (!policy->governor_enabled && (event == CPUFREQ_GOV_LIMITS || event == CPUFREQ_GOV_STOP))) { mutex_unlock(&cpufreq_governor_lock); return -EBUSY; } if (event == CPUFREQ_GOV_STOP) policy->governor_enabled = false; else if (event == CPUFREQ_GOV_START) policy->governor_enabled = true; mutex_unlock(&cpufreq_governor_lock); ret = policy->governor->governor(policy, event); if (!ret) { Loading @@ -1935,14 +1918,6 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, policy->governor->initialized++; else if (event == CPUFREQ_GOV_POLICY_EXIT) policy->governor->initialized--; } else { /* Restore original values */ mutex_lock(&cpufreq_governor_lock); if (event == CPUFREQ_GOV_STOP) policy->governor_enabled = true; else if (event == CPUFREQ_GOV_START) policy->governor_enabled = false; mutex_unlock(&cpufreq_governor_lock); } if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) || Loading Loading @@ -2097,7 +2072,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, old_gov = policy->governor; /* end old governor */ if (old_gov) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); if (ret) { /* This can happen due to race with other operations */ pr_debug("%s: Failed to Stop Governor: %s (%d)\n", Loading @@ -2105,10 +2080,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, return ret; } up_write(&policy->rwsem); ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); down_write(&policy->rwsem); ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); if (ret) { pr_err("%s: Failed to Exit Governor: %s (%d)\n", __func__, old_gov->name, ret); Loading @@ -2118,32 +2090,30 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, /* start new governor */ policy->governor = new_policy->governor; ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); if (!ret) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_START); ret = cpufreq_governor(policy, CPUFREQ_GOV_START); if (!ret) goto out; up_write(&policy->rwsem); __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); down_write(&policy->rwsem); cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); } /* new governor failed, so re-start old one */ pr_debug("starting governor %s failed\n", policy->governor->name); if (old_gov) { policy->governor = old_gov; if (__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) if (cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) policy->governor = NULL; else __cpufreq_governor(policy, CPUFREQ_GOV_START); cpufreq_governor(policy, CPUFREQ_GOV_START); } return ret; out: pr_debug("governor: change or update limits\n"); return __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); return cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); } /** Loading Loading @@ -2210,11 +2180,7 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, break; case CPU_DOWN_PREPARE: cpufreq_offline_prepare(cpu); break; case CPU_POST_DEAD: cpufreq_offline_finish(cpu); cpufreq_offline(cpu); break; case CPU_DOWN_FAILED: Loading Loading @@ -2247,8 +2213,11 @@ static int cpufreq_boost_set_sw(int state) __func__); break; } down_write(&policy->rwsem); policy->user_policy.max = policy->max; __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); up_write(&policy->rwsem); } } Loading
drivers/cpufreq/cpufreq_conservative.c +124 −152 Original line number Diff line number Diff line Loading @@ -14,6 +14,22 @@ #include <linux/slab.h> #include "cpufreq_governor.h" struct cs_policy_dbs_info { struct policy_dbs_info policy_dbs; unsigned int down_skip; unsigned int requested_freq; }; static inline struct cs_policy_dbs_info *to_dbs_info(struct policy_dbs_info *policy_dbs) { return container_of(policy_dbs, struct cs_policy_dbs_info, policy_dbs); } struct cs_dbs_tuners { unsigned int down_threshold; unsigned int freq_step; }; /* Conservative governor macros */ #define DEF_FREQUENCY_UP_THRESHOLD (80) #define DEF_FREQUENCY_DOWN_THRESHOLD (20) Loading @@ -21,18 +37,6 @@ #define DEF_SAMPLING_DOWN_FACTOR (1) #define MAX_SAMPLING_DOWN_FACTOR (10) static DEFINE_PER_CPU(struct cs_cpu_dbs_info_s, cs_cpu_dbs_info); static int cs_cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event); static struct cpufreq_governor cpufreq_gov_conservative = { .name = "conservative", .governor = cs_cpufreq_governor_dbs, .max_transition_latency = TRANSITION_LATENCY_LIMIT, .owner = THIS_MODULE, }; static inline unsigned int get_freq_target(struct cs_dbs_tuners *cs_tuners, struct cpufreq_policy *policy) { Loading @@ -54,27 +58,28 @@ static inline unsigned int get_freq_target(struct cs_dbs_tuners *cs_tuners, * Any frequency increase takes it to the maximum frequency. Frequency reduction * happens at minimum steps of 5% (default) of maximum frequency */ static void cs_check_cpu(int cpu, unsigned int load) static unsigned int cs_dbs_timer(struct cpufreq_policy *policy) { struct cs_cpu_dbs_info_s *dbs_info = &per_cpu(cs_cpu_dbs_info, cpu); struct cpufreq_policy *policy = dbs_info->cdbs.shared->policy; struct dbs_data *dbs_data = policy->governor_data; struct policy_dbs_info *policy_dbs = policy->governor_data; struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs); struct dbs_data *dbs_data = policy_dbs->dbs_data; struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; unsigned int load = dbs_update(policy); /* * break out if we 'cannot' reduce the speed as the user might * want freq_step to be zero */ if (cs_tuners->freq_step == 0) return; goto out; /* Check for frequency increase */ if (load > cs_tuners->up_threshold) { if (load > dbs_data->up_threshold) { dbs_info->down_skip = 0; /* if we are already at full speed then break out early */ if (dbs_info->requested_freq == policy->max) return; goto out; dbs_info->requested_freq += get_freq_target(cs_tuners, policy); Loading @@ -83,12 +88,12 @@ static void cs_check_cpu(int cpu, unsigned int load) __cpufreq_driver_target(policy, dbs_info->requested_freq, CPUFREQ_RELATION_H); return; goto out; } /* if sampling_down_factor is active break out early */ if (++dbs_info->down_skip < cs_tuners->sampling_down_factor) return; if (++dbs_info->down_skip < dbs_data->sampling_down_factor) goto out; dbs_info->down_skip = 0; /* Check for frequency decrease */ Loading @@ -98,7 +103,7 @@ static void cs_check_cpu(int cpu, unsigned int load) * if we cannot reduce the frequency anymore, break out early */ if (policy->cur == policy->min) return; goto out; freq_target = get_freq_target(cs_tuners, policy); if (dbs_info->requested_freq > freq_target) Loading @@ -108,58 +113,25 @@ static void cs_check_cpu(int cpu, unsigned int load) __cpufreq_driver_target(policy, dbs_info->requested_freq, CPUFREQ_RELATION_L); return; } } static unsigned int cs_dbs_timer(struct cpufreq_policy *policy, bool modify_all) { struct dbs_data *dbs_data = policy->governor_data; struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; if (modify_all) dbs_check_cpu(dbs_data, policy->cpu); return delay_for_sampling_rate(cs_tuners->sampling_rate); out: return dbs_data->sampling_rate; } static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) { struct cpufreq_freqs *freq = data; struct cs_cpu_dbs_info_s *dbs_info = &per_cpu(cs_cpu_dbs_info, freq->cpu); struct cpufreq_policy *policy = cpufreq_cpu_get_raw(freq->cpu); if (!policy) return 0; /* policy isn't governed by conservative governor */ if (policy->governor != &cpufreq_gov_conservative) return 0; /* * we only care if our internally tracked freq moves outside the 'valid' * ranges of frequency available to us otherwise we do not change it */ if (dbs_info->requested_freq > policy->max || dbs_info->requested_freq < policy->min) dbs_info->requested_freq = freq->new; return 0; } void *data); static struct notifier_block cs_cpufreq_notifier_block = { .notifier_call = dbs_cpufreq_notifier, }; /************************** sysfs interface ************************/ static struct common_dbs_data cs_dbs_cdata; static struct dbs_governor cs_dbs_gov; static ssize_t store_sampling_down_factor(struct dbs_data *dbs_data, const char *buf, size_t count) { struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; unsigned int input; int ret; ret = sscanf(buf, "%u", &input); Loading @@ -167,22 +139,7 @@ static ssize_t store_sampling_down_factor(struct dbs_data *dbs_data, if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1) return -EINVAL; cs_tuners->sampling_down_factor = input; return count; } static ssize_t store_sampling_rate(struct dbs_data *dbs_data, const char *buf, size_t count) { struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; unsigned int input; int ret; ret = sscanf(buf, "%u", &input); if (ret != 1) return -EINVAL; cs_tuners->sampling_rate = max(input, dbs_data->min_sampling_rate); dbs_data->sampling_down_factor = input; return count; } Loading @@ -197,7 +154,7 @@ static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf, if (ret != 1 || input > 100 || input <= cs_tuners->down_threshold) return -EINVAL; cs_tuners->up_threshold = input; dbs_data->up_threshold = input; return count; } Loading @@ -211,7 +168,7 @@ static ssize_t store_down_threshold(struct dbs_data *dbs_data, const char *buf, /* cannot be lower than 11 otherwise freq will not fall */ if (ret != 1 || input < 11 || input > 100 || input >= cs_tuners->up_threshold) input >= dbs_data->up_threshold) return -EINVAL; cs_tuners->down_threshold = input; Loading @@ -221,8 +178,7 @@ static ssize_t store_down_threshold(struct dbs_data *dbs_data, const char *buf, static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data, const char *buf, size_t count) { struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; unsigned int input, j; unsigned int input; int ret; ret = sscanf(buf, "%u", &input); Loading @@ -232,21 +188,14 @@ static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data, if (input > 1) input = 1; if (input == cs_tuners->ignore_nice_load) /* nothing to do */ if (input == dbs_data->ignore_nice_load) /* nothing to do */ return count; cs_tuners->ignore_nice_load = input; dbs_data->ignore_nice_load = input; /* we need to re-evaluate prev_cpu_idle */ for_each_online_cpu(j) { struct cs_cpu_dbs_info_s *dbs_info; dbs_info = &per_cpu(cs_cpu_dbs_info, j); dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j, &dbs_info->cdbs.prev_cpu_wall, 0); if (cs_tuners->ignore_nice_load) dbs_info->cdbs.prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE]; } gov_update_cpu_data(dbs_data); return count; } Loading @@ -272,55 +221,47 @@ static ssize_t store_freq_step(struct dbs_data *dbs_data, const char *buf, return count; } show_store_one(cs, sampling_rate); show_store_one(cs, sampling_down_factor); show_store_one(cs, up_threshold); show_store_one(cs, down_threshold); show_store_one(cs, ignore_nice_load); show_store_one(cs, freq_step); declare_show_sampling_rate_min(cs); gov_sys_pol_attr_rw(sampling_rate); gov_sys_pol_attr_rw(sampling_down_factor); gov_sys_pol_attr_rw(up_threshold); gov_sys_pol_attr_rw(down_threshold); gov_sys_pol_attr_rw(ignore_nice_load); gov_sys_pol_attr_rw(freq_step); gov_sys_pol_attr_ro(sampling_rate_min); static struct attribute *dbs_attributes_gov_sys[] = { &sampling_rate_min_gov_sys.attr, &sampling_rate_gov_sys.attr, &sampling_down_factor_gov_sys.attr, &up_threshold_gov_sys.attr, &down_threshold_gov_sys.attr, &ignore_nice_load_gov_sys.attr, &freq_step_gov_sys.attr, gov_show_one_common(sampling_rate); gov_show_one_common(sampling_down_factor); gov_show_one_common(up_threshold); gov_show_one_common(ignore_nice_load); gov_show_one_common(min_sampling_rate); gov_show_one(cs, down_threshold); gov_show_one(cs, freq_step); gov_attr_rw(sampling_rate); gov_attr_rw(sampling_down_factor); gov_attr_rw(up_threshold); gov_attr_rw(ignore_nice_load); gov_attr_ro(min_sampling_rate); gov_attr_rw(down_threshold); gov_attr_rw(freq_step); static struct attribute *cs_attributes[] = { &min_sampling_rate.attr, &sampling_rate.attr, &sampling_down_factor.attr, &up_threshold.attr, &down_threshold.attr, &ignore_nice_load.attr, &freq_step.attr, NULL }; static struct attribute_group cs_attr_group_gov_sys = { .attrs = dbs_attributes_gov_sys, .name = "conservative", }; /************************** sysfs end ************************/ static struct attribute *dbs_attributes_gov_pol[] = { &sampling_rate_min_gov_pol.attr, &sampling_rate_gov_pol.attr, &sampling_down_factor_gov_pol.attr, &up_threshold_gov_pol.attr, &down_threshold_gov_pol.attr, &ignore_nice_load_gov_pol.attr, &freq_step_gov_pol.attr, NULL }; static struct policy_dbs_info *cs_alloc(void) { struct cs_policy_dbs_info *dbs_info; static struct attribute_group cs_attr_group_gov_pol = { .attrs = dbs_attributes_gov_pol, .name = "conservative", }; dbs_info = kzalloc(sizeof(*dbs_info), GFP_KERNEL); return dbs_info ? &dbs_info->policy_dbs : NULL; } /************************** sysfs end ************************/ static void cs_free(struct policy_dbs_info *policy_dbs) { kfree(to_dbs_info(policy_dbs)); } static int cs_init(struct dbs_data *dbs_data, bool notify) { Loading @@ -332,11 +273,11 @@ static int cs_init(struct dbs_data *dbs_data, bool notify) return -ENOMEM; } tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD; tuners->down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD; tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR; tuners->ignore_nice_load = 0; tuners->freq_step = DEF_FREQUENCY_STEP; dbs_data->up_threshold = DEF_FREQUENCY_UP_THRESHOLD; dbs_data->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR; dbs_data->ignore_nice_load = 0; dbs_data->tuners = tuners; dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * Loading @@ -358,35 +299,66 @@ static void cs_exit(struct dbs_data *dbs_data, bool notify) kfree(dbs_data->tuners); } define_get_cpu_dbs_routines(cs_cpu_dbs_info); static void cs_start(struct cpufreq_policy *policy) { struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy->governor_data); dbs_info->down_skip = 0; dbs_info->requested_freq = policy->cur; } static struct common_dbs_data cs_dbs_cdata = { .governor = GOV_CONSERVATIVE, .attr_group_gov_sys = &cs_attr_group_gov_sys, .attr_group_gov_pol = &cs_attr_group_gov_pol, .get_cpu_cdbs = get_cpu_cdbs, .get_cpu_dbs_info_s = get_cpu_dbs_info_s, static struct dbs_governor cs_dbs_gov = { .gov = { .name = "conservative", .governor = cpufreq_governor_dbs, .max_transition_latency = TRANSITION_LATENCY_LIMIT, .owner = THIS_MODULE, }, .kobj_type = { .default_attrs = cs_attributes }, .gov_dbs_timer = cs_dbs_timer, .gov_check_cpu = cs_check_cpu, .alloc = cs_alloc, .free = cs_free, .init = cs_init, .exit = cs_exit, .mutex = __MUTEX_INITIALIZER(cs_dbs_cdata.mutex), .start = cs_start, }; static int cs_cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event) #define CPU_FREQ_GOV_CONSERVATIVE (&cs_dbs_gov.gov) static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) { return cpufreq_governor_dbs(policy, &cs_dbs_cdata, event); struct cpufreq_freqs *freq = data; struct cpufreq_policy *policy = cpufreq_cpu_get_raw(freq->cpu); struct cs_policy_dbs_info *dbs_info; if (!policy) return 0; /* policy isn't governed by conservative governor */ if (policy->governor != CPU_FREQ_GOV_CONSERVATIVE) return 0; dbs_info = to_dbs_info(policy->governor_data); /* * we only care if our internally tracked freq moves outside the 'valid' * ranges of frequency available to us otherwise we do not change it */ if (dbs_info->requested_freq > policy->max || dbs_info->requested_freq < policy->min) dbs_info->requested_freq = freq->new; return 0; } static int __init cpufreq_gov_dbs_init(void) { return cpufreq_register_governor(&cpufreq_gov_conservative); return cpufreq_register_governor(CPU_FREQ_GOV_CONSERVATIVE); } static void __exit cpufreq_gov_dbs_exit(void) { cpufreq_unregister_governor(&cpufreq_gov_conservative); cpufreq_unregister_governor(CPU_FREQ_GOV_CONSERVATIVE); } MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>"); Loading @@ -398,7 +370,7 @@ MODULE_LICENSE("GPL"); #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE struct cpufreq_governor *cpufreq_default_governor(void) { return &cpufreq_gov_conservative; return CPU_FREQ_GOV_CONSERVATIVE; } fs_initcall(cpufreq_gov_dbs_init); Loading
drivers/cpufreq/cpufreq_governor.c +403 −363 File changed.Preview size limit exceeded, changes collapsed. Show changes