Now, all the cooling device use the globle cpufreq_cooling_ops. When the
CONFIG_THERMAL_GOV_POWER_ALLOCATOR is enabled, once one cluster init the
cpufreq_cooling_ops, it would make all cooling device use the power allocator's
ops. If one's em is error because of the "em_is_sane", it would cause the
em NULL, but the cooling device's ops is exist, as a result, it would cause
panic because of the em.
Add cpufreq_power_cooling_ops to avoid this case.
Signed-off-by: Di Shen <[email protected]>
Signed-off-by: Xuewen Yan <[email protected]>
---
drivers/thermal/cpufreq_cooling.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
index b8151d95a806..af5cfb458370 100644
--- a/drivers/thermal/cpufreq_cooling.c
+++ b/drivers/thermal/cpufreq_cooling.c
@@ -493,6 +493,17 @@ static struct thermal_cooling_device_ops cpufreq_cooling_ops = {
.set_cur_state = cpufreq_set_cur_state,
};
+#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
+static struct thermal_cooling_device_ops cpufreq_power_cooling_ops = {
+ .get_max_state = cpufreq_get_max_state,
+ .get_cur_state = cpufreq_get_cur_state,
+ .set_cur_state = cpufreq_set_cur_state,
+ .get_requested_power = cpufreq_get_requested_power,
+ .state2power = cpufreq_state2power,
+ .power2state = cpufreq_power2state,
+};
+#endif
+
/**
* __cpufreq_cooling_register - helper function to create cpufreq cooling device
* @np: a valid struct device_node to the cooling device device tree node
@@ -559,9 +570,7 @@ __cpufreq_cooling_register(struct device_node *np,
#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
if (em_is_sane(cpufreq_cdev, em)) {
cpufreq_cdev->em = em;
- cooling_ops->get_requested_power = cpufreq_get_requested_power;
- cooling_ops->state2power = cpufreq_state2power;
- cooling_ops->power2state = cpufreq_power2state;
+ cooling_ops = &cpufreq_power_cooling_ops;
} else
#endif
if (policy->freq_table_sorted == CPUFREQ_TABLE_UNSORTED) {
--
2.17.1
On 18-07-22, 20:24, Di Shen wrote:
> Now, all the cooling device use the globle cpufreq_cooling_ops. When the
> CONFIG_THERMAL_GOV_POWER_ALLOCATOR is enabled, once one cluster init the
> cpufreq_cooling_ops, it would make all cooling device use the power allocator's
> ops. If one's em is error because of the "em_is_sane", it would cause the
> em NULL, but the cooling device's ops is exist, as a result, it would cause
> panic because of the em.
>
> Add cpufreq_power_cooling_ops to avoid this case.
>
> Signed-off-by: Di Shen <[email protected]>
> Signed-off-by: Xuewen Yan <[email protected]>
> ---
> drivers/thermal/cpufreq_cooling.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
> index b8151d95a806..af5cfb458370 100644
> --- a/drivers/thermal/cpufreq_cooling.c
> +++ b/drivers/thermal/cpufreq_cooling.c
> @@ -493,6 +493,17 @@ static struct thermal_cooling_device_ops cpufreq_cooling_ops = {
> .set_cur_state = cpufreq_set_cur_state,
> };
>
> +#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
> +static struct thermal_cooling_device_ops cpufreq_power_cooling_ops = {
> + .get_max_state = cpufreq_get_max_state,
> + .get_cur_state = cpufreq_get_cur_state,
> + .set_cur_state = cpufreq_set_cur_state,
> + .get_requested_power = cpufreq_get_requested_power,
> + .state2power = cpufreq_state2power,
> + .power2state = cpufreq_power2state,
> +};
> +#endif
> +
> /**
> * __cpufreq_cooling_register - helper function to create cpufreq cooling device
> * @np: a valid struct device_node to the cooling device device tree node
> @@ -559,9 +570,7 @@ __cpufreq_cooling_register(struct device_node *np,
> #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
> if (em_is_sane(cpufreq_cdev, em)) {
> cpufreq_cdev->em = em;
> - cooling_ops->get_requested_power = cpufreq_get_requested_power;
> - cooling_ops->state2power = cpufreq_state2power;
> - cooling_ops->power2state = cpufreq_power2state;
> + cooling_ops = &cpufreq_power_cooling_ops;
> } else
> #endif
> if (policy->freq_table_sorted == CPUFREQ_TABLE_UNSORTED) {
Please have a look at this patch in linux-next.
commit 6ee324afdf30 ("drivers/thermal/cpufreq_cooling: Use private callback ops for each cooling device")
This already fixes the problem, right ?
--
viresh
Yes, it fixes this problem! Thank you:)
BR
Di
On Tue, Jul 19, 2022 at 12:30 PM Viresh Kumar <[email protected]> wrote:
>
> On 18-07-22, 20:24, Di Shen wrote:
> > Now, all the cooling device use the globle cpufreq_cooling_ops. When the
> > CONFIG_THERMAL_GOV_POWER_ALLOCATOR is enabled, once one cluster init the
> > cpufreq_cooling_ops, it would make all cooling device use the power allocator's
> > ops. If one's em is error because of the "em_is_sane", it would cause the
> > em NULL, but the cooling device's ops is exist, as a result, it would cause
> > panic because of the em.
> >
> > Add cpufreq_power_cooling_ops to avoid this case.
> >
> > Signed-off-by: Di Shen <[email protected]>
> > Signed-off-by: Xuewen Yan <[email protected]>
> > ---
> > drivers/thermal/cpufreq_cooling.c | 15 ++++++++++++---
> > 1 file changed, 12 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
> > index b8151d95a806..af5cfb458370 100644
> > --- a/drivers/thermal/cpufreq_cooling.c
> > +++ b/drivers/thermal/cpufreq_cooling.c
> > @@ -493,6 +493,17 @@ static struct thermal_cooling_device_ops cpufreq_cooling_ops = {
> > .set_cur_state = cpufreq_set_cur_state,
> > };
> >
> > +#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
> > +static struct thermal_cooling_device_ops cpufreq_power_cooling_ops = {
> > + .get_max_state = cpufreq_get_max_state,
> > + .get_cur_state = cpufreq_get_cur_state,
> > + .set_cur_state = cpufreq_set_cur_state,
> > + .get_requested_power = cpufreq_get_requested_power,
> > + .state2power = cpufreq_state2power,
> > + .power2state = cpufreq_power2state,
> > +};
> > +#endif
> > +
> > /**
> > * __cpufreq_cooling_register - helper function to create cpufreq cooling device
> > * @np: a valid struct device_node to the cooling device device tree node
> > @@ -559,9 +570,7 @@ __cpufreq_cooling_register(struct device_node *np,
> > #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
> > if (em_is_sane(cpufreq_cdev, em)) {
> > cpufreq_cdev->em = em;
> > - cooling_ops->get_requested_power = cpufreq_get_requested_power;
> > - cooling_ops->state2power = cpufreq_state2power;
> > - cooling_ops->power2state = cpufreq_power2state;
> > + cooling_ops = &cpufreq_power_cooling_ops;
> > } else
> > #endif
> > if (policy->freq_table_sorted == CPUFREQ_TABLE_UNSORTED) {
>
> Please have a look at this patch in linux-next.
>
> commit 6ee324afdf30 ("drivers/thermal/cpufreq_cooling: Use private callback ops for each cooling device")
>
> This already fixes the problem, right ?
>
> --
> viresh