[PATCH 10/31] devfreq: exynos: Migrate to dev_pm_opp_set_config()
Chanwoo Choi
cw00.choi at samsung.com
Mon May 30 22:05:43 PDT 2022
On 5/31/22 1:38 PM, Viresh Kumar wrote:
> On 31-05-22, 09:45, Viresh Kumar wrote:
>> On 31-05-22, 13:12, Chanwoo Choi wrote:
>>> I try to find the cause of this warning.
>>> I think that dev_pm_opp_clear_config needs to check
>>> whether 'opp_table' is NULL or not as following:
>>>
>>>
>>> diff --git a/drivers/opp/core.c b/drivers/opp/core.c
>>> index fba6e2b20b8f..cbf8f10b9ff0 100644
>>> --- a/drivers/opp/core.c
>>> +++ b/drivers/opp/core.c
>>> @@ -2598,6 +2598,9 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_set_config);
>>> */
>>> void dev_pm_opp_clear_config(struct opp_table *opp_table)
>>> {
>>> + if (unlikely(!opp_table))
>>> + return;
>>> +
>>> if (opp_table->genpd_virt_devs)
>>> dev_pm_opp_detach_genpd(opp_table);
>>
>> Does this fixes it for you ?
>>
>> It isn't allowed to call this routine with opp_table as NULL, I should
>> rather have a WARN() for the same instead.
>>
>> Can you check why exynos is passing NULL here as I don't see an
>> obvious reason currently.
>
> Looking at the exynos devfreq driver again, it feels like the design
> of the driver itself is causing all these issues.
>
> Ideally, whatever resources are acquired by probe() must be freed only
> and only by remove()/shutdown(). But you are trying to do it from
> exynos_bus_exit() as well. Calling dev_pm_opp_of_remove_table() as
> well from this function is wrong as you may very well end up
> corrupting the OPP refcount and OPP may never get freed or something
> else may come up.
>
> For now I am adding following to the patch, please see if it fixes it
> or not (I have pushed the changes to my branch as well).
>
> diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
> index 780e525eb92a..8fca24565e7d 100644
> --- a/drivers/devfreq/exynos-bus.c
> +++ b/drivers/devfreq/exynos-bus.c
> @@ -161,8 +161,11 @@ static void exynos_bus_exit(struct device *dev)
>
> dev_pm_opp_of_remove_table(dev);
> clk_disable_unprepare(bus->clk);
> - dev_pm_opp_clear_config(bus->opp_table);
> - bus->opp_table = NULL;
> +
> + if (bus->opp_table) {
> + dev_pm_opp_clear_config(bus->opp_table);
> + bus->opp_table = NULL;
> + }
> }
>
> static void exynos_bus_passive_exit(struct device *dev)
> @@ -463,8 +466,10 @@ static int exynos_bus_probe(struct platform_device *pdev)
> dev_pm_opp_of_remove_table(dev);
> clk_disable_unprepare(bus->clk);
> err_reg:
> - dev_pm_opp_clear_config(bus->opp_table);
> - bus->opp_table = NULL;
> + if (bus->opp_table) {
> + dev_pm_opp_clear_config(bus->opp_table);
> + bus->opp_table = NULL;
> + }
>
> return ret;
> }
>
This change is enough to remove the null pointer error. Thanks.
--
Best Regards,
Chanwoo Choi
Samsung Electronics
More information about the linux-arm-kernel
mailing list