cpufreq: Remove cpufreq_frequency_get_table()
authorViresh Kumar <viresh.kumar@linaro.org>
Fri, 3 Jun 2016 05:28:47 +0000 (10:58 +0530)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 8 Jun 2016 22:58:05 +0000 (00:58 +0200)
Most of the callers of cpufreq_frequency_get_table() already have the
pointer to a valid 'policy' structure and they don't really need to go
through the per-cpu variable first and then a check to validate the
frequency, in order to find the freq-table for the policy.

Directly use the policy->freq_table field instead for them.

Only one user of that API is left after above changes, cpu_cooling.c and
it accesses the freq_table in a racy way as the policy can get freed in
between.

Fix it by using cpufreq_cpu_get() properly.

Since there are no more users of cpufreq_frequency_get_table() left, get
rid of it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Javi Merino <javi.merino@arm.com> (cpu_cooling.c)
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_stats.c
drivers/cpufreq/freq_table.c
drivers/cpufreq/ppc_cbe_cpufreq_pmi.c
drivers/thermal/cpu_cooling.c
include/linux/cpufreq.h

index c6a14ba..cc252ee 100644 (file)
@@ -126,15 +126,6 @@ struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)
 }
 EXPORT_SYMBOL_GPL(get_governor_parent_kobj);
 
-struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
-{
-       struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
-
-       return policy && !policy_is_inactive(policy) ?
-               policy->freq_table : NULL;
-}
-EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
-
 static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
 {
        u64 idle_time;
@@ -1950,7 +1941,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
        if (!cpufreq_driver->target_index)
                return -EINVAL;
 
-       freq_table = cpufreq_frequency_get_table(policy->cpu);
+       freq_table = policy->freq_table;
        if (unlikely(!freq_table)) {
                pr_err("%s: Unable to find freq_table\n", __func__);
                return -EINVAL;
@@ -2345,26 +2336,25 @@ static struct notifier_block __refdata cpufreq_cpu_notifier = {
  *********************************************************************/
 static int cpufreq_boost_set_sw(int state)
 {
-       struct cpufreq_frequency_table *freq_table;
        struct cpufreq_policy *policy;
        int ret = -EINVAL;
 
        for_each_active_policy(policy) {
-               freq_table = cpufreq_frequency_get_table(policy->cpu);
-               if (freq_table) {
-                       ret = cpufreq_frequency_table_cpuinfo(policy,
-                                                       freq_table);
-                       if (ret) {
-                               pr_err("%s: Policy frequency update failed\n",
-                                      __func__);
-                               break;
-                       }
+               if (!policy->freq_table)
+                       continue;
 
-                       down_write(&policy->rwsem);
-                       policy->user_policy.max = policy->max;
-                       cpufreq_governor_limits(policy);
-                       up_write(&policy->rwsem);
+               ret = cpufreq_frequency_table_cpuinfo(policy,
+                                                     policy->freq_table);
+               if (ret) {
+                       pr_err("%s: Policy frequency update failed\n",
+                              __func__);
+                       break;
                }
+
+               down_write(&policy->rwsem);
+               policy->user_policy.max = policy->max;
+               cpufreq_governor_limits(policy);
+               up_write(&policy->rwsem);
        }
 
        return ret;
index c84fc22..4d2fe27 100644 (file)
@@ -113,7 +113,7 @@ static void ondemand_powersave_bias_init(struct cpufreq_policy *policy)
 {
        struct od_policy_dbs_info *dbs_info = to_dbs_info(policy->governor_data);
 
-       dbs_info->freq_table = cpufreq_frequency_get_table(policy->cpu);
+       dbs_info->freq_table = policy->freq_table;
        dbs_info->freq_lo = 0;
 }
 
index c6e7f81..06d3abd 100644 (file)
@@ -157,11 +157,10 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
        unsigned int i = 0, count = 0, ret = -ENOMEM;
        struct cpufreq_stats *stats;
        unsigned int alloc_size;
-       unsigned int cpu = policy->cpu;
        struct cpufreq_frequency_table *pos, *table;
 
        /* We need cpufreq table for creating stats table */
-       table = cpufreq_frequency_get_table(cpu);
+       table = policy->freq_table;
        if (unlikely(!table))
                return;
 
index 4e5c5db..f52b547 100644 (file)
@@ -106,12 +106,10 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify);
  */
 int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy)
 {
-       struct cpufreq_frequency_table *table =
-               cpufreq_frequency_get_table(policy->cpu);
-       if (!table)
+       if (!policy->freq_table)
                return -ENODEV;
 
-       return cpufreq_frequency_table_verify(policy, table);
+       return cpufreq_frequency_table_verify(policy, policy->freq_table);
 }
 EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify);
 
@@ -210,9 +208,8 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
 int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,
                unsigned int freq)
 {
-       struct cpufreq_frequency_table *pos, *table;
+       struct cpufreq_frequency_table *pos, *table = policy->freq_table;
 
-       table = cpufreq_frequency_get_table(policy->cpu);
        if (unlikely(!table)) {
                pr_debug("%s: Unable to find frequency table\n", __func__);
                return -ENOENT;
index 7c4cd5c..dc11248 100644 (file)
@@ -94,7 +94,7 @@ static int pmi_notifier(struct notifier_block *nb,
                                       unsigned long event, void *data)
 {
        struct cpufreq_policy *policy = data;
-       struct cpufreq_frequency_table *cbe_freqs;
+       struct cpufreq_frequency_table *cbe_freqs = policy->freq_table;
        u8 node;
 
        /* Should this really be called for CPUFREQ_ADJUST and CPUFREQ_NOTIFY
@@ -103,7 +103,6 @@ static int pmi_notifier(struct notifier_block *nb,
        if (event == CPUFREQ_START)
                return 0;
 
-       cbe_freqs = cpufreq_frequency_get_table(policy->cpu);
        node = cbe_cpu_to_node(policy->cpu);
 
        pr_debug("got notified, event=%lu, node=%u\n", event, node);
index 6ceac4f..4d678cf 100644 (file)
@@ -787,22 +787,34 @@ __cpufreq_cooling_register(struct device_node *np,
                        const struct cpumask *clip_cpus, u32 capacitance,
                        get_static_t plat_static_func)
 {
+       struct cpufreq_policy *policy;
        struct thermal_cooling_device *cool_dev;
        struct cpufreq_cooling_device *cpufreq_dev;
        char dev_name[THERMAL_NAME_LENGTH];
        struct cpufreq_frequency_table *pos, *table;
+       struct cpumask temp_mask;
        unsigned int freq, i, num_cpus;
        int ret;
 
-       table = cpufreq_frequency_get_table(cpumask_first(clip_cpus));
+       cpumask_and(&temp_mask, clip_cpus, cpu_online_mask);
+       policy = cpufreq_cpu_get(cpumask_first(&temp_mask));
+       if (!policy) {
+               pr_debug("%s: CPUFreq policy not found\n", __func__);
+               return ERR_PTR(-EPROBE_DEFER);
+       }
+
+       table = policy->freq_table;
        if (!table) {
                pr_debug("%s: CPUFreq table not found\n", __func__);
-               return ERR_PTR(-EPROBE_DEFER);
+               cool_dev = ERR_PTR(-ENODEV);
+               goto put_policy;
        }
 
        cpufreq_dev = kzalloc(sizeof(*cpufreq_dev), GFP_KERNEL);
-       if (!cpufreq_dev)
-               return ERR_PTR(-ENOMEM);
+       if (!cpufreq_dev) {
+               cool_dev = ERR_PTR(-ENOMEM);
+               goto put_policy;
+       }
 
        num_cpus = cpumask_weight(clip_cpus);
        cpufreq_dev->time_in_idle = kcalloc(num_cpus,
@@ -892,7 +904,7 @@ __cpufreq_cooling_register(struct device_node *np,
                                          CPUFREQ_POLICY_NOTIFIER);
        mutex_unlock(&cooling_cpufreq_lock);
 
-       return cool_dev;
+       goto put_policy;
 
 remove_idr:
        release_idr(&cpufreq_idr, cpufreq_dev->id);
@@ -906,6 +918,8 @@ free_time_in_idle:
        kfree(cpufreq_dev->time_in_idle);
 free_cdev:
        kfree(cpufreq_dev);
+put_policy:
+       cpufreq_cpu_put(policy);
 
        return cool_dev;
 }
index 7ed93c3..1342cbc 100644 (file)
@@ -632,8 +632,6 @@ static inline bool policy_has_boost_freq(struct cpufreq_policy *policy)
        return false;
 }
 #endif
-/* the following funtion is for cpufreq core use only */
-struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
 
 /* the following are really really optional */
 extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;