[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v1 06/14] xen/riscv: riscv_of_processor_hartid() implementation




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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.