All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lukasz Luba <lukasz.luba@arm.com>
To: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
	rafael@kernel.org
Cc: lukasz.luba@arm.com, dietmar.eggemann@arm.com,
	rui.zhang@intel.com, amit.kucheria@verdurent.com,
	amit.kachhap@gmail.com, daniel.lezcano@linaro.org,
	viresh.kumar@linaro.org, len.brown@intel.com, pavel@ucw.cz,
	mhiramat@kernel.org, qyousef@layalina.io, wvw@google.com,
	xuewen.yan94@gmail.com
Subject: [PATCH v8 08/23] PM: EM: Introduce runtime modifiable table
Date: Thu,  8 Feb 2024 11:55:42 +0000	[thread overview]
Message-ID: <20240208115557.1273962-9-lukasz.luba@arm.com> (raw)
In-Reply-To: <20240208115557.1273962-1-lukasz.luba@arm.com>

The new runtime table can be populated with a new power data to better
reflect the actual efficiency of the device e.g. CPU. The power can vary
over time e.g. due to the SoC temperature change. Higher temperature can
increase power values. For longer running scenarios, such as game or
camera, when also other devices are used (e.g. GPU, ISP) the CPU power can
change. The new EM framework is able to addresses this issue and change
the EM data at runtime safely.

Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
---
 include/linux/energy_model.h | 12 ++++++++
 kernel/power/energy_model.c  | 53 ++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h
index 1dcd1645dde7..8ddf1d8a9581 100644
--- a/include/linux/energy_model.h
+++ b/include/linux/energy_model.h
@@ -36,9 +36,20 @@ struct em_perf_state {
  */
 #define EM_PERF_STATE_INEFFICIENT BIT(0)
 
+/**
+ * struct em_perf_table - Performance states table
+ * @rcu:	RCU used for safe access and destruction
+ * @state:	List of performance states, in ascending order
+ */
+struct em_perf_table {
+	struct rcu_head rcu;
+	struct em_perf_state state[];
+};
+
 /**
  * struct em_perf_domain - Performance domain
  * @table:		List of performance states, in ascending order
+ * @em_table:		Pointer to the runtime modifiable em_perf_table
  * @nr_perf_states:	Number of performance states
  * @flags:		See "em_perf_domain flags"
  * @cpus:		Cpumask covering the CPUs of the domain. It's here
@@ -54,6 +65,7 @@ struct em_perf_state {
  */
 struct em_perf_domain {
 	struct em_perf_state *table;
+	struct em_perf_table __rcu *em_table;
 	int nr_perf_states;
 	unsigned long flags;
 	unsigned long cpus[];
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
index 7468fa92134b..131ff1d0dc5b 100644
--- a/kernel/power/energy_model.c
+++ b/kernel/power/energy_model.c
@@ -23,6 +23,9 @@
  */
 static DEFINE_MUTEX(em_pd_mutex);
 
+static void em_cpufreq_update_efficiencies(struct device *dev,
+					   struct em_perf_state *table);
+
 static bool _is_cpu_device(struct device *dev)
 {
 	return (dev->bus == &cpu_subsys);
@@ -103,6 +106,31 @@ static void em_debug_create_pd(struct device *dev) {}
 static void em_debug_remove_pd(struct device *dev) {}
 #endif
 
+static void em_destroy_table_rcu(struct rcu_head *rp)
+{
+	struct em_perf_table __rcu *table;
+
+	table = container_of(rp, struct em_perf_table, rcu);
+	kfree(table);
+}
+
+static void em_free_table(struct em_perf_table __rcu *table)
+{
+	call_rcu(&table->rcu, em_destroy_table_rcu);
+}
+
+static struct em_perf_table __rcu *
+em_allocate_table(struct em_perf_domain *pd)
+{
+	struct em_perf_table __rcu *table;
+	int table_size;
+
+	table_size = sizeof(struct em_perf_state) * pd->nr_perf_states;
+
+	table = kzalloc(sizeof(*table) + table_size, GFP_KERNEL);
+	return table;
+}
+
 static int em_compute_costs(struct device *dev, struct em_perf_state *table,
 			    struct em_data_callback *cb, int nr_states,
 			    unsigned long flags)
@@ -153,6 +181,24 @@ static int em_allocate_perf_table(struct em_perf_domain *pd,
 	return 0;
 }
 
+static int em_create_runtime_table(struct em_perf_domain *pd)
+{
+	struct em_perf_table __rcu *table;
+	int table_size;
+
+	table = em_allocate_table(pd);
+	if (!table)
+		return -ENOMEM;
+
+	/* Initialize runtime table with existing data */
+	table_size = sizeof(struct em_perf_state) * pd->nr_perf_states;
+	memcpy(table->state, pd->table, table_size);
+
+	rcu_assign_pointer(pd->em_table, table);
+
+	return 0;
+}
+
 static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
 				struct em_perf_state *table,
 				struct em_data_callback *cb,
@@ -245,6 +291,10 @@ static int em_create_pd(struct device *dev, int nr_states,
 	if (ret)
 		goto free_pd_table;
 
+	ret = em_create_runtime_table(pd);
+	if (ret)
+		goto free_pd_table;
+
 	if (_is_cpu_device(dev))
 		for_each_cpu(cpu, cpus) {
 			cpu_dev = get_cpu_device(cpu);
@@ -461,6 +511,9 @@ void em_dev_unregister_perf_domain(struct device *dev)
 	em_debug_remove_pd(dev);
 
 	kfree(dev->em_pd->table);
+
+	em_free_table(dev->em_pd->em_table);
+
 	kfree(dev->em_pd);
 	dev->em_pd = NULL;
 	mutex_unlock(&em_pd_mutex);
-- 
2.25.1


  parent reply	other threads:[~2024-02-08 11:56 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-08 11:55 [PATCH v8 00/23] Introduce runtime modifiable Energy Model Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 01/23] PM: EM: Add missing newline for the message log Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 02/23] PM: EM: Extend em_cpufreq_update_efficiencies() argument list Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 03/23] PM: EM: Find first CPU active while updating OPP efficiency Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 04/23] PM: EM: Refactor em_pd_get_efficient_state() to be more flexible Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 05/23] PM: EM: Introduce em_compute_costs() Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 06/23] PM: EM: Check if the get_cost() callback is present in em_compute_costs() Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 07/23] PM: EM: Split the allocation and initialization of the EM table Lukasz Luba
