All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] xen/arm: Device Tree based CPU topology support
@ 2026-06-10 11:13 Hirokazu Takahashi
  2026-06-10 11:13 ` [PATCH 1/3] xen/device-tree: Parse 'cpu-map' node for CPU topology exploration Hirokazu Takahashi
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Hirokazu Takahashi @ 2026-06-10 11:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Mykyta_Poturai, Hirokazu Takahashi

Hello,

This patch series introduces Device Tree based CPU topology support for
ARM Xen.

These patches were previously part of my "Introduce Device Tree based NUMA
support for ARM Xen" series. Since the CPU topology feature can perfectly
work on its own, I decided to split it out and submit it as a standalone
series to make the review process easier.

Compared to the previous version included in the NUMA series, I have made
a few key improvements based on earlier discussions:

1. Optimized Memory Allocation:
   The series now allocates only the minimum required memory area to manage
   the essential data for the CPUs.

2. Flexible Device Tree Parsing:
   The parsing logic no longer depends on the definition order of the 'cpu'
   nodes and 'cpu-map' nodes in the Device Tree. They can now be read
   correctly even if their orders do not match.

3. CPU Hotplug Readiness:
   To support future CPU hotplug, the system assumes that inactive CPUs are
   also described in the Device Tree. Xen will pre-load and generate the
   topology information for these inactive CPUs during the boot phase so
   it stays available in memory.

Summary of changes:
 - Patch 1: Parses the 'cpu-map' node in the Device Tree to extract topology
            information.
 - Patch 2: Connects the extracted CPU topology data to the Xen scheduler.
 - Patch 3: Refactors `cpu_nr_siblings()` to be an architecture-specific
            function, providing an x86 implementation and a common version
            for Device Tree-based systems.

Thank you,
Hirokazu Takahashi

Hirokazu Takahashi (3):
  xen/device-tree: Parse 'cpu-map' node for CPU topology exploration
  xen/sched: Link CPU topology to scheduler
  xen/sched: Make cpu_nr_siblings() architecture-specific

 xen/arch/arm/include/asm/processor.h  |   4 -
 xen/arch/arm/smpboot.c                |  16 +-
 xen/arch/x86/include/asm/processor.h  |   1 +
 xen/common/Kconfig                    |   7 +
 xen/common/device-tree/Makefile       |   1 +
 xen/common/device-tree/cpu-topology.c | 393 ++++++++++++++++++++++++++
 xen/common/sched/credit2.c            |  22 +-
 xen/common/sysctl.c                   |   1 +
 xen/include/xen/cpu-topology.h        |  50 ++++
 9 files changed, 472 insertions(+), 23 deletions(-)
 create mode 100644 xen/common/device-tree/cpu-topology.c
 create mode 100644 xen/include/xen/cpu-topology.h

-- 
2.43.0



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

* [PATCH 1/3] xen/device-tree: Parse 'cpu-map' node for CPU topology exploration
  2026-06-10 11:13 [PATCH 0/3] xen/arm: Device Tree based CPU topology support Hirokazu Takahashi
@ 2026-06-10 11:13 ` Hirokazu Takahashi
  2026-06-11 14:06   ` Jan Beulich
  2026-06-11 22:35   ` Julien Grall
  2026-06-10 11:13 ` [PATCH 2/3] xen/sched: Link CPU topology to scheduler Hirokazu Takahashi
  2026-06-10 11:13 ` [PATCH 3/3] xen/sched: Make cpu_nr_siblings() architecture-specific Hirokazu Takahashi
  2 siblings, 2 replies; 16+ messages in thread
From: Hirokazu Takahashi @ 2026-06-10 11:13 UTC (permalink / raw)
  To: xen-devel
  Cc: Mykyta_Poturai, Hirokazu Takahashi, Stefano Stabellini,
	Julien Grall, Bertrand Marquis, Michal Orzel, Volodymyr Babchuk,
	Andrew Cooper, Anthony PERARD, Jan Beulich, Roger Pau Monné

Parse the 'cpu-map' node in the Device Tree to extract CPU topology
information. If the 'cpu-map' node is absent, fall back to
generating the topology data from the NUMA information. This
generation assumes exactly one socket per NUMA node and that SMT
is unsupported.

Signed-off-by: Hirokazu Takahashi <taka@valinux.co.jp>
---
 xen/arch/arm/smpboot.c                |   6 +
 xen/common/Kconfig                    |   7 +
 xen/common/device-tree/Makefile       |   1 +
 xen/common/device-tree/cpu-topology.c | 342 ++++++++++++++++++++++++++
 xen/include/xen/cpu-topology.h        |  38 +++
 5 files changed, 394 insertions(+)
 create mode 100644 xen/common/device-tree/cpu-topology.c
 create mode 100644 xen/include/xen/cpu-topology.h

diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
index 7f3cfa812e..c071f1494f 100644
--- a/xen/arch/arm/smpboot.c
+++ b/xen/arch/arm/smpboot.c
@@ -24,6 +24,7 @@
 #include <xen/warning.h>
 #include <xen/irq.h>
 #include <xen/console.h>
+#include <xen/cpu-topology.h>
 #include <asm/cpuerrata.h>
 #include <asm/gic.h>
 #include <asm/procinfo.h>
@@ -242,6 +243,8 @@ static void __init dt_smp_init_cpus(void)
         }
         else
             tmp_map[i] = hwid;
+
+        map_cpuid_to_node(i, cpu); /* pass the info to dt_init_cpu_topology() */
     }
 
     if ( !bootcpu_valid )
@@ -275,7 +278,10 @@ void __init smp_init_cpus(void)
     }
 
     if ( acpi_disabled )
+    {
         dt_smp_init_cpus();
+        dt_init_cpu_topology();
+    }
     else
         acpi_smp_init_cpus();
 
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index 5ff71480ee..9f9b48a4b7 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -188,6 +188,13 @@ config VM_EVENT
 config NEEDS_LIBELF
 	bool
 
+config DT_CPU_TOPOLOGY
+	bool "Device tree based CPU topology support (UNSUPPORTED)" if UNSUPPORTED
+	depends on HAS_DEVICE_TREE_DISCOVERY
+	help
+	  Retrieve CPU topology information from the device tree to optimize
+	  virtual CPU scheduling.
+
 config NUMA
 	bool
 
diff --git a/xen/common/device-tree/Makefile b/xen/common/device-tree/Makefile
index 9036e455d6..38bc5d5306 100644
--- a/xen/common/device-tree/Makefile
+++ b/xen/common/device-tree/Makefile
@@ -1,6 +1,7 @@
 obj-y += bootfdt.init.o
 obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += bootinfo-fdt.init.o
 obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += bootinfo.init.o
+obj-$(CONFIG_DT_CPU_TOPOLOGY) += cpu-topology.o
 obj-y += device-tree.o
 obj-$(CONFIG_DOMAIN_BUILD_HELPERS) += domain-build.init.o
 obj-$(filter $(CONFIG_DOM0LESS_BOOT),$(CONFIG_HAS_DEVICE_TREE_DISCOVERY)) += dom0less-build.init.o
