On 4/28/25 8:31 AM, Jan Beulich wrote:
On 25.04.2025 19:07, Oleksii Kurochko wrote:
On 4/15/25 3:45 PM, Jan Beulich wrote:
On 15.04.2025 15:39, Oleksii Kurochko wrote:
On 4/10/25 5:53 PM, Jan Beulich wrote:
On 08.04.2025 17:57, Oleksii Kurochko wrote:
+{
+    const __be32 *cell;
+    int ac;
+    uint32_t len;
+
+    ac = dt_n_addr_cells(cpun);
+    cell = dt_get_property(cpun, "reg", &len);
+    if ( !cell || !ac || ((sizeof(*cell) * ac * (thread + 1)) > len) )
+        return ~0ULL;
I'm sorry for my lack of DT knowledge, but what's "thread" representing here?
You only pass in 0 below, so it's unclear whether it's what one might expect
(the thread number on a multi-threaded core).
Based on the DT specification alone, the|`reg`| value could refer to either a 
CPU or a thread ID:
```
The value of reg is a <prop-encoded-array> that defines a unique CPU/thread id 
for
the CPU/threads represented by the CPU node. If a CPU supports more than one 
thread
(i.e. multiple streams of execution) the reg prop-erty is an array with 1 
element
per thread.
```

My understanding is that the term/thread/ was used in the Linux kernel to cover 
both
cases.
When SMT isn't supported, the CPU can be considered to have a single thread.
For example, RISC-V uses the term/hardware thread/ to describe a hart (i.e., a 
CPU).
Note the terminology ("CPU") you used here.

Interestingly, the Linux kernel always uses|thread = 0|.

We could potentially drop this ambiguity and introduce an|ASSERT()| to check 
that
the|`reg`| property contains only one entry, representing the HART (CPU) ID:
```
     Software can determine the number of threads by dividing the size of reg 
by the parent
     node’s #address-cells. If `|reg`| has more than one entry, it would simply 
SMT support
     is required.
```

Does that approach make sense, or should we stick with the current 
implementation?
If extra enabling is required to make multi-thread CPUs work, then panic()ing
(not so much ASSERT()ing) may make sense, for the time being. Better would be
if we could use all threads in a system right away.
Actually, this function is ready to be used for multi-thread CPUs. A caller can 
request hardware id
by passing `thread` argument (`thread` -> the local thread number to get the 
hardware ID for).
So by calling:
   dt_get_cpu_hwid(cpu0, 0) -> it will return hardware id of thread 0 of cpu0
   dt_get_cpu_hwid(cpu0, 1) -> it will return hardware id of thread 1 of cpu0
   ...

In our case we assume that SMP isn't supported so that is why it is used only 
dt_get_cpu_hwid(cpu0, 0).

If one day, SMP will be enabled then it will be needed to change a callers of 
dt_get_cpu_hwid().
I assume you meant SMT in both places you wrote SMP?

Yes, it should be SMT.

  But my main point here is:
If enumeration gives you "thread <N> of core <M>" (using x86 terminology), you
need to be quite careful with what you call "CPU". Things need to be entirely
unambiguous, taking into account what internally in (common code) Xen we call a
"CPU". You certainly may call "CPU" what is a collection of threads / harts,
but you then need to clarify this in a prominent comment somewhere, and you
need to be entirely consistent throughout the RISC-V sub-tree.

╭────────────────────╮
│        CPU          │  ← 1 physical processor (chip)
│ ┌───────┬─────────┐ │
│ │ Core 0│ Core 1  │ │  ← 2 cores (for example)
│ │ ┌──┬──┐ ┌──┬──┐ │ │
│ │Thr0 Thr1 Thr0 Thr1│ ← 2 threads on each core (SMT)
│ └───────┴─────────┘ │
╰────────────────────╯
I want to double check what Xen call a "CPU". I thought that Xen uses word
CPU to describe a core, right?

What you wrote above "thread <N> of core <M> (using x86 terminology)" is also 
correlated
with RISC-V terminology:
  A component is termed a core if it contains an independent instruction fetch 
unit.
  A RISC-V-compatible core might support multiple RISC-V-compatible hardware 
threads,
  or harts, through multithreading

I checked RISC-V's DTS binding and it seems it is a little bit contradictory to 
DTS spec,
where it is mentioned that reg property is used to describe how many threads a 
cpu  has
when SMP is used, but in RISC-V's dts binding they are describing a hardware 
execution
context:
  This document uses some terminology common to the RISC-V community
  that is not widely used, the definitions of which are listed here:

  hart: A hardware execution context, which contains all the state
  mandated by the RISC-V ISA: a PC and some registers.  This
  terminology is designed to disambiguate software's view of execution
  contexts from any particular microarchitectural implementation
  strategy.  For example, an Intel laptop containing one socket with
  two cores, each of which has two hyperthreads, could be described as
  having four harts.

So in RISC-V's DTS binding they are describing only hardware threads what makes 
things more
confusing in terms what kind terminology from Xen point of view should be used.

And based on what is written in RISC-V's dts binding:
 For example, an Intel laptop containing one socket with
 two cores, each of which has two hyperthreads, could be described as
 having four harts.
It would be more logical to drop 'thread' argument of 
riscv_of_get_cpu_hwid(const struct dt_device_node *cpun).
And then the question is what to do with the name of variable cpun? As it could 
be still confusing. Or, at least,
I can add the comment that CPUn in terms of RISC-V means hart (hardware 
thread). And then will it be needed to
add such comment for each usage of word "CPU"?

~ Oleksii


Reply via email to