Skip to content

Commit

Permalink
OPP: Don't try to remove all OPP tables on failure
Browse files Browse the repository at this point in the history
dev_pm_opp_of_cpumask_add_table() creates the OPP table for all CPUs
present in the cpumask and on errors it should revert all changes it has
done.

It actually is doing a bit more than that. On errors, it tries to free
all the OPP tables, even the one it hasn't created yet. This may also
end up freeing the OPP tables which were created from separate path,
like dev_pm_opp_set_supported_hw().

Reported-and-tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
  • Loading branch information
Viresh Kumar committed Sep 19, 2018
1 parent 2fbb867 commit 404b136
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 5 deletions.
8 changes: 6 additions & 2 deletions drivers/opp/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,18 @@ void dev_pm_opp_free_cpufreq_table(struct device *dev,
EXPORT_SYMBOL_GPL(dev_pm_opp_free_cpufreq_table);
#endif /* CONFIG_CPU_FREQ */

void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of)
void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of,
int last_cpu)
{
struct device *cpu_dev;
int cpu;

WARN_ON(cpumask_empty(cpumask));

for_each_cpu(cpu, cpumask) {
if (cpu == last_cpu)
break;

cpu_dev = get_cpu_device(cpu);
if (!cpu_dev) {
pr_err("%s: failed to get cpu%d device\n", __func__,
Expand All @@ -140,7 +144,7 @@ void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of)
*/
void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask)
{
_dev_pm_opp_cpumask_remove_table(cpumask, false);
_dev_pm_opp_cpumask_remove_table(cpumask, false, -1);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_cpumask_remove_table);

Expand Down
4 changes: 2 additions & 2 deletions drivers/opp/of.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_indexed);
*/
void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask)
{
_dev_pm_opp_cpumask_remove_table(cpumask, true);
_dev_pm_opp_cpumask_remove_table(cpumask, true, -1);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_remove_table);

Expand Down Expand Up @@ -627,7 +627,7 @@ int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask)
__func__, cpu, ret);

/* Free all other OPPs */
dev_pm_opp_of_cpumask_remove_table(cpumask);
_dev_pm_opp_cpumask_remove_table(cpumask, true, cpu);
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/opp/opp.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table);
void _opp_free(struct dev_pm_opp *opp);
int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_table *opp_table, bool rate_not_available);
int _opp_add_v1(struct opp_table *opp_table, struct device *dev, unsigned long freq, long u_volt, bool dynamic);
void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of);
void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of, int last_cpu);
struct opp_table *_add_opp_table(struct device *dev);

#ifdef CONFIG_OF
Expand Down

0 comments on commit 404b136

Please sign in to comment.