Message ID | 20190625113244.18146-2-daniel.lezcano@linaro.org |
---|---|
State | New |
Headers | show |
Series | [V3,1/3] cpufreq: Move the IS_ENABLED(CPU_THERMAL) macro in a stub | expand |
On 26/06/2019 11:06, Rafael J. Wysocki wrote: > On Wed, Jun 26, 2019 at 8:37 AM Viresh Kumar <viresh.kumar@linaro.org> wrote: >> >> On 26-06-19, 08:02, Daniel Lezcano wrote: >>> On 26/06/2019 04:58, Viresh Kumar wrote: >>>> On 25-06-19, 13:32, Daniel Lezcano wrote: >>>>> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c >>>>> index aee024e42618..f07454249fbc 100644 >>>>> --- a/drivers/cpufreq/cpufreq.c >>>>> +++ b/drivers/cpufreq/cpufreq.c >>>>> @@ -1379,8 +1379,8 @@ static int cpufreq_online(unsigned int cpu) >>>>> cpufreq_driver->ready(policy); >>>>> >>>>> if (cpufreq_thermal_control_enabled(cpufreq_driver)) >>>>> - policy->cdev = of_cpufreq_cooling_register(policy); >>>>> - >>>>> + of_cpufreq_cooling_register(policy); >>>>> + >>>> >>>> We don't need any error checking here anymore ? >>> >>> There was no error checking initially. This comment and the others below >>> are for an additional patch IMO, not a change in this one. >> >> right, but ... >> >>>>> -void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) >>>>> +void cpufreq_cooling_unregister(struct cpufreq_policy *policy) >>>>> { >>>>> struct cpufreq_cooling_device *cpufreq_cdev; >>>>> bool last; >>>>> >>>>> - if (!cdev) >>>>> - return; >> >> we used to return without any errors from here. Now we will have >> problems if regsitering fails for some reason. > > Specifically, the last cpufreq_cdev in the list will be unregistered > AFAICS, and without removing it from the list for that matter, which > isn't what the caller wants. Indeed, What about the resulting code above: void __cpufreq_cooling_unregister(struct cpufreq_cooling_device *cpufreq_cdev, int last) { /* Unregister the notifier for the last cpufreq cooling device */ if (last) cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); thermal_cooling_device_unregister(cpufreq_cdev->cdev); ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id); kfree(cpufreq_cdev->idle_time); kfree(cpufreq_cdev); } /** * cpufreq_cooling_unregister - function to remove cpufreq cooling device. * @cdev: thermal cooling device pointer. * * This interface function unregisters the "thermal-cpufreq-%x" cooling device. */ void cpufreq_cooling_unregister(struct cpufreq_policy *policy) { struct cpufreq_cooling_device *cpufreq_cdev; bool last; mutex_lock(&cooling_list_lock); list_for_each_entry(cpufreq_cdev, &cpufreq_cdev_list, node) { if (cpufreq_cdev->policy == policy) { list_del(&cpufreq_cdev->node); last = list_empty(&cpufreq_cdev_list); break; } } mutex_unlock(&cooling_list_lock); if (cpufreq_cdev->policy == policy) __cpufreq_cooling_unregister(cpufreq_cdev, last); } EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister); -- <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook | <http://twitter.com/#!/linaroorg> Twitter | <http://www.linaro.org/linaro-blog/> Blog
On Wed, Jun 26, 2019 at 12:19 PM Daniel Lezcano <daniel.lezcano@linaro.org> wrote: > > On 26/06/2019 11:06, Rafael J. Wysocki wrote: > > On Wed, Jun 26, 2019 at 8:37 AM Viresh Kumar <viresh.kumar@linaro.org> wrote: > >> > >> On 26-06-19, 08:02, Daniel Lezcano wrote: > >>> On 26/06/2019 04:58, Viresh Kumar wrote: > >>>> On 25-06-19, 13:32, Daniel Lezcano wrote: > >>>>> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c > >>>>> index aee024e42618..f07454249fbc 100644 > >>>>> --- a/drivers/cpufreq/cpufreq.c > >>>>> +++ b/drivers/cpufreq/cpufreq.c > >>>>> @@ -1379,8 +1379,8 @@ static int cpufreq_online(unsigned int cpu) > >>>>> cpufreq_driver->ready(policy); > >>>>> > >>>>> if (cpufreq_thermal_control_enabled(cpufreq_driver)) > >>>>> - policy->cdev = of_cpufreq_cooling_register(policy); > >>>>> - > >>>>> + of_cpufreq_cooling_register(policy); > >>>>> + > >>>> > >>>> We don't need any error checking here anymore ? > >>> > >>> There was no error checking initially. This comment and the others below > >>> are for an additional patch IMO, not a change in this one. > >> > >> right, but ... > >> > >>>>> -void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) > >>>>> +void cpufreq_cooling_unregister(struct cpufreq_policy *policy) > >>>>> { > >>>>> struct cpufreq_cooling_device *cpufreq_cdev; > >>>>> bool last; > >>>>> > >>>>> - if (!cdev) > >>>>> - return; > >> > >> we used to return without any errors from here. Now we will have > >> problems if regsitering fails for some reason. > > > > Specifically, the last cpufreq_cdev in the list will be unregistered > > AFAICS, and without removing it from the list for that matter, which > > isn't what the caller wants. > > Indeed, > > What about the resulting code above: > > void __cpufreq_cooling_unregister(struct cpufreq_cooling_device > *cpufreq_cdev, int last) > { > /* Unregister the notifier for the last cpufreq cooling device */ > if (last) > cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, > CPUFREQ_POLICY_NOTIFIER); > Doesn't the notifier need to be unregistered under cooling_list_lock ? > thermal_cooling_device_unregister(cpufreq_cdev->cdev); > ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id); > kfree(cpufreq_cdev->idle_time); > kfree(cpufreq_cdev); > } > > /** > > * cpufreq_cooling_unregister - function to remove cpufreq cooling > device. > * @cdev: thermal cooling device pointer. > > * > > * This interface function unregisters the "thermal-cpufreq-%x" cooling > device. > */ > void cpufreq_cooling_unregister(struct cpufreq_policy *policy) > { > struct cpufreq_cooling_device *cpufreq_cdev; > bool last; > > mutex_lock(&cooling_list_lock); > list_for_each_entry(cpufreq_cdev, &cpufreq_cdev_list, node) { > if (cpufreq_cdev->policy == policy) { > list_del(&cpufreq_cdev->node); > last = list_empty(&cpufreq_cdev_list); > break; > } > } > mutex_unlock(&cooling_list_lock); > > if (cpufreq_cdev->policy == policy) > __cpufreq_cooling_unregister(cpufreq_cdev, last); > } > EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister); > > > > > -- > <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs > > Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook | > <http://twitter.com/#!/linaroorg> Twitter | > <http://www.linaro.org/linaro-blog/> Blog >
On 26/06/2019 13:28, Rafael J. Wysocki wrote: > On Wed, Jun 26, 2019 at 12:19 PM Daniel Lezcano > <daniel.lezcano@linaro.org> wrote: >> >> On 26/06/2019 11:06, Rafael J. Wysocki wrote: >>> On Wed, Jun 26, 2019 at 8:37 AM Viresh Kumar <viresh.kumar@linaro.org> wrote: >>>> >>>> On 26-06-19, 08:02, Daniel Lezcano wrote: >>>>> On 26/06/2019 04:58, Viresh Kumar wrote: >>>>>> On 25-06-19, 13:32, Daniel Lezcano wrote: >>>>>>> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c >>>>>>> index aee024e42618..f07454249fbc 100644 >>>>>>> --- a/drivers/cpufreq/cpufreq.c >>>>>>> +++ b/drivers/cpufreq/cpufreq.c >>>>>>> @@ -1379,8 +1379,8 @@ static int cpufreq_online(unsigned int cpu) >>>>>>> cpufreq_driver->ready(policy); >>>>>>> >>>>>>> if (cpufreq_thermal_control_enabled(cpufreq_driver)) >>>>>>> - policy->cdev = of_cpufreq_cooling_register(policy); >>>>>>> - >>>>>>> + of_cpufreq_cooling_register(policy); >>>>>>> + >>>>>> >>>>>> We don't need any error checking here anymore ? >>>>> >>>>> There was no error checking initially. This comment and the others below >>>>> are for an additional patch IMO, not a change in this one. >>>> >>>> right, but ... >>>> >>>>>>> -void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) >>>>>>> +void cpufreq_cooling_unregister(struct cpufreq_policy *policy) >>>>>>> { >>>>>>> struct cpufreq_cooling_device *cpufreq_cdev; >>>>>>> bool last; >>>>>>> >>>>>>> - if (!cdev) >>>>>>> - return; >>>> >>>> we used to return without any errors from here. Now we will have >>>> problems if regsitering fails for some reason. >>> >>> Specifically, the last cpufreq_cdev in the list will be unregistered >>> AFAICS, and without removing it from the list for that matter, which >>> isn't what the caller wants. >> >> Indeed, >> >> What about the resulting code above: >> >> void __cpufreq_cooling_unregister(struct cpufreq_cooling_device >> *cpufreq_cdev, int last) >> { >> /* Unregister the notifier for the last cpufreq cooling device */ >> if (last) >> cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, >> CPUFREQ_POLICY_NOTIFIER); >> > > Doesn't the notifier need to be unregistered under cooling_list_lock ? I don't think so because the element is no longer in the list and we don't touch the list anymore. Do you see another possible race? >> thermal_cooling_device_unregister(cpufreq_cdev->cdev); >> ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id); >> kfree(cpufreq_cdev->idle_time); >> kfree(cpufreq_cdev); >> } >> >> /** >> >> * cpufreq_cooling_unregister - function to remove cpufreq cooling >> device. >> * @cdev: thermal cooling device pointer. >> >> * >> >> * This interface function unregisters the "thermal-cpufreq-%x" cooling >> device. >> */ >> void cpufreq_cooling_unregister(struct cpufreq_policy *policy) >> { >> struct cpufreq_cooling_device *cpufreq_cdev; >> bool last; >> >> mutex_lock(&cooling_list_lock); >> list_for_each_entry(cpufreq_cdev, &cpufreq_cdev_list, node) { >> if (cpufreq_cdev->policy == policy) { >> list_del(&cpufreq_cdev->node); >> last = list_empty(&cpufreq_cdev_list); >> break; >> } >> } >> mutex_unlock(&cooling_list_lock); >> >> if (cpufreq_cdev->policy == policy) >> __cpufreq_cooling_unregister(cpufreq_cdev, last); >> } >> EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister); >> >> >> >> >> -- >> <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs >> >> Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook | >> <http://twitter.com/#!/linaroorg> Twitter | >> <http://www.linaro.org/linaro-blog/> Blog >> -- <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook | <http://twitter.com/#!/linaroorg> Twitter | <http://www.linaro.org/linaro-blog/> Blog
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index 7fe52fcddcf1..718c63231e66 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -56,7 +56,6 @@ static bool bL_switching_enabled; #define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : freq) #define VIRT_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq >> 1 : freq) -static struct thermal_cooling_device *cdev[MAX_CLUSTERS]; static const struct cpufreq_arm_bL_ops *arm_bL_ops; static struct clk *clk[MAX_CLUSTERS]; static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1]; @@ -501,10 +500,8 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy) struct device *cpu_dev; int cur_cluster = cpu_to_cluster(policy->cpu); - if (cur_cluster < MAX_CLUSTERS) { - cpufreq_cooling_unregister(cdev[cur_cluster]); - cdev[cur_cluster] = NULL; - } + if (cur_cluster < MAX_CLUSTERS) + cpufreq_cooling_unregister(policy); cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) { @@ -527,7 +524,7 @@ static void bL_cpufreq_ready(struct cpufreq_policy *policy) if (cur_cluster >= MAX_CLUSTERS) return; - cdev[cur_cluster] = of_cpufreq_cooling_register(policy); + of_cpufreq_cooling_register(policy); } static struct cpufreq_driver bL_cpufreq_driver = { diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index aee024e42618..f07454249fbc 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1379,8 +1379,8 @@ static int cpufreq_online(unsigned int cpu) cpufreq_driver->ready(policy); if (cpufreq_thermal_control_enabled(cpufreq_driver)) - policy->cdev = of_cpufreq_cooling_register(policy); - + of_cpufreq_cooling_register(policy); + pr_debug("initialization complete\n"); return 0; @@ -1468,10 +1468,8 @@ static int cpufreq_offline(unsigned int cpu) goto unlock; } - if (cpufreq_thermal_control_enabled(cpufreq_driver)) { - cpufreq_cooling_unregister(policy->cdev); - policy->cdev = NULL; - } + if (cpufreq_thermal_control_enabled(cpufreq_driver)) + cpufreq_cooling_unregister(policy); if (cpufreq_driver->stop_cpu) cpufreq_driver->stop_cpu(policy); diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 83486775e593..007c7c6bf845 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -78,6 +78,7 @@ struct cpufreq_cooling_device { struct cpufreq_policy *policy; struct list_head node; struct time_in_idle *idle_time; + struct thermal_cooling_device *cdev; }; static DEFINE_IDA(cpufreq_ida); @@ -606,6 +607,7 @@ __cpufreq_cooling_register(struct device_node *np, goto remove_ida; cpufreq_cdev->clipped_freq = get_state_freq(cpufreq_cdev, 0); + cpufreq_cdev->cdev = cdev; mutex_lock(&cooling_list_lock); /* Register the notifier for first cpufreq cooling device */ @@ -699,18 +701,18 @@ EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register); * * This interface function unregisters the "thermal-cpufreq-%x" cooling device. */ -void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) +void cpufreq_cooling_unregister(struct cpufreq_policy *policy) { struct cpufreq_cooling_device *cpufreq_cdev; bool last; - if (!cdev) - return; - - cpufreq_cdev = cdev->devdata; - mutex_lock(&cooling_list_lock); - list_del(&cpufreq_cdev->node); + list_for_each_entry(cpufreq_cdev, &cpufreq_cdev_list, node) { + if (cpufreq_cdev->policy == policy) { + list_del(&cpufreq_cdev->node); + break; + } + } /* Unregister the notifier for the last cpufreq cooling device */ last = list_empty(&cpufreq_cdev_list); mutex_unlock(&cooling_list_lock); @@ -719,7 +721,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); - thermal_cooling_device_unregister(cdev); + thermal_cooling_device_unregister(cpufreq_cdev->cdev); ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id); kfree(cpufreq_cdev->idle_time); kfree(cpufreq_cdev); diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index bb6754a5342c..021c0948b740 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -203,7 +203,6 @@ static struct thermal_soc_data thermal_imx7d_data = { struct imx_thermal_data { struct cpufreq_policy *policy; struct thermal_zone_device *tz; - struct thermal_cooling_device *cdev; enum thermal_device_mode mode; struct regmap *tempmon; u32 c1, c2; /* See formula in imx_init_calib() */ @@ -656,6 +655,7 @@ MODULE_DEVICE_TABLE(of, of_imx_thermal_match); static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) { struct device_node *np; + struct thermal_cooling_device *cdev; int ret; data->policy = cpufreq_cpu_get(0); @@ -667,9 +667,9 @@ static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) np = of_get_cpu_node(data->policy->cpu, NULL); if (!np || !of_find_property(np, "#cooling-cells", NULL)) { - data->cdev = cpufreq_cooling_register(data->policy); - if (IS_ERR(data->cdev)) { - ret = PTR_ERR(data->cdev); + cdev = cpufreq_cooling_register(data->policy); + if (IS_ERR(cdev)) { + ret = PTR_ERR(cdev); cpufreq_cpu_put(data->policy); return ret; } @@ -680,7 +680,7 @@ static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) static void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data) { - cpufreq_cooling_unregister(data->cdev); + cpufreq_cooling_unregister(data->policy); cpufreq_cpu_put(data->policy); } @@ -872,7 +872,7 @@ static int imx_thermal_remove(struct platform_device *pdev) clk_disable_unprepare(data->thermal_clk); thermal_zone_device_unregister(data->tz); - cpufreq_cooling_unregister(data->cdev); + cpufreq_cooling_unregister(data->policy); cpufreq_cpu_put(data->policy); return 0; diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c index b4f981daeaf2..170b70b6ec61 100644 --- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c @@ -41,7 +41,6 @@ struct ti_thermal_data { struct cpufreq_policy *policy; struct thermal_zone_device *ti_thermal; struct thermal_zone_device *pcb_tz; - struct thermal_cooling_device *cool_dev; struct ti_bandgap *bgp; enum thermal_device_mode mode; struct work_struct thermal_wq; @@ -233,6 +232,7 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id) { struct ti_thermal_data *data; struct device_node *np = bgp->dev->of_node; + struct thermal_cooling_device *cdev; /* * We are assuming here that if one deploys the zone @@ -256,9 +256,9 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id) } /* Register cooling device */ - data->cool_dev = cpufreq_cooling_register(data->policy); - if (IS_ERR(data->cool_dev)) { - int ret = PTR_ERR(data->cool_dev); + cdev = cpufreq_cooling_register(data->policy); + if (IS_ERR(cdev)) { + int ret = PTR_ERR(cdev); dev_err(bgp->dev, "Failed to register cpu cooling device %d\n", ret); cpufreq_cpu_put(data->policy); @@ -277,7 +277,7 @@ int ti_thermal_unregister_cpu_cooling(struct ti_bandgap *bgp, int id) data = ti_bandgap_get_sensor_data(bgp, id); if (data) { - cpufreq_cooling_unregister(data->cool_dev); + cpufreq_cooling_unregister(data->policy); if (data->policy) cpufreq_cpu_put(data->policy); } diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index bae54bb7c048..89f469ee4be4 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -29,9 +29,9 @@ cpufreq_cooling_register(struct cpufreq_policy *policy); /** * cpufreq_cooling_unregister - function to remove cpufreq cooling device. - * @cdev: thermal cooling device pointer. + * @policy: cpufreq policy */ -void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev); +void cpufreq_cooling_unregister(struct cpufreq_policy *policy); #else /* !CONFIG_CPU_THERMAL */ static inline struct thermal_cooling_device * @@ -41,7 +41,7 @@ cpufreq_cooling_register(struct cpufreq_policy *policy) } static inline -void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) +void cpufreq_cooling_unregister(struct cpufreq_policy *policy) { return; } diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index a1467aa7f58b..ce13204df972 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -144,9 +144,6 @@ struct cpufreq_policy { /* For cpufreq driver's internal use */ void *driver_data; - - /* Pointer to the cooling device if used for thermal mitigation */ - struct thermal_cooling_device *cdev; }; struct cpufreq_freqs {