2024-02-08 11:55 ` Lukasz Luba [this message]
2024-02-08 11:55 ` [PATCH v8 09/23] PM: EM: Use runtime modified EM for CPUs energy estimation in EAS Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 10/23] PM: EM: Add functions for memory allocations for new EM tables Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 11/23] PM: EM: Introduce em_dev_update_perf_domain() for EM updates Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 12/23] PM: EM: Add em_perf_state_from_pd() to get performance states table Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 13/23] PM: EM: Add performance field to struct em_perf_state and optimize Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 14/23] PM: EM: Support late CPUs booting and capacity adjustment Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 15/23] PM: EM: Optimize em_cpu_energy() and remove division Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 16/23] powercap/dtpm_cpu: Use new Energy Model interface to get table Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 17/23] powercap/dtpm_devfreq: " Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 18/23] drivers/thermal/cpufreq_cooling: Use new Energy Model interface Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 19/23] drivers/thermal/devfreq_cooling: " Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 20/23] PM: EM: Change debugfs configuration to use runtime EM table data Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 21/23] PM: EM: Remove old table Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 22/23] PM: EM: Add em_dev_compute_costs() Lukasz Luba
2024-02-08 11:55 ` [PATCH v8 23/23] Documentation: EM: Update with runtime modification design Lukasz Luba
2024-02-08 14:01 ` [PATCH v8 00/23] Introduce runtime modifiable Energy Model Rafael J. Wysocki
2024-02-08 15:00   ` Lukasz Luba

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240208115557.1273962-9-lukasz.luba@arm.com \
    --to=lukasz.luba@arm.com \
    --cc=amit.kachhap@gmail.com \
    --cc=amit.kucheria@verdurent.com \
    --cc=daniel.lezcano@linaro.org \
    --cc=dietmar.eggemann@arm.com \
    --cc=len.brown@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=pavel@ucw.cz \
    --cc=qyousef@layalina.io \
    --cc=rafael@kernel.org \
    --cc=rui.zhang@intel.com \
    --cc=viresh.kumar@linaro.org \
    --cc=wvw@google.com \
    --cc=xuewen.yan94@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.