mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/2] PM: EM: Fix incorrect description of the cost field in struct em_perf_state
@ 2025-12-30  6:15 Yaxiong Tian
  2025-12-30  6:20 ` [PATCH 2/2] PM: EM: Simplify mutex-related code in energy_model.c using scoped_guard Yaxiong Tian
  2025-12-30  9:35 ` [PATCH 1/2] PM: EM: Fix incorrect description of the cost field in struct em_perf_state Lukasz Luba
  0 siblings, 2 replies; 4+ messages in thread
From: Yaxiong Tian @ 2025-12-30  6:15 UTC (permalink / raw)
  To: lukasz.luba, rafael, pavel, lenb; +Cc: linux-pm, linux-kernel, Yaxiong Tian

Due to commit 1b600da51073 ("PM: EM: Optimize em_cpu_energy() and remove
division"), the logic for energy consumption calculation has been modified.
The actual calculation of cost is 10 * power * max_frequency / frequency
instead of power * max_frequency / frequency.

Therefore, the comment for cost has been updated to reflect the correct
content.

Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
---
 include/linux/energy_model.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h
index 43aa6153dc57..e7497f804644 100644
--- a/include/linux/energy_model.h
+++ b/include/linux/energy_model.h
@@ -18,7 +18,7 @@
  * @power:	The power consumed at this level (by 1 CPU or by a registered
  *		device). It can be a total power: static and dynamic.
  * @cost:	The cost coefficient associated with this level, used during
- *		energy calculation. Equal to: power * max_frequency / frequency
+ *		energy calculation. Equal to: 10 * power * max_frequency / frequency
  * @flags:	see "em_perf_state flags" description below.
  */
 struct em_perf_state {
-- 
2.25.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/2] PM: EM: Simplify mutex-related code in energy_model.c using scoped_guard
  2025-12-30  6:15 [PATCH 1/2] PM: EM: Fix incorrect description of the cost field in struct em_perf_state Yaxiong Tian
@ 2025-12-30  6:20 ` Yaxiong Tian
  2025-12-30  9:35 ` [PATCH 1/2] PM: EM: Fix incorrect description of the cost field in struct em_perf_state Lukasz Luba
  1 sibling, 0 replies; 4+ messages in thread
From: Yaxiong Tian @ 2025-12-30  6:20 UTC (permalink / raw)
  To: lukasz.luba, rafael, pavel, lenb; +Cc: linux-pm, linux-kernel, Yaxiong Tian

Code cleanup with no functional changes. Use scoped_guard() instead of
open-coded mutex_lock/mutex_unlock.

Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
---
 kernel/power/energy_model.c | 173 ++++++++++++++++--------------------
 1 file changed, 78 insertions(+), 95 deletions(-)

diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
index 11af9f64aa82..cf2a8e958ecb 100644
--- a/kernel/power/energy_model.c
+++ b/kernel/power/energy_model.c
@@ -333,25 +333,21 @@ int em_dev_update_perf_domain(struct device *dev,
 		return -EINVAL;
 
 	/* Serialize update/unregister or concurrent updates */
-	mutex_lock(&em_pd_mutex);
-
-	if (!dev->em_pd) {
-		mutex_unlock(&em_pd_mutex);
-		return -EINVAL;
-	}
-	pd = dev->em_pd;
-
-	kref_get(&new_table->kref);
+	scoped_guard(mutex, &em_pd_mutex) {
+		if (!dev->em_pd)
+			return -EINVAL;
+		pd = dev->em_pd;
 
-	old_table = rcu_dereference_protected(pd->em_table,
-					      lockdep_is_held(&em_pd_mutex));
-	rcu_assign_pointer(pd->em_table, new_table);
+		kref_get(&new_table->kref);
 
-	em_cpufreq_update_efficiencies(dev, new_table->state);
+		old_table = rcu_dereference_protected(pd->em_table,
+							lockdep_is_held(&em_pd_mutex));
+		rcu_assign_pointer(pd->em_table, new_table);
 
-	em_table_free(old_table);
+		em_cpufreq_update_efficiencies(dev, new_table->state);
 
-	mutex_unlock(&em_pd_mutex);
+		em_table_free(old_table);
+	}
 
 	em_notify_pd_updated(pd);
 	return 0;
@@ -623,82 +619,70 @@ int em_dev_register_pd_no_update(struct device *dev, unsigned int nr_states,
 	 * Use a mutex to serialize the registration of performance domains and
 	 * let the driver-defined callback functions sleep.
 	 */
-	mutex_lock(&em_pd_mutex);
-
-	if (dev->em_pd) {
-		ret = -EEXIST;
-		goto unlock;
-	}
+	scoped_guard(mutex, &em_pd_mutex) {
+		if (dev->em_pd)
+			return -EEXIST;
 
-	if (_is_cpu_device(dev)) {
-		if (!cpus) {
-			dev_err(dev, "EM: invalid CPU mask\n");
-			ret = -EINVAL;
-			goto unlock;
-		}
-
-		for_each_cpu(cpu, cpus) {
-			if (em_cpu_get(cpu)) {
-				dev_err(dev, "EM: exists for CPU%d\n", cpu);
-				ret = -EEXIST;
-				goto unlock;
+		if (_is_cpu_device(dev)) {
+			if (!cpus) {
+				dev_err(dev, "EM: invalid CPU mask\n");
+				return -EINVAL;
 			}
-			/*
-			 * All CPUs of a domain must have the same
-			 * micro-architecture since they all share the same
-			 * table.
-			 */
-			cap = arch_scale_cpu_capacity(cpu);
-			if (prev_cap && prev_cap != cap) {
-				dev_err(dev, "EM: CPUs of %*pbl must have the same capacity\n",
-					cpumask_pr_args(cpus));
-
-				ret = -EINVAL;
-				goto unlock;
+
+			for_each_cpu(cpu, cpus) {
+				if (em_cpu_get(cpu)) {
+					dev_err(dev, "EM: exists for CPU%d\n", cpu);
+					return -EEXIST;
+				}
+				/*
+				 * All CPUs of a domain must have the same
+				 * micro-architecture since they all share the same
+				 * table.
+				 */
+				cap = arch_scale_cpu_capacity(cpu);
+				if (prev_cap && prev_cap != cap) {
+					dev_err(dev, "EM: CPUs of %*pbl must have the same capacity\n",
+						cpumask_pr_args(cpus));
+
+					return -EINVAL;
+				}
+				prev_cap = cap;
 			}
-			prev_cap = cap;
 		}
-	}
 
-	if (microwatts)
-		flags |= EM_PERF_DOMAIN_MICROWATTS;
-	else if (cb->get_cost)
-		flags |= EM_PERF_DOMAIN_ARTIFICIAL;
+		if (microwatts)
+			flags |= EM_PERF_DOMAIN_MICROWATTS;
+		else if (cb->get_cost)
+			flags |= EM_PERF_DOMAIN_ARTIFICIAL;
 
-	/*
-	 * EM only supports uW (exception is artificial EM).
-	 * Therefore, check and force the drivers to provide
-	 * power in uW.
-	 */
-	if (!microwatts && !(flags & EM_PERF_DOMAIN_ARTIFICIAL)) {
-		dev_err(dev, "EM: only supports uW power values\n");
-		ret = -EINVAL;
-		goto unlock;
-	}
-
-	ret = em_create_pd(dev, nr_states, cb, cpus, flags);
-	if (ret)
-		goto unlock;
+		/*
+		 * EM only supports uW (exception is artificial EM).
+		 * Therefore, check and force the drivers to provide
+		 * power in uW.
+		 */
+		if (!microwatts && !(flags & EM_PERF_DOMAIN_ARTIFICIAL)) {
+			dev_err(dev, "EM: only supports uW power values\n");
+			return -EINVAL;
+		}
 
-	dev->em_pd->flags |= flags;
-	dev->em_pd->min_perf_state = 0;
-	dev->em_pd->max_perf_state = nr_states - 1;
+		ret = em_create_pd(dev, nr_states, cb, cpus, flags);
+		if (ret)
+			return ret;
 
-	em_table = rcu_dereference_protected(dev->em_pd->em_table,
-					     lockdep_is_held(&em_pd_mutex));
-	em_cpufreq_update_efficiencies(dev, em_table->state);
+		dev->em_pd->flags |= flags;
+		dev->em_pd->min_perf_state = 0;
+		dev->em_pd->max_perf_state = nr_states - 1;
 
-	em_debug_create_pd(dev);
-	dev_info(dev, "EM: created perf domain\n");
+		em_table = rcu_dereference_protected(dev->em_pd->em_table,
+							lockdep_is_held(&em_pd_mutex));
+		em_cpufreq_update_efficiencies(dev, em_table->state);
 
-unlock:
-	mutex_unlock(&em_pd_mutex);
-	if (ret)
-		return ret;
+		em_debug_create_pd(dev);
+		dev_info(dev, "EM: created perf domain\n");
+	}
 
-	mutex_lock(&em_pd_list_mutex);
-	list_add_tail(&dev->em_pd->node, &em_pd_list);
-	mutex_unlock(&em_pd_list_mutex);
+	scoped_guard(mutex, &em_pd_list_mutex)
+		list_add_tail(&dev->em_pd->node, &em_pd_list);
 
 	em_notify_pd_created(dev->em_pd);
 
@@ -720,9 +704,8 @@ void em_dev_unregister_perf_domain(struct device *dev)
 	if (_is_cpu_device(dev))
 		return;
 
-	mutex_lock(&em_pd_list_mutex);
-	list_del_init(&dev->em_pd->node);
-	mutex_unlock(&em_pd_list_mutex);
+	scoped_guard(mutex, &em_pd_list_mutex)
+		list_del_init(&dev->em_pd->node);
 
 	em_notify_pd_deleted(dev->em_pd);
 
@@ -731,17 +714,17 @@ void em_dev_unregister_perf_domain(struct device *dev)
 	 * from potential clean-up/setup issues in the debugfs directories.
 	 * The debugfs directory name is the same as device's name.
 	 */
-	mutex_lock(&em_pd_mutex);
-	em_debug_remove_pd(dev);
+	scoped_guard(mutex, &em_pd_mutex) {
+		em_debug_remove_pd(dev);
 
-	em_table_free(rcu_dereference_protected(dev->em_pd->em_table,
-						lockdep_is_held(&em_pd_mutex)));
+		em_table_free(rcu_dereference_protected(dev->em_pd->em_table,
+							lockdep_is_held(&em_pd_mutex)));
 
-	ida_free(&em_pd_ida, dev->em_pd->id);
+		ida_free(&em_pd_ida, dev->em_pd->id);
 
-	kfree(dev->em_pd);
-	dev->em_pd = NULL;
-	mutex_unlock(&em_pd_mutex);
+		kfree(dev->em_pd);
+		dev->em_pd = NULL;
+	}
 }
 EXPORT_SYMBOL_GPL(em_dev_unregister_perf_domain);
 
@@ -983,10 +966,10 @@ int em_update_performance_limits(struct em_perf_domain *pd,
 
 
 	/* Guard simultaneous updates and make them atomic */
-	mutex_lock(&em_pd_mutex);
-	pd->min_perf_state = min_ps;
-	pd->max_perf_state = max_ps;
-	mutex_unlock(&em_pd_mutex);
+	scoped_guard(mutex, &em_pd_mutex) {
+		pd->min_perf_state = min_ps;
+		pd->max_perf_state = max_ps;
+	}
 
 	return 0;
 }
-- 
2.25.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] PM: EM: Fix incorrect description of the cost field in struct em_perf_state
  2025-12-30  6:15 [PATCH 1/2] PM: EM: Fix incorrect description of the cost field in struct em_perf_state Yaxiong Tian
  2025-12-30  6:20 ` [PATCH 2/2] PM: EM: Simplify mutex-related code in energy_model.c using scoped_guard Yaxiong Tian
@ 2025-12-30  9:35 ` Lukasz Luba
  2026-01-08 15:53   ` Rafael J. Wysocki
  1 sibling, 1 reply; 4+ messages in thread
From: Lukasz Luba @ 2025-12-30  9:35 UTC (permalink / raw)
  To: Yaxiong Tian; +Cc: linux-pm, lenb, linux-kernel, pavel, rafael



On 12/30/25 06:15, Yaxiong Tian wrote:
> Due to commit 1b600da51073 ("PM: EM: Optimize em_cpu_energy() and remove
> division"), the logic for energy consumption calculation has been modified.
> The actual calculation of cost is 10 * power * max_frequency / frequency
> instead of power * max_frequency / frequency.
> 
> Therefore, the comment for cost has been updated to reflect the correct
> content.
> 
> Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
> ---
>   include/linux/energy_model.h | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h
> index 43aa6153dc57..e7497f804644 100644
> --- a/include/linux/energy_model.h
> +++ b/include/linux/energy_model.h
> @@ -18,7 +18,7 @@
>    * @power:	The power consumed at this level (by 1 CPU or by a registered
>    *		device). It can be a total power: static and dynamic.
>    * @cost:	The cost coefficient associated with this level, used during
> - *		energy calculation. Equal to: power * max_frequency / frequency
> + *		energy calculation. Equal to: 10 * power * max_frequency / frequency
>    * @flags:	see "em_perf_state flags" description below.
>    */
>   struct em_perf_state {

Good catch, thank you!

Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] PM: EM: Fix incorrect description of the cost field in struct em_perf_state
  2025-12-30  9:35 ` [PATCH 1/2] PM: EM: Fix incorrect description of the cost field in struct em_perf_state Lukasz Luba
@ 2026-01-08 15:53   ` Rafael J. Wysocki
  0 siblings, 0 replies; 4+ messages in thread
From: Rafael J. Wysocki @ 2026-01-08 15:53 UTC (permalink / raw)
  To: Lukasz Luba, Yaxiong Tian; +Cc: linux-pm, linux-kernel

On Tue, Dec 30, 2025 at 10:36 AM Lukasz Luba <lukasz.luba@arm.com> wrote:
>
>
>
> On 12/30/25 06:15, Yaxiong Tian wrote:
> > Due to commit 1b600da51073 ("PM: EM: Optimize em_cpu_energy() and remove
> > division"), the logic for energy consumption calculation has been modified.
> > The actual calculation of cost is 10 * power * max_frequency / frequency
> > instead of power * max_frequency / frequency.
> >
> > Therefore, the comment for cost has been updated to reflect the correct
> > content.
> >
> > Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
> > ---
> >   include/linux/energy_model.h | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h
> > index 43aa6153dc57..e7497f804644 100644
> > --- a/include/linux/energy_model.h
> > +++ b/include/linux/energy_model.h
> > @@ -18,7 +18,7 @@
> >    * @power:  The power consumed at this level (by 1 CPU or by a registered
> >    *          device). It can be a total power: static and dynamic.
> >    * @cost:   The cost coefficient associated with this level, used during
> > - *           energy calculation. Equal to: power * max_frequency / frequency
> > + *           energy calculation. Equal to: 10 * power * max_frequency / frequency
> >    * @flags:  see "em_perf_state flags" description below.
> >    */
> >   struct em_perf_state {
>
> Good catch, thank you!
>
> Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>

Applied as 6.19-rc material, thanks!

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-01-08 15:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-30  6:15 [PATCH 1/2] PM: EM: Fix incorrect description of the cost field in struct em_perf_state Yaxiong Tian
2025-12-30  6:20 ` [PATCH 2/2] PM: EM: Simplify mutex-related code in energy_model.c using scoped_guard Yaxiong Tian
2025-12-30  9:35 ` [PATCH 1/2] PM: EM: Fix incorrect description of the cost field in struct em_perf_state Lukasz Luba
2026-01-08 15:53   ` Rafael J. Wysocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®