diff --git a/xen/common/device-tree/cpu-topology.c b/xen/common/device-tree/cpu-topology.c
new file mode 100644
index 0000000000..bbdf0d1fe8
--- /dev/null
+++ b/xen/common/device-tree/cpu-topology.c
@@ -0,0 +1,342 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Derived from Linux kernel 7.0's $drivers/base/arch_topology.c
+ * Parse cpu topology information.
+ *
+ * Copyright (c) 2026 VA Linux Systems Japan K.K.
+ * Author: Hirokazu Takahashi <taka@valinux.co.jp>
+ */
+
+#include <xen/cpu.h>
+#include <xen/cpumask.h>
+#include <xen/delay.h>
+#include <xen/device_tree.h>
+#include <xen/cpu-topology.h>
+#include <xen/numa.h>
+#include <xen/domain_page.h>
+#include <xen/errno.h>
+#include <xen/init.h>
+
+struct cpu_map {
+    unsigned int thread_id;
+    unsigned int core_id;
+    unsigned int cluster_id;
+    unsigned int package_id;
+};
+
+struct cpu_topology *cpu_topology;
+static struct cpu_map __initdata cpu_map[NR_CPUS] = {
+    [0 ... NR_CPUS-1] = {~0U, ~0U, ~0U, 0U}
+};
+static struct dt_device_node * __initdata dt_cpu_table[NR_CPUS];
+static const unsigned int __initdata invalid_topo_id = (~0U);
+
+static void __init setup_siblings_masks(unsigned int cpuid)
+{
+    struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
+    struct cpu_map *cpuid_map = &cpu_map[cpuid];
+    unsigned int cpu;
+
+    /* Update core and thread sibling masks */
+    for_each_possible_cpu( cpu )
+    {
+        struct cpu_topology *cpu_topo = &cpu_topology[cpu];
+        struct cpu_map *map = &cpu_map[cpu];
+
+        if ( cpuid_map->package_id != map->package_id )
+            continue;
+
+        cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
+        cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
+
+        if ( cpuid_map->cluster_id != map->cluster_id )
+            continue;
+
+        if ( cpuid_map->cluster_id != invalid_topo_id )
+        {
+            cpumask_set_cpu(cpu, &cpuid_topo->cluster_sibling);
+            cpumask_set_cpu(cpuid, &cpu_topo->cluster_sibling);
+        }
+
+        if ( cpuid_map->core_id != map->core_id )
+            continue;
+
+        cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
+        cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
+    }
+}
+
+static struct dt_device_node * __init dt_find_child_node_by_name(struct dt_device_node *from, const char *name)
+{
+    struct dt_device_node *np;
+    const struct dt_device_node *dt = from;
+
+    dt_for_each_child_node( dt, np )
+        if ( np->name && (dt_node_cmp(np->name, name) == 0) )
+            break;
+
+    return np;
+}
+
+void __init map_cpuid_to_node(unsigned int cpuid, struct dt_device_node *cpu_node)
+{
+    if ( cpuid < NR_CPUS )
+        dt_cpu_table[cpuid] = cpu_node;
+}
+
+static unsigned int __init cpu_node_to_id(struct dt_device_node *cpu_node)
+{
+    unsigned int cpu;
+    bool found = false;
+
+    for_each_possible_cpu( cpu )
+    {
+        found = (cpu_node == dt_cpu_table[cpu]);
+        if ( found )
+            return cpu;
+    }
+
+    return invalid_topo_id;
+}
+
+/*
+ * This function returns the logic cpu number of the node.
+ */
+static unsigned int __init get_cpu_for_node(struct dt_device_node *node)
+{
+    struct dt_device_node *cpu_node = dt_parse_phandle(node, "cpu", 0);
+
+    if ( !cpu_node )
+        return invalid_topo_id;
+
+    return cpu_node_to_id(cpu_node);
+}
+
+static int __init parse_core(struct dt_device_node *core,
+                unsigned int package_id, unsigned int cluster_id,
+                unsigned int core_id)
+{
+    char name[20];
+    bool leaf = true;
+    unsigned int i = 0U;
+    unsigned int cpu;
+
+    do {
+        struct dt_device_node *t;
+
+        snprintf(name, sizeof(name), "thread%u", i);
+        t = dt_find_child_node_by_name(core, name);
+
+        if ( !t )
+            break;
+
+        leaf = false;
+        cpu = get_cpu_for_node(t);
+        if ( cpu != invalid_topo_id )
+        {
+            cpu_map[cpu].package_id = package_id;
+            cpu_map[cpu].cluster_id = cluster_id;
+            cpu_map[cpu].core_id = core_id;
+            cpu_map[cpu].thread_id = i;
+        }
+        else
+        {
+            printk(XENLOG_ERR "ERROR: %pOF: Can't get CPU for thread\n", t);
+            return -EINVAL;
+        }
+        i++;
+    } while ( true );
+
+    cpu = get_cpu_for_node(core);
+
+    if ( cpu != invalid_topo_id )
+    {
+        if ( !leaf )
+        {
+            printk(XENLOG_ERR "ERROR: %pOF: Core has both threads and CPU\n",
+                   core);
+            return -EINVAL;
+        }
+
+        cpu_map[cpu].package_id = package_id;
+        cpu_map[cpu].cluster_id = cluster_id;
+        cpu_map[cpu].core_id = core_id;
+        cpu_map[cpu].thread_id = 0U;
+    }
+    else if ( leaf )
+    {
+        printk(XENLOG_ERR "ERROR: %pOF: Can't get CPU for leaf core\n", core);
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+static int __init parse_cluster(struct dt_device_node *cluster,
+                unsigned int package_id, unsigned int cluster_id,
+                unsigned int depth)
+{
+    char name[20];
+    bool leaf = true;
+    bool has_cores = false;
+    unsigned int core_id = 0U;
+    unsigned int i;
+    int ret;
+
+    /*
+     * First check for child clusters; we currently ignore any
+     * information about the nesting of clusters and present the
+     * scheduler with a flat list of them.
+     */
+    i = 0U;
+    do {
+        struct dt_device_node *c;
+
+        snprintf(name, sizeof(name), "cluster%u", i);
+        c = dt_find_child_node_by_name(cluster, name);
+
+        if ( !c )
+            break;
+
+        leaf = false;
+        ret = parse_cluster(c, package_id, i, depth + 1U);
+        if ( depth > 0U )
+            printk(XENLOG_WARNING "WARNING: Topology for clusters of clusters not yet supported\n");
+        if ( ret != 0 )
+            return ret;
+        i++;
+    } while ( true );
+
+    /* Now check for cores */
+    i = 0U;
+    do {
+        struct dt_device_node *c;
+
+        snprintf(name, sizeof(name), "core%u", i);
+        c = dt_find_child_node_by_name(cluster, name);
+
+        if ( !c )
+            break;
+
+        has_cores = true;
+
+        if ( depth == 0U )
+        {
+            printk(XENLOG_ERR "ERROR: %pOF: cpu-map children should be clusters\n", c);
+            return -EINVAL;
+        }
+
+        if ( leaf )
+        {
+            ret = parse_core(c, package_id, cluster_id, core_id++);
+            if ( ret != 0 )
+                return ret;
+        }
+        else
+        {
+            printk(XENLOG_ERR "ERROR: %pOF: Non-leaf cluster with core %s\n",
+                   cluster, name);
+            return -EINVAL;
+        }
+
+        i++;
+    } while ( true );
+
+    if ( leaf && !has_cores )
+        printk(XENLOG_WARNING "WARNING: %pOF: empty cluster\n", cluster);
+
+    return 0;
+}
+
+static int __init parse_socket(struct dt_device_node *socket)
+{
+    char name[20];
+    bool has_socket = false;
+    unsigned int package_id = 0U;
+    int ret;
+
+    do {
+        struct dt_device_node *c;
+
+        snprintf(name, sizeof(name), "socket%u", package_id);
+        c = dt_find_child_node_by_name(socket, name);
+
+        if ( !c )
+            break;
+
+        has_socket = true;
+        ret = parse_cluster(c, package_id, invalid_topo_id, 0U);
+        if ( ret != 0 )
+            return ret;
+
+        package_id++;
+    } while ( true );
+
+    if ( !has_socket )
+        ret = parse_cluster(socket, 0U, invalid_topo_id, 0U);
+
+    return ret;
+}
+
+/*
+ * Generate cpu topology information when cpu-map node doesn't exist.
+ * It assumes that the cpu doesn't have SMT and all CPUs on a NUMA
+ * node belong to the same socket.
+ */
+static void __init fixup_topology(void)
+{
+    unsigned int cpu;
+    unsigned int clid = 0U;
+    unsigned int pkgid = 0U;
+
+    for_each_possible_cpu( cpu )
+    {
+        struct cpu_map *map = &cpu_map[cpu];
+
+        map->package_id = cpu_to_node(cpu);
+        if ( map->package_id != pkgid )
+        {
+            pkgid = map->package_id;
+            clid = 0U;
+        }
+        map->cluster_id = clid++;
+        map->core_id = 0U;
+        map->thread_id = 0U;
+    }
+}
+
+int __init parse_dt_topology(void)
+{
+    struct dt_device_node *cpus;
+    struct dt_device_node *map;
+
+    cpus = dt_find_node_by_path("/cpus");
+
+    if ( !cpus )
+    {
+        printk(XENLOG_ERR "ERROR: No CPU information found in DT\n");
+        return -EINVAL;
+    }
+
+    map = dt_find_child_node_by_name(cpus, "cpu-map");
+    if ( !map )
+        return -ENOENT;
+
+    return parse_socket(map);
+}
+
+void __init dt_init_cpu_topology(void)
+{
+    unsigned int cpu;
+    const unsigned int nr_cpus = cpumask_last(&cpu_possible_map) + 1U;
+
+    cpu_topology = xzalloc_array(struct cpu_topology, nr_cpus);
+    if ( !cpu_topology )
+        panic("Failed to allocate memory for cpu_topology array\n");
+
+    if (parse_dt_topology())
+        fixup_topology();
+
+    for_each_possible_cpu( cpu )
+        setup_siblings_masks(cpu);
+}
diff --git a/xen/include/xen/cpu-topology.h b/xen/include/xen/cpu-topology.h
new file mode 100644
index 0000000000..1c03f4deaa
--- /dev/null
+++ b/xen/include/xen/cpu-topology.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef XEN_CPU_TOPOLOGY_H
+#define XEN_CPU_TOPOLOGY_H
+
+#include <xen/types.h>
+#include <xen/device_tree.h>
+
+struct cpu_topology {
+    cpumask_t thread_sibling;
+    cpumask_t core_sibling;
+    cpumask_t cluster_sibling;
+};
+
+
+#ifdef CONFIG_DT_CPU_TOPOLOGY
+
+extern struct cpu_topology *cpu_topology;
+void map_cpuid_to_node(unsigned int cpuid, struct dt_device_node *cpu_node);
+void dt_init_cpu_topology(void);
+
+#elif CONFIG_DEVICE_TREE_PARSE
+
+static inline void map_cpuid_to_node(unsigned int cpuid, struct dt_device_node *cpu_node) {}
+static inline void dt_init_cpu_topology(void) {}
+
+#endif /* CONFIG_DEVICE_TREE_PARSE */
+
+#endif /* XEN_CPU_TOPOLOGY_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH 2/3] xen/sched: Link CPU topology to scheduler
  2026-06-10 11:13 [PATCH 0/3] xen/arm: Device Tree based CPU topology support Hirokazu Takahashi
  2026-06-10 11:13 ` [PATCH 1/3] xen/device-tree: Parse 'cpu-map' node for CPU topology exploration Hirokazu Takahashi
@ 2026-06-10 11:13 ` Hirokazu Takahashi
  2026-06-11 14:12   ` Jan Beulich
  2026-06-11 22:23   ` Julien Grall
  2026-06-10 11:13 ` [PATCH 3/3] xen/sched: Make cpu_nr_siblings() architecture-specific Hirokazu Takahashi
  2 siblings, 2 replies; 16+ messages in thread
From: Hirokazu Takahashi @ 2026-06-10 11:13 UTC (permalink / raw)
  To: xen-devel
  Cc: Mykyta_Poturai, Hirokazu Takahashi, Stefano Stabellini,
	Julien Grall, Bertrand Marquis, Michal Orzel, Volodymyr Babchuk,
	Andrew Cooper, Anthony PERARD, Jan Beulich, Roger Pau Monné,
	Dario Faggioli, Juergen Gross, George Dunlap

Make CPU topology information available to the Xen scheduler.
Additionally, ensure that this topology information is displayed
when executing the 'xl info -n' command.

Signed-off-by: Hirokazu Takahashi <taka@valinux.co.jp>
---
 xen/arch/arm/include/asm/processor.h  |  4 ---
 xen/arch/arm/smpboot.c                | 10 ++++--
 xen/common/device-tree/cpu-topology.c | 51 +++++++++++++++++++++++++++
 xen/common/sched/credit2.c            |  3 ++
 xen/common/sysctl.c                   |  1 +
 xen/include/xen/cpu-topology.h        | 10 ++++++
 6 files changed, 72 insertions(+), 7 deletions(-)

diff --git a/xen/arch/arm/include/asm/processor.h b/xen/arch/arm/include/asm/processor.h
index a3753c317f..41fa73cfc4 100644
--- a/xen/arch/arm/include/asm/processor.h
+++ b/xen/arch/arm/include/asm/processor.h
@@ -613,10 +613,6 @@ void show_stack(const struct cpu_user_regs *regs);
 
 #define cpu_relax() barrier() /* Could yield? */
 
-/* All a bit UP for the moment */
-#define cpu_to_core(_cpu)   (0)
-#define cpu_to_socket(_cpu) (0)
-
 struct vcpu;
 void vcpu_regs_hyp_to_user(const struct vcpu *vcpu,
                            struct vcpu_guest_core_regs *regs);
diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
index c071f1494f..b25d98c109 100644
--- a/xen/arch/arm/smpboot.c
+++ b/xen/arch/arm/smpboot.c
@@ -91,13 +91,17 @@ static int setup_cpu_sibling_map(int cpu)
          !zalloc_cpumask_var(&per_cpu(cpu_core_mask, cpu)) )
         return -ENOMEM;
 
+#ifdef CONFIG_DT_CPU_TOPOLOGY
+    cpumask_copy(per_cpu(cpu_sibling_mask, cpu), &cpu_topology[cpu].thread_sibling);
+    cpumask_copy(per_cpu(cpu_core_mask, cpu), &cpu_topology[cpu].core_sibling);
+#else /* CONFIG_DT_CPU_TOPOLOGY */
     /*
-     * Currently we assume there is no multithread and NUMA, so
-     * a CPU is a sibling with itself, and the all possible CPUs
-     * are supposed to belong to the same socket (NUMA node).
+     * If CONFIG_DT_CPU_TOPOLOGY is disabled, it is assumed that
+     * all CPUs reside in the same socket and that SMT is not used.
      */
     cpumask_set_cpu(cpu, per_cpu(cpu_sibling_mask, cpu));
     cpumask_copy(per_cpu(cpu_core_mask, cpu), &cpu_possible_map);
+#endif /* CONFIG_DT_CPU_TOPOLOGY */
 
     return 0;
 }
diff --git a/xen/common/device-tree/cpu-topology.c b/xen/common/device-tree/cpu-topology.c
index bbdf0d1fe8..7b6c918139 100644
--- a/xen/common/device-tree/cpu-topology.c
+++ b/xen/common/device-tree/cpu-topology.c
@@ -325,6 +325,55 @@ int __init parse_dt_topology(void)
     return parse_socket(map);
 }
 
+static void __init setup_cpu_topology_ids(void)
+{
+    unsigned int cpu;
+    unsigned int next_core_id = 0U;
+    unsigned int next_cluster_id = 0U;
+    unsigned int next_socket_id = 0U;
+
+    for_each_possible_cpu( cpu )
+    {
+        unsigned int first_cpu;
+        struct cpu_topology *topo = &cpu_topology[cpu];
+
+        first_cpu = cpumask_first(&topo->thread_sibling);
+        if ( first_cpu == cpu )
+        {
+            topo->phys_core_id = next_core_id;
+            next_core_id++;
+        }
+        else
+        {
+            topo->phys_core_id = cpu_topology[first_cpu].phys_core_id;
+        }
+
+        first_cpu = cpumask_first(&topo->cluster_sibling);
+        if ( first_cpu == cpu )
+        {
+            topo->phys_cluster_id = next_cluster_id;
+            next_cluster_id++;
+        }
+        else
+        {
+            topo->phys_cluster_id = cpu_topology[first_cpu].phys_cluster_id;
+        }
+
+        first_cpu = cpumask_first(&topo->core_sibling);
+        if ( first_cpu == cpu )
+        {
+            topo->phys_socket_id = next_socket_id;
+            next_socket_id++;
+        }
+        else
+        {
+            topo->phys_socket_id = cpu_topology[first_cpu].phys_socket_id;
+        }
+
+        topo->num_siblings = cpumask_weight(&topo->thread_sibling);
+    }
+}
+
 void __init dt_init_cpu_topology(void)
 {
     unsigned int cpu;
@@ -339,4 +388,6 @@ void __init dt_init_cpu_topology(void)
 
     for_each_possible_cpu( cpu )
         setup_siblings_masks(cpu);
+
+    setup_cpu_topology_ids();
 }
diff --git a/xen/common/sched/credit2.c b/xen/common/sched/credit2.c
index 77475ee363..dcce1e361f 100644
--- a/xen/common/sched/credit2.c
+++ b/xen/common/sched/credit2.c
@@ -19,6 +19,7 @@
 #include <xen/softirq.h>
 #include <xen/time.h>
 #include <xen/trace.h>
+#include <xen/cpu-topology.h>
 
 #include <asm/div64.h>
 
@@ -37,6 +38,8 @@ static unsigned int cpu_nr_siblings(unsigned int cpu)
 {
 #ifdef CONFIG_X86
     return cpu_data[cpu].x86_num_siblings;
+#elif CONFIG_DT_CPU_TOPOLOGY
+    return cpu_topology[cpu].num_siblings;
 #else
     return 1;
 #endif
diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c
index 5207664252..81a68fe24c 100644
--- a/xen/common/sysctl.c
+++ b/xen/common/sysctl.c
@@ -28,6 +28,7 @@
 #include <xen/pmstat.h>
 #include <xen/livepatch.h>
 #include <xen/coverage.h>
+#include <xen/cpu-topology.h>
 
 long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
 {
diff --git a/xen/include/xen/cpu-topology.h b/xen/include/xen/cpu-topology.h
index 1c03f4deaa..f268069449 100644
--- a/xen/include/xen/cpu-topology.h
+++ b/xen/include/xen/cpu-topology.h
@@ -10,6 +10,10 @@ struct cpu_topology {
     cpumask_t thread_sibling;
     cpumask_t core_sibling;
     cpumask_t cluster_sibling;
+    unsigned int phys_core_id;
+    unsigned int phys_cluster_id;
+    unsigned int phys_socket_id;
+    unsigned int num_siblings;
 };
 
 
@@ -19,11 +23,17 @@ extern struct cpu_topology *cpu_topology;
 void map_cpuid_to_node(unsigned int cpuid, struct dt_device_node *cpu_node);
 void dt_init_cpu_topology(void);
 
+#define cpu_to_core(_cpu)   (cpu_topology[_cpu].phys_core_id)
+#define cpu_to_socket(_cpu)   (cpu_topology[_cpu].phys_socket_id)
+
 #elif CONFIG_DEVICE_TREE_PARSE
 
 static inline void map_cpuid_to_node(unsigned int cpuid, struct dt_device_node *cpu_node) {}
 static inline void dt_init_cpu_topology(void) {}
 
+#define cpu_to_core(_cpu)   (0)
+#define cpu_to_socket(_cpu) (0)
+
 #endif /* CONFIG_DEVICE_TREE_PARSE */
 
 #endif /* XEN_CPU_TOPOLOGY_H */
-- 
2.43.0



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

* [PATCH 3/3] xen/sched: Make cpu_nr_siblings() architecture-specific
  2026-06-10 11:13 [PATCH 0/3] xen/arm: Device Tree based CPU topology support Hirokazu Takahashi
  2026-06-10 11:13 ` [PATCH 1/3] xen/device-tree: Parse 'cpu-map' node for CPU topology exploration Hirokazu Takahashi
  2026-06-10 11:13 ` [PATCH 2/3] xen/sched: Link CPU topology to scheduler Hirokazu Takahashi
@ 2026-06-10 11:13 ` Hirokazu Takahashi
  2026-06-11 14:14   ` Jan Beulich
  2026-06-11 22:37   ` Andrew Cooper
  2 siblings, 2 replies; 16+ messages in thread
From: Hirokazu Takahashi @ 2026-06-10 11:13 UTC (permalink / raw)
  To: xen-devel
  Cc: Mykyta_Poturai, Hirokazu Takahashi, Jan Beulich, Andrew Cooper,
	Roger Pau Monné, Teddy Astie, Anthony PERARD, Michal Orzel,
	Julien Grall, Stefano Stabellini, Dario Faggioli, Juergen Gross,
	George Dunlap

Make cpu_nr_siblings() an architecture-specific function.
This patch provides the implementation for x86 and a common
version for Device Tree-based architectures.

Signed-off-by: Hirokazu Takahashi <taka@valinux.co.jp>
---
 xen/arch/x86/include/asm/processor.h |  1 +
 xen/common/sched/credit2.c           | 23 +++++------------------
 xen/include/xen/cpu-topology.h       |  2 ++
 3 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/xen/arch/x86/include/asm/processor.h b/xen/arch/x86/include/asm/processor.h
index 8ca6799a81..9758060129 100644
--- a/xen/arch/x86/include/asm/processor.h
+++ b/xen/arch/x86/include/asm/processor.h
@@ -106,6 +106,7 @@ extern void intel_init_arat(void);
 
 #define cpu_to_core(_cpu)   (cpu_data[_cpu].cpu_core_id)
 #define cpu_to_socket(_cpu) (cpu_data[_cpu].phys_proc_id)
+#define cpu_nr_siblings(_cpu) (cpu_data[_cpu].x86_num_siblings)
 
 unsigned int apicid_to_socket(unsigned int apicid);
 
diff --git a/xen/common/sched/credit2.c b/xen/common/sched/credit2.c
index dcce1e361f..2d93944824 100644
--- a/xen/common/sched/credit2.c
+++ b/xen/common/sched/credit2.c
@@ -29,22 +29,6 @@
 /* #define d2printk printk */
 #define d2printk(x...)
 
-/*
- * TODO: Abstract this properly, and figure out what Credit2 wants to do with
- *       the fact that x86_num_siblings doesn't even have the same meaning
- *       between x86 vendors.
- */
-static unsigned int cpu_nr_siblings(unsigned int cpu)
-{
-#ifdef CONFIG_X86
-    return cpu_data[cpu].x86_num_siblings;
-#elif CONFIG_DT_CPU_TOPOLOGY
-    return cpu_topology[cpu].num_siblings;
-#else
-    return 1;
-#endif
-}
-
 /*
  * Credit2 tracing events ("only" 512 available!). Check
  * include/public/trace.h for more details.
@@ -884,8 +868,11 @@ cpu_runqueue_match(const struct csched2_runqueue_data *rqd, unsigned int cpu)
  * Additional checks, to avoid separating siblings in different runqueues.
  * This deals with both Intel's HTs and AMD's CUs. An arch that does not have
  * any similar concept will just have cpu_nr_siblings() always return 1, and
- * setup the cpu_sibling_mask-s acordingly (as currently does ARM), and things
- * will just work as well.
+ * setup the cpu_sibling_mask-s acordingly, and things will just work as well.
+ *
+ * TODO: Abstract cpu_nr_siblings properly, and figure out what Credit2 wants
+ *       to do with the fact that x86_num_siblings doesn't even have the same
+ *       meaning between x86 vendors.
  */
 static bool
 cpu_runqueue_siblings_match(const struct csched2_runqueue_data *rqd,
diff --git a/xen/include/xen/cpu-topology.h b/xen/include/xen/cpu-topology.h
index f268069449..ea5518bb16 100644
--- a/xen/include/xen/cpu-topology.h
+++ b/xen/include/xen/cpu-topology.h
@@ -25,6 +25,7 @@ void dt_init_cpu_topology(void);
 
 #define cpu_to_core(_cpu)   (cpu_topology[_cpu].phys_core_id)
 #define cpu_to_socket(_cpu)   (cpu_topology[_cpu].phys_socket_id)
+#define cpu_nr_siblings(_cpu) (cpu_topology[_cpu].num_siblings)
 
 #elif CONFIG_DEVICE_TREE_PARSE
 
@@ -33,6 +34,7 @@ static inline void dt_init_cpu_topology(void) {}
 
 #define cpu_to_core(_cpu)   (0)
 #define cpu_to_socket(_cpu) (0)
+#define cpu_nr_siblings(_cpu) (1)
 
 #endif /* CONFIG_DEVICE_TREE_PARSE */
 
-- 
2.43.0



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

* Re: [PATCH 1/3] xen/device-tree: Parse 'cpu-map' node for CPU topology exploration
  2026-06-10 11:13 ` [PATCH 1/3] xen/device-tree: Parse 'cpu-map' node for CPU topology exploration Hirokazu Takahashi
@ 2026-06-11 14:06   ` Jan Beulich
  2026-06-12  2:29     ` Hirokazu Takahashi
  2026-06-11 22:35   ` Julien Grall
  1 sibling, 1 reply; 16+ messages in thread
From: Jan Beulich @ 2026-06-11 14:06 UTC (permalink / raw)
  To: Hirokazu Takahashi
  Cc: Mykyta_Poturai, Stefano Stabellini, Julien Grall,
	Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper,
	Anthony PERARD, Roger Pau Monné, xen-devel

On 10.06.2026 13:13, Hirokazu Takahashi wrote:
> --- /dev/null
> +++ b/xen/include/xen/cpu-topology.h

The name of the new file does not in any way ...

> @@ -0,0 +1,38 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef XEN_CPU_TOPOLOGY_H
> +#define XEN_CPU_TOPOLOGY_H
> +
> +#include <xen/types.h>
> +#include <xen/device_tree.h>
> +
> +struct cpu_topology {
> +    cpumask_t thread_sibling;
> +    cpumask_t core_sibling;
> +    cpumask_t cluster_sibling;
> +};
> +
> +
> +#ifdef CONFIG_DT_CPU_TOPOLOGY
> +
> +extern struct cpu_topology *cpu_topology;
> +void map_cpuid_to_node(unsigned int cpuid, struct dt_device_node *cpu_node);
> +void dt_init_cpu_topology(void);

... express this is all about DT stuff. Is this intentional? Else it
may want adjusting.

> +#elif CONFIG_DEVICE_TREE_PARSE

DYM "#elif defined(CONFIG_DEVICE_TREE_PARSE)"?

Jan


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

* Re: [PATCH 2/3] xen/sched: Link CPU topology to scheduler
  2026-06-10 11:13 ` [PATCH 2/3] xen/sched: Link CPU topology to scheduler Hirokazu Takahashi
@ 2026-06-11 14:12   ` Jan Beulich
  2026-06-12 19:53     ` Hirokazu Takahashi
  2026-06-11 22:23   ` Julien Grall
  1 sibling, 1 reply; 16+ messages in thread
From: Jan Beulich @ 2026-06-11 14:12 UTC (permalink / raw)
  To: Hirokazu Takahashi
  Cc: Mykyta_Poturai, Stefano Stabellini, Julien Grall,
	Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper,
	Anthony PERARD, Roger Pau Monné, Dario Faggioli,
	Juergen Gross, George Dunlap, xen-devel

On 10.06.2026 13:13, Hirokazu Takahashi wrote:
> Make CPU topology information available to the Xen scheduler.
> Additionally, ensure that this topology information is displayed
> when executing the 'xl info -n' command.

Both in title and description you're pretty generic, yet then ...

>  xen/arch/arm/include/asm/processor.h  |  4 ---
>  xen/arch/arm/smpboot.c                | 10 ++++--
>  xen/common/device-tree/cpu-topology.c | 51 +++++++++++++++++++++++++++
>  xen/common/sched/credit2.c            |  3 ++
>  xen/common/sysctl.c                   |  1 +
>  xen/include/xen/cpu-topology.h        | 10 ++++++
>  6 files changed, 72 insertions(+), 7 deletions(-)

... only the credit2 scheduler is actually enabled.
> --- a/xen/common/device-tree/cpu-topology.c
> +++ b/xen/common/device-tree/cpu-topology.c
> @@ -325,6 +325,55 @@ int __init parse_dt_topology(void)
>      return parse_socket(map);
>  }
>  
> +static void __init setup_cpu_topology_ids(void)
> +{
> +    unsigned int cpu;
> +    unsigned int next_core_id = 0U;
> +    unsigned int next_cluster_id = 0U;
> +    unsigned int next_socket_id = 0U;
> +
> +    for_each_possible_cpu( cpu )

Nit (style): Either you deem for_each_possible_cpu a (pseudo-)keyword
(then there's a blank missing) or you don't (then there are excess
blanks).

> +    {
> +        unsigned int first_cpu;
> +        struct cpu_topology *topo = &cpu_topology[cpu];
> +
> +        first_cpu = cpumask_first(&topo->thread_sibling);
> +        if ( first_cpu == cpu )
> +        {
> +            topo->phys_core_id = next_core_id;
> +            next_core_id++;
> +        }
> +        else
> +        {
> +            topo->phys_core_id = cpu_topology[first_cpu].phys_core_id;
> +        }

Nit, here and below: Please omit unnecessary figure braces.

> @@ -339,4 +388,6 @@ void __init dt_init_cpu_topology(void)
>  
>      for_each_possible_cpu( cpu )
>          setup_siblings_masks(cpu);
As to the earlier remark: Bad pre-existing examples don't count.

> @@ -19,11 +23,17 @@ extern struct cpu_topology *cpu_topology;
>  void map_cpuid_to_node(unsigned int cpuid, struct dt_device_node *cpu_node);
>  void dt_init_cpu_topology(void);
>  
> +#define cpu_to_core(_cpu)   (cpu_topology[_cpu].phys_core_id)
> +#define cpu_to_socket(_cpu)   (cpu_topology[_cpu].phys_socket_id)

Please can you avoid introducing new name space violations (identifiers
with leading underscores should name file scope entities); also again
below.

Jan


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

* Re: [PATCH 3/3] xen/sched: Make cpu_nr_siblings() architecture-specific
  2026-06-10 11:13 ` [PATCH 3/3] xen/sched: Make cpu_nr_siblings() architecture-specific Hirokazu Takahashi
@ 2026-06-11 14:14   ` Jan Beulich
  2026-06-12 21:06     ` Hirokazu Takahashi
  2026-06-11 22:37   ` Andrew Cooper
  1 sibling, 1 reply; 16+ messages in thread
From: Jan Beulich @ 2026-06-11 14:14 UTC (permalink / raw)
  To: Hirokazu Takahashi
  Cc: Mykyta_Poturai, Andrew Cooper, Roger Pau Monné, Teddy Astie,
	Anthony PERARD, Michal Orzel, Julien Grall, Stefano Stabellini,
	Dario Faggioli, Juergen Gross, George Dunlap, xen-devel

On 10.06.2026 13:13, Hirokazu Takahashi wrote:
> --- a/xen/common/sched/credit2.c
> +++ b/xen/common/sched/credit2.c
> @@ -29,22 +29,6 @@
>  /* #define d2printk printk */
>  #define d2printk(x...)
>  
> -/*
> - * TODO: Abstract this properly, and figure out what Credit2 wants to do with
> - *       the fact that x86_num_siblings doesn't even have the same meaning
> - *       between x86 vendors.
> - */
> -static unsigned int cpu_nr_siblings(unsigned int cpu)
> -{
> -#ifdef CONFIG_X86
> -    return cpu_data[cpu].x86_num_siblings;
> -#elif CONFIG_DT_CPU_TOPOLOGY
> -    return cpu_topology[cpu].num_siblings;
> -#else
> -    return 1;
> -#endif
> -}
> -
>  /*
>   * Credit2 tracing events ("only" 512 available!). Check
>   * include/public/trace.h for more details.
> @@ -884,8 +868,11 @@ cpu_runqueue_match(const struct csched2_runqueue_data *rqd, unsigned int cpu)
>   * Additional checks, to avoid separating siblings in different runqueues.
>   * This deals with both Intel's HTs and AMD's CUs. An arch that does not have
>   * any similar concept will just have cpu_nr_siblings() always return 1, and
> - * setup the cpu_sibling_mask-s acordingly (as currently does ARM), and things
> - * will just work as well.
> + * setup the cpu_sibling_mask-s acordingly, and things will just work as well.
> + *
> + * TODO: Abstract cpu_nr_siblings properly, and figure out what Credit2 wants
> + *       to do with the fact that x86_num_siblings doesn't even have the same
> + *       meaning between x86 vendors.

Hmm, the "abstract properly" part is being addressed by this patch. Why would
you keep saying it needs addressing in the comment you move?

Jan


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

* Re: [PATCH 2/3] xen/sched: Link CPU topology to scheduler
  2026-06-10 11:13 ` [PATCH 2/3] xen/sched: Link CPU topology to scheduler Hirokazu Takahashi
  2026-06-11 14:12   ` Jan Beulich
@ 2026-06-11 22:23   ` Julien Grall
  1 sibling, 0 replies; 16+ messages in thread
From: Julien Grall @ 2026-06-11 22:23 UTC (permalink / raw)
  To: Hirokazu Takahashi, xen-devel
  Cc: Mykyta_Poturai, Stefano Stabellini, Bertrand Marquis,
	Michal Orzel, Volodymyr Babchuk, Andrew Cooper, Anthony PERARD,
	Jan Beulich, Roger Pau Monné, Dario Faggioli, Juergen Gross,
	George Dunlap

Hi,

On 10/06/2026 12:13, Hirokazu Takahashi wrote:
> Make CPU topology information available to the Xen scheduler.
> Additionally, ensure that this topology information is displayed
> when executing the 'xl info -n' command.
> 
> Signed-off-by: Hirokazu Takahashi <taka@valinux.co.jp>
> ---
>   xen/arch/arm/include/asm/processor.h  |  4 ---
>   xen/arch/arm/smpboot.c                | 10 ++++--
>   xen/common/device-tree/cpu-topology.c | 51 +++++++++++++++++++++++++++
>   xen/common/sched/credit2.c            |  3 ++
>   xen/common/sysctl.c                   |  1 +
>   xen/include/xen/cpu-topology.h        | 10 ++++++
>   6 files changed, 72 insertions(+), 7 deletions(-)
> 
> diff --git a/xen/arch/arm/include/asm/processor.h b/xen/arch/arm/include/asm/processor.h
> index a3753c317f..41fa73cfc4 100644
> --- a/xen/arch/arm/include/asm/processor.h
> +++ b/xen/arch/arm/include/asm/processor.h
> @@ -613,10 +613,6 @@ void show_stack(const struct cpu_user_regs *regs);
>   
>   #define cpu_relax() barrier() /* Could yield? */
>   
> -/* All a bit UP for the moment */
> -#define cpu_to_core(_cpu)   (0)
> -#define cpu_to_socket(_cpu) (0)
> -
>   struct vcpu;
>   void vcpu_regs_hyp_to_user(const struct vcpu *vcpu,
>                              struct vcpu_guest_core_regs *regs);
> diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
> index c071f1494f..b25d98c109 100644
> --- a/xen/arch/arm/smpboot.c
> +++ b/xen/arch/arm/smpboot.c
> @@ -91,13 +91,17 @@ static int setup_cpu_sibling_map(int cpu)
>            !zalloc_cpumask_var(&per_cpu(cpu_core_mask, cpu)) )
>           return -ENOMEM;
>   
> +#ifdef CONFIG_DT_CPU_TOPOLOGY

For Arm, we support both ACPI and Device-Tree in a single binary. That's 
fine if we don't support NUMA with ACPI for now, but we need to make 
sure this doesn't regress for now.

With that in mind, I was expecting some runtime checks based on whether 
ACPI or DT is used. Can you explain why this is not the case?

Cheers,

-- 
Julien Grall



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

* Re: [PATCH 1/3] xen/device-tree: Parse 'cpu-map' node for CPU topology exploration
  2026-06-10 11:13 ` [PATCH 1/3] xen/device-tree: Parse 'cpu-map' node for CPU topology exploration Hirokazu Takahashi
  2026-06-11 14:06   ` Jan Beulich
@ 2026-06-11 22:35   ` Julien Grall
  2026-06-14  0:00     ` Hirokazu Takahashi
  1 sibling, 1 reply; 16+ messages in thread
From: Julien Grall @ 2026-06-11 22:35 UTC (permalink / raw)
  To: Hirokazu Takahashi, xen-devel
  Cc: Mykyta_Poturai, Stefano Stabellini, Bertrand Marquis,
	Michal Orzel, Volodymyr Babchuk, Andrew Cooper, Anthony PERARD,
	Jan Beulich, Roger Pau Monné

Hi,

On 10/06/2026 12:13, Hirokazu Takahashi wrote:
> diff --git a/xen/common/device-tree/Makefile b/xen/common/device-tree/Makefile
> index 9036e455d6..38bc5d5306 100644
> --- a/xen/common/device-tree/Makefile
> +++ b/xen/common/device-tree/Makefile
> @@ -1,6 +1,7 @@
>   obj-y += bootfdt.init.o
>   obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += bootinfo-fdt.init.o
>   obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += bootinfo.init.o
> +obj-$(CONFIG_DT_CPU_TOPOLOGY) += cpu-topology.o
>   obj-y += device-tree.o
>   obj-$(CONFIG_DOMAIN_BUILD_HELPERS) += domain-build.init.o
>   obj-$(filter $(CONFIG_DOM0LESS_BOOT),$(CONFIG_HAS_DEVICE_TREE_DISCOVERY)) += dom0less-build.init.o
> diff --git a/xen/common/device-tree/cpu-topology.c b/xen/common/device-tree/cpu-topology.c
> new file mode 100644
> index 0000000000..bbdf0d1fe8
> --- /dev/null
> +++ b/xen/common/device-tree/cpu-topology.c
> @@ -0,0 +1,342 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Derived from Linux kernel 7.0's $drivers/base/arch_topology.c
> + * Parse cpu topology information.
> + *
> + * Copyright (c) 2026 VA Linux Systems Japan K.K.
> + * Author: Hirokazu Takahashi <taka@valinux.co.jp>

We don't commonly have copyright header in the tree and instead use the 
commit message to keep track of Copyright. That said, if you want to 
keep it, I think you ought to keep the copyright from Linux because your 
code is based on it.

> + */
> +
> +#include <xen/cpu.h>
> +#include <xen/cpumask.h>
> +#include <xen/delay.h>
> +#include <xen/device_tree.h>
> +#include <xen/cpu-topology.h>
> +#include <xen/numa.h>
> +#include <xen/domain_page.h>
> +#include <xen/errno.h>
> +#include <xen/init.h>
> +
> +struct cpu_map {
> +    unsigned int thread_id;
> +    unsigned int core_id;
> +    unsigned int cluster_id;
> +    unsigned int package_id;
> +};
> +
> +struct cpu_topology *cpu_topology;

Looking at the use in the other patch, you seem to unconditionally use 
cpu_topology when CONFIG_DT_CPU_TOPOLOGY. However, you don't seem to 
fill it when the system is using ACPI.

So I think this either needs to be moved to common code and filled by 
ACPI or we need to make clear in the name that this is DT specific.

[...]

> +void __init dt_init_cpu_topology(void)
> +{
> +    unsigned int cpu;
> +    const unsigned int nr_cpus = cpumask_last(&cpu_possible_map) + 1U;
> +
> +    cpu_topology = xzalloc_array(struct cpu_topology, nr_cpus);
> +    if ( !cpu_topology )
> +        panic("Failed to allocate memory for cpu_topology array\n");
> +
> +    if (parse_dt_topology())

Style: AFAICT, this is following Xen style. So it wants to be:

if ( ... )

> +        fixup_topology();
> +
> +    for_each_possible_cpu( cpu )
> +        setup_siblings_masks(cpu);
> +}
> diff --git a/xen/include/xen/cpu-topology.h b/xen/include/xen/cpu-topology.h
> new file mode 100644
> index 0000000000..1c03f4deaa
> --- /dev/null
> +++ b/xen/include/xen/cpu-topology.h
> @@ -0,0 +1,38 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef XEN_CPU_TOPOLOGY_H
> +#define XEN_CPU_TOPOLOGY_H
> +
> +#include <xen/types.h>
> +#include <xen/device_tree.h>
> +
> +struct cpu_topology {
> +    cpumask_t thread_sibling;
> +    cpumask_t core_sibling;
> +    cpumask_t cluster_sibling;
> +};
> +
> +
> +#ifdef CONFIG_DT_CPU_TOPOLOGY
> +
> +extern struct cpu_topology *cpu_topology;
> +void map_cpuid_to_node(unsigned int cpuid, struct dt_device_node *cpu_node);
> +void dt_init_cpu_topology(void);
> +
> +#elif CONFIG_DEVICE_TREE_PARSE
> +
> +static inline void map_cpuid_to_node(unsigned int cpuid, struct dt_device_node *cpu_node) {}
> +static inline void dt_init_cpu_topology(void) {}
> +
> +#endif /* CONFIG_DEVICE_TREE_PARSE */
> +
> +#endif /* XEN_CPU_TOPOLOGY_H */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */

-- 
Julien Grall



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

* Re: [PATCH 3/3] xen/sched: Make cpu_nr_siblings() architecture-specific
  2026-06-10 11:13 ` [PATCH 3/3] xen/sched: Make cpu_nr_siblings() architecture-specific Hirokazu Takahashi
  2026-06-11 14:14   ` Jan Beulich
@ 2026-06-11 22:37   ` Andrew Cooper
  1 sibling, 0 replies; 16+ messages in thread
From: Andrew Cooper @ 2026-06-11 22:37 UTC (permalink / raw)
  To: Hirokazu Takahashi, xen-devel
  Cc: Andrew Cooper, Mykyta_Poturai, Jan Beulich, Roger Pau Monné,
	Teddy Astie, Anthony PERARD, Michal Orzel, Julien Grall,
	Stefano Stabellini, Dario Faggioli, Juergen Gross, George Dunlap

On 10/06/2026 12:13 pm, Hirokazu Takahashi wrote:
> Make cpu_nr_siblings() an architecture-specific function.
> This patch provides the implementation for x86 and a common
> version for Device Tree-based architectures.
>
> Signed-off-by: Hirokazu Takahashi <taka@valinux.co.jp>

You're effectively reverting 188d568db8c, but without fixing the
underlying bug.

It is undefined behaviour for Credit2 to use cpu_nr_siblings().  It
needs reworking to avoid this function entirely, after which
cpu_nr_siblings() wants to be deleted, rather than being reintroduced to
where it was previously removed.

~Andrew


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

* RE: [PATCH 1/3] xen/device-tree: Parse 'cpu-map' node for CPU topology exploration
  2026-06-11 14:06   ` Jan Beulich
@ 2026-06-12  2:29     ` Hirokazu Takahashi
  2026-06-12  6:49       ` Jan Beulich
  0 siblings, 1 reply; 16+ messages in thread
From: Hirokazu Takahashi @ 2026-06-12  2:29 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Mykyta_Poturai@epam.com, Stefano Stabellini, Julien Grall,
	Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper,
	Anthony PERARD, Roger Pau Monné,
	xen-devel@lists.xenproject.org

Hello, 

Thank you for the feedback.

> > --- /dev/null
>

> The name of the new file does not in any way

>... express this is all about DT stuff. Is this intentional? Else it
> may want adjusting.

To address the immediate concern, I agree with renaming the file
to 'dt-cpu-topology.h' in v2, since the current implementation is
purely Device Tree-based.

However, my original intention behind the generic name was to
accommodate future enhancements. Since ARM Xen supports both Device
Tree and ACPI-based boots determined at runtime, I hoped to allow
ACPI boots to populate and share the same underlying topology data
structure. I think this can be achieved by scanning the ACPI PPTT
(Processor Properties Topology Table).

> > +#elif CONFIG_DEVICE_TREE_PARSE
>
>DYM "#elif defined(CONFIG_DEVICE_TREE_PARSE)"?

Oops, I will fix it.

Thank you,
Hirokazu Takahashi.

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

* Re: [PATCH 1/3] xen/device-tree: Parse 'cpu-map' node for CPU topology exploration
  2026-06-12  2:29     ` Hirokazu Takahashi
@ 2026-06-12  6:49       ` Jan Beulich
  0 siblings, 0 replies; 16+ messages in thread
From: Jan Beulich @ 2026-06-12  6:49 UTC (permalink / raw)
  To: Hirokazu Takahashi
  Cc: Mykyta_Poturai@epam.com, Stefano Stabellini, Julien Grall,
	Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper,
	Anthony PERARD, Roger Pau Monné,
	xen-devel@lists.xenproject.org

On 12.06.2026 04:29, Hirokazu Takahashi wrote:
>>> --- /dev/null
>>
> 
>> The name of the new file does not in any way
> 
>> ... express this is all about DT stuff. Is this intentional? Else it
>> may want adjusting.
> 
> To address the immediate concern, I agree with renaming the file
> to 'dt-cpu-topology.h' in v2, since the current implementation is
> purely Device Tree-based.
> 
> However, my original intention behind the generic name was to
> accommodate future enhancements. Since ARM Xen supports both Device
> Tree and ACPI-based boots determined at runtime, I hoped to allow
> ACPI boots to populate and share the same underlying topology data
> structure. I think this can be achieved by scanning the ACPI PPTT
> (Processor Properties Topology Table).

If that's the plan, then keeping the name is fine (at least with me)
as long as that plan is mentioned in the description.

Jan


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

* RE: [PATCH 2/3] xen/sched: Link CPU topology to scheduler
  2026-06-11 14:12   ` Jan Beulich
@ 2026-06-12 19:53     ` Hirokazu Takahashi
  2026-06-15  6:57       ` Jan Beulich
  0 siblings, 1 reply; 16+ messages in thread
From: Hirokazu Takahashi @ 2026-06-12 19:53 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Mykyta_Poturai@epam.com, Stefano Stabellini, Julien Grall,
	Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper,
	Anthony PERARD, Roger Pau Monné, Dario Faggioli,
	Juergen Gross, George Dunlap, xen-devel@lists.xenproject.org

Hello,

> Subject: Re: [PATCH 2/3] xen/sched: Link CPU topology to scheduler
> 
> On 10.06.2026 13:13, Hirokazu Takahashi wrote:
> > Make CPU topology information available to the Xen scheduler.
> > Additionally, ensure that this topology information is displayed
> > when executing the 'xl info -n' command.
> 
> Both in title and description you're pretty generic, yet then ...
> 
> >  xen/arch/arm/include/asm/processor.h  |  4 ---
> >  xen/arch/arm/smpboot.c                | 10 ++++--
> >  xen/common/device-tree/cpu-topology.c | 51
> +++++++++++++++++++++++++++
> >  xen/common/sched/credit2.c            |  3 ++
> >  xen/common/sysctl.c                   |  1 +
> >  xen/include/xen/cpu-topology.h        | 10 ++++++
> >  6 files changed, 72 insertions(+), 7 deletions(-)
> 
> ... only the credit2 scheduler is actually enabled.

While it is true that this patch is focused on Credit2, the CPU topology
information is also reflected in `cpu_sibling_mask` and `cpu_core_mask`.
These masks are globally populated and are already referenced by other
schedulers' code as well.

> > --- a/xen/common/device-tree/cpu-topology.c
> > +++ b/xen/common/device-tree/cpu-topology.c
> > @@ -325,6 +325,55 @@ int __init parse_dt_topology(void)
> >      return parse_socket(map);
> >  }
> >
> > +static void __init setup_cpu_topology_ids(void)
> > +{
> > +    unsigned int cpu;
> > +    unsigned int next_core_id = 0U;
> > +    unsigned int next_cluster_id = 0U;
> > +    unsigned int next_socket_id = 0U;
> > +
> > +    for_each_possible_cpu( cpu )
> 
> Nit (style): Either you deem for_each_possible_cpu a (pseudo-)keyword
> (then there's a blank missing) or you don't (then there are excess
> blanks).

Okay, I will fix them.

> > +    {
> > +        unsigned int first_cpu;
> > +        struct cpu_topology *topo = &cpu_topology[cpu];
> > +
> > +        first_cpu = cpumask_first(&topo->thread_sibling);
> > +        if ( first_cpu == cpu )
> > +        {
> > +            topo->phys_core_id = next_core_id;
> > +            next_core_id++;
> > +        }
> > +        else
> > +        {
> > +            topo->phys_core_id = cpu_topology[first_cpu].phys_core_id;
> > +        }
> 
> Nit, here and below: Please omit unnecessary figure braces.

Okay, I will remove them.

> > @@ -339,4 +388,6 @@ void __init dt_init_cpu_topology(void)
> >
> >      for_each_possible_cpu( cpu )
> >          setup_siblings_masks(cpu);
> As to the earlier remark: Bad pre-existing examples don't count.

Okay.

> > @@ -19,11 +23,17 @@ extern struct cpu_topology *cpu_topology;
> >  void map_cpuid_to_node(unsigned int cpuid, struct dt_device_node
> *cpu_node);
> >  void dt_init_cpu_topology(void);
> >
> > +#define cpu_to_core(_cpu)   (cpu_topology[_cpu].phys_core_id)
> > +#define cpu_to_socket(_cpu)   (cpu_topology[_cpu].phys_socket_id)
> 
> Please can you avoid introducing new name space violations (identifiers
> with leading underscores should name file scope entities); also again
> below.

Ok, I will remove the leading underscores from the macro, which were
originally defined in xen/arch/arm/include/asm/processor.h.
Is it okay to leave the macro definitions in x86's 
`xen/arch/x86/include/asm/processor.h` untouched?

Thank you,
Hirokazu Takahashi.

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

* RE: [PATCH 3/3] xen/sched: Make cpu_nr_siblings() architecture-specific
  2026-06-11 14:14   ` Jan Beulich
@ 2026-06-12 21:06     ` Hirokazu Takahashi
  0 siblings, 0 replies; 16+ messages in thread
From: Hirokazu Takahashi @ 2026-06-12 21:06 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Mykyta_Poturai@epam.com, Andrew Cooper, Roger Pau Monné,
	Teddy Astie, Anthony PERARD, Michal Orzel, Julien Grall,
	Stefano Stabellini, Dario Faggioli, Juergen Gross, George Dunlap,
	xen-devel@lists.xenproject.org

Hello, 

> > --- a/xen/common/sched/credit2.c
> > +++ b/xen/common/sched/credit2.c
> > @@ -29,22 +29,6 @@
> >  /* #define d2printk printk */
> > @@ -884,8 +868,11 @@ cpu_runqueue_match(const struct csched2_runqueue_data *rqd, unsigned int cpu)
> >   * Additional checks, to avoid separating siblings in different runqueues.
> >   * This deals with both Intel's HTs and AMD's CUs. An arch that does not have
> >   * any similar concept will just have cpu_nr_siblings() always return 1, and
> > - * setup the cpu_sibling_mask-s acordingly (as currently does ARM), and things
> > - * will just work as well.
> > + * setup the cpu_sibling_mask-s acordingly, and things will just work as well.
> > + *
> > + * TODO: Abstract cpu_nr_siblings properly, and figure out what Credit2 wants
> > + *       to do with the fact that x86_num_siblings doesn't even have the same
> > + *       meaning between x86 vendors.
> 
> Hmm, the "abstract properly" part is being addressed by this patch. Why would
> you keep saying it needs addressing in the comment you move?

Oaky, I shouldn't have left the "abstract properly" part. I will delete it.
Additionally, I will update this comment block to explicitly mention ARM's 
SMT topology alongside Intel's HTs and AMD's CUs.

Thank you,
Hirokazu Takahashi

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

* RE: [PATCH 1/3] xen/device-tree: Parse 'cpu-map' node for CPU topology exploration
  2026-06-11 22:35   ` Julien Grall
@ 2026-06-14  0:00     ` Hirokazu Takahashi
  0 siblings, 0 replies; 16+ messages in thread
From: Hirokazu Takahashi @ 2026-06-14  0:00 UTC (permalink / raw)
  To: Julien Grall, xen-devel@lists.xenproject.org
  Cc: Mykyta_Poturai@epam.com, Stefano Stabellini, Bertrand Marquis,
	Michal Orzel, Volodymyr Babchuk, Andrew Cooper, Anthony PERARD,
	Jan Beulich, Roger Pau Monné

Hello,

Thank you for your advice.

> > diff --git a/xen/common/device-tree/cpu-topology.c
> b/xen/common/device-tree/cpu-topology.c
> > new file mode 100644
> > index 0000000000..bbdf0d1fe8
> > --- /dev/null
> > +++ b/xen/common/device-tree/cpu-topology.c
> > @@ -0,0 +1,342 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Derived from Linux kernel 7.0's $drivers/base/arch_topology.c
> > + * Parse cpu topology information.
> > + *
> > + * Copyright (c) 2026 VA Linux Systems Japan K.K.
> > + * Author: Hirokazu Takahashi <taka@valinux.co.jp>
> 
> We don't commonly have copyright header in the tree and instead use the
> commit message to keep track of Copyright. That said, if you want to
> keep it, I think you ought to keep the copyright from Linux because your
> code is based on it.

Ok, I will remove the copyright lines from the header.

> > +#include <xen/cpu.h>
> > +#include <xen/cpumask.h>
> > +#include <xen/delay.h>
> > +#include <xen/device_tree.h>
> > +#include <xen/cpu-topology.h>
> > +#include <xen/numa.h>
> > +#include <xen/domain_page.h>
> > +#include <xen/errno.h>
> > +#include <xen/init.h>
> > +
> > +struct cpu_map {
> > +    unsigned int thread_id;
> > +    unsigned int core_id;
> > +    unsigned int cluster_id;
> > +    unsigned int package_id;
> > +};
> > +
> > +struct cpu_topology *cpu_topology;
> 
> Looking at the use in the other patch, you seem to unconditionally use
> cpu_topology when CONFIG_DT_CPU_TOPOLOGY. However, you don't seem to
> fill it when the system is using ACPI.
> 
> So I think this either needs to be moved to common code and filled by
> ACPI or we need to make clear in the name that this is DT specific.
> 
> [...]

You are completely right, and thank you for pointing out this gap. 
I agree that the ACPI path needs to be properly handled.
I will fill the cpu information with temporary values for now though the goal is to
populate it by scanning the ACPI PPTT (Processor Properties Topology Table).

> > +void __init dt_init_cpu_topology(void)
> > +{
> > +    unsigned int cpu;
> > +    const unsigned int nr_cpus = cpumask_last(&cpu_possible_map) + 1U;
> > +
> > +    cpu_topology = xzalloc_array(struct cpu_topology, nr_cpus);
> > +    if ( !cpu_topology )
> > +        panic("Failed to allocate memory for cpu_topology array\n");
> > +
> > +    if (parse_dt_topology())
> 
> Style: AFAICT, this is following Xen style. So it wants to be:
> 
> if ( ... )

Ok, I will fix it.

Thank you,
Hirokazu Takahashi.

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

* Re: [PATCH 2/3] xen/sched: Link CPU topology to scheduler
  2026-06-12 19:53     ` Hirokazu Takahashi
@ 2026-06-15  6:57       ` Jan Beulich
  0 siblings, 0 replies; 16+ messages in thread
From: Jan Beulich @ 2026-06-15  6:57 UTC (permalink / raw)
  To: Hirokazu Takahashi
  Cc: Mykyta_Poturai@epam.com, Stefano Stabellini, Julien Grall,
	Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper,
	Anthony PERARD, Roger Pau Monné, Dario Faggioli,
	Juergen Gross, George Dunlap, xen-devel@lists.xenproject.org

On 12.06.2026 21:53, Hirokazu Takahashi wrote:
>> On 10.06.2026 13:13, Hirokazu Takahashi wrote:
>>> @@ -19,11 +23,17 @@ extern struct cpu_topology *cpu_topology;
>>>  void map_cpuid_to_node(unsigned int cpuid, struct dt_device_node
>> *cpu_node);
>>>  void dt_init_cpu_topology(void);
>>>
>>> +#define cpu_to_core(_cpu)   (cpu_topology[_cpu].phys_core_id)
>>> +#define cpu_to_socket(_cpu)   (cpu_topology[_cpu].phys_socket_id)
>>
>> Please can you avoid introducing new name space violations (identifiers
>> with leading underscores should name file scope entities); also again
>> below.
> 
> Ok, I will remove the leading underscores from the macro, which were
> originally defined in xen/arch/arm/include/asm/processor.h.
> Is it okay to leave the macro definitions in x86's 
> `xen/arch/x86/include/asm/processor.h` untouched?

If you have no other need to touch them - of course.

Jan


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

end of thread, other threads:[~2026-06-15  6:57 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-10 11:13 [PATCH 0/3] xen/arm: Device Tree based CPU topology support Hirokazu Takahashi
2026-06-10 11:13 ` [PATCH 1/3] xen/device-tree: Parse 'cpu-map' node for CPU topology exploration Hirokazu Takahashi
2026-06-11 14:06   ` Jan Beulich
2026-06-12  2:29     ` Hirokazu Takahashi
2026-06-12  6:49       ` Jan Beulich
2026-06-11 22:35   ` Julien Grall
2026-06-14  0:00     ` Hirokazu Takahashi
2026-06-10 11:13 ` [PATCH 2/3] xen/sched: Link CPU topology to scheduler Hirokazu Takahashi
2026-06-11 14:12   ` Jan Beulich
2026-06-12 19:53     ` Hirokazu Takahashi
2026-06-15  6:57       ` Jan Beulich
2026-06-11 22:23   ` Julien Grall
2026-06-10 11:13 ` [PATCH 3/3] xen/sched: Make cpu_nr_siblings() architecture-specific Hirokazu Takahashi
2026-06-11 14:14   ` Jan Beulich
2026-06-12 21:06     ` Hirokazu Takahashi
2026-06-11 22:37   ` Andrew Cooper

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.