[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250502161300.1411-7-alireza.sanaee@huawei.com>
Date: Fri, 2 May 2025 17:13:00 +0100
From: Alireza Sanaee <alireza.sanaee@...wei.com>
To: <devicetree@...r.kernel.org>
CC: <robh@...nel.org>, <jonathan.cameron@...wei.com>,
<linux-arm-kernel@...ts.infradead.org>, <linux-kernel@...r.kernel.org>,
<linuxarm@...wei.com>, <mark.rutland@....com>,
<shameerali.kolothum.thodi@...wei.com>
Subject: [PATCH v2 6/6] of: of_cpu_phandle_to_id to support SMT threads
Enhance the API to support SMT threads, this will allow sharing resources among
multiple SMT threads.
Enabled the sharing of resources, such as L1 Cache and clocks, between SMT
threads. It introduces a fix that uses thread IDs to match each CPU thread in
the register array within the cpu-node. This ensures that the cpu-map or any
driver relying on this API is fine even when SMT threads share resources.
Additionally, I have tested this for CPU based on the discussions in [1], I
adopted the new cpu-map layout, where the first parameter is a phandle and the
second is the local thread index, as shown below:
In the CPU map, there are two cases that only one occurs at at time.
1) "cpu" = <phandle>
2) "cpus" = <phandle> <index>
The first case addresses non-SMTs and the second case addresses SMTs
that the variable must be cpu(s) with an index where we later look up
the reg array with that.
core0 {
thread0 {
cpus = <&cpu0 0>;
};
thread1 {
cpus = <&cpu0 1>;
};
};
[1] https://lore.kernel.org/devicetree-spec/CAL_JsqK1yqRLD9B+G7UUp=D8K++mXHq0Rmv=1i6DL_jXyZwXAw@mail.gmail.com/
Signed-off-by: Alireza Sanaee <alireza.sanaee@...wei.com>
---
drivers/of/cpu.c | 33 ++++++++++++++++++++++++++++++---
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/drivers/of/cpu.c b/drivers/of/cpu.c
index 1e8d1fa04d3c..fbd3f6d4a87f 100644
--- a/drivers/of/cpu.c
+++ b/drivers/of/cpu.c
@@ -186,14 +186,41 @@ EXPORT_SYMBOL(of_cpu_node_to_id);
int of_cpu_phandle_to_id(const struct device_node *node,
struct device_node **cpu_np)
{
+ int cpu, ret;
+ bool found = false;
+ uint32_t local_thread, thread_index;
+ struct device_node *np;
+ struct of_phandle_args args;
+
if (!node)
return -1;
+ /*
+ * Two cases which only one occurs at a time:
+ * 1) cpu = <phandle>
+ * 2) cpus = <phandle> <thread_index>
+ */
*cpu_np = of_parse_phandle(node, "cpu", 0);
- if (!cpu_np)
- return -ENODEV;
+ if (!*cpu_np) {
+ ret = of_parse_phandle_with_fixed_args(node, "cpus", 1, 0,
+ &args);
+ if (ret < 0)
+ return ret;
+
+ *cpu_np = args.np;
+ thread_index = args.args[0];
+ for_each_possible_cpu(cpu) {
+ np = of_get_cpu_node(cpu, &local_thread);
+ found = (*cpu_np == np) && (local_thread == thread_index);
+ of_node_put(np);
+ if (found)
+ return cpu;
+ }
- return of_cpu_node_to_id(*cpu_np);
+ return -ENODEV;
+ } else {
+ return of_cpu_node_to_id(*cpu_np);
+ }
}
EXPORT_SYMBOL(of_cpu_phandle_to_id);
--
2.34.1
Powered by blists - more mailing lists