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/Kconfig | 1 +
xen/arch/arm/smpboot.c | 7 +
xen/common/Kconfig | 15 ++
xen/common/Makefile | 1 +
xen/common/cpu-topology.c | 62 +++++
xen/common/device-tree/Makefile | 1 +
xen/common/device-tree/cpu-topology.c | 355 ++++++++++++++++++++++++++
xen/drivers/acpi/Kconfig | 3 +
xen/drivers/acpi/Makefile | 1 +
xen/drivers/acpi/topology.c | 38 +++
xen/include/xen/acpi.h | 10 +
xen/include/xen/cpu-topology.h | 35 +++
xen/include/xen/dt-cpu-topology.h | 29 +++
13 files changed, 558 insertions(+)
create mode 100644 xen/common/cpu-topology.c
create mode 100644 xen/common/device-tree/cpu-topology.c
create mode 100644 xen/drivers/acpi/topology.c
create mode 100644 xen/include/xen/cpu-topology.h
create mode 100644 xen/include/xen/dt-cpu-topology.h
diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index 843a43897e..26296c12c8 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -23,6 +23,7 @@ config ARM
select HAS_STACK_PROTECTOR
select HAS_STATIC_MEMORY
select HAS_UBSAN
+ select HAS_GENERIC_CPU_TOPOLOGY
config ARCH_DEFCONFIG
string
diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
index ba5fd2dd52..d957553a44 100644
--- a/xen/arch/arm/smpboot.c
+++ b/xen/arch/arm/smpboot.c
@@ -9,10 +9,12 @@
#include <xen/acpi.h>
#include <xen/cpu.h>
+#include <xen/cpu-topology.h>
#include <xen/cpumask.h>
#include <xen/delay.h>
#include <xen/device_tree.h>
#include <xen/domain_page.h>
+#include <xen/dt-cpu-topology.h>
#include <xen/errno.h>
#include <xen/init.h>
#include <xen/mm.h>
@@ -244,6 +246,9 @@ static void __init dt_smp_init_cpus(void)
}
else
tmp_map[i] = hwid;
+
+ /* Pass the info to dt_init_cpu_topology() */
+ map_cpu_to_dt_node(i, cpu);
}
if ( !bootcpu_valid )
@@ -280,6 +285,8 @@ void __init smp_init_cpus(void)
else
acpi_smp_init_cpus();
+ init_cpu_topology();
+
if ( opt_hmp_unsafe )
warning_add("WARNING: HMP COMPUTING HAS BEEN ENABLED.\n"
"It has implications on the security and stability of the system,\n"
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index da80fdba84..c4bddfd098 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -191,6 +191,21 @@ config VM_EVENT
config NEEDS_LIBELF
bool
+config HAS_GENERIC_CPU_TOPOLOGY
+ bool
+
+config DT_CPU_TOPOLOGY
+ bool
+
+config GENERIC_CPU_TOPOLOGY
+ bool "CPU topology support (UNSUPPORTED)" if UNSUPPORTED
+ depends on HAS_GENERIC_CPU_TOPOLOGY
+ select DT_CPU_TOPOLOGY if DEVICE_TREE_PARSE
+ select ACPI_CPU_TOPOLOGY if ACPI
+ help
+ Retrieve CPU topology information from the device tree or the
+ ACPI PPTT to optimize virtual CPU scheduling.
+
config NUMA
bool
diff --git a/xen/common/Makefile b/xen/common/Makefile
index 6018e25614..34b333cdb3 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_GENERIC_BUG_FRAME) += bug.o
obj-$(CONFIG_HYPFS_CONFIG) += config_data.o
obj-$(CONFIG_CORE_PARKING) += core_parking.o
obj-y += cpu.o
+obj-$(CONFIG_GENERIC_CPU_TOPOLOGY) += cpu-topology.o
obj-$(CONFIG_DEBUG_TRACE) += debugtrace.o
obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += device.o
obj-$(filter-out $(CONFIG_X86),$(CONFIG_ACPI)) += device.o
diff --git a/xen/common/cpu-topology.c b/xen/common/cpu-topology.c
new file mode 100644
index 0000000000..94cb9ba312
--- /dev/null
+++ b/xen/common/cpu-topology.c
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <xen/acpi.h>
+#include <xen/cpu-topology.h>
+#include <xen/cpumask.h>
+#include <xen/dt-cpu-topology.h>
+#include <xen/init.h>
+
+struct cpu_topology *__ro_after_init cpu_topology;
+
+static void __init free_topology_table(void)
+{
+ unsigned int cpu;
+
+ for ( cpu = 0; cpu < nr_cpu_ids; cpu++ )
+ {
+ free_cpumask_var(cpu_topology[cpu].thread_sibling);
+ free_cpumask_var(cpu_topology[cpu].core_sibling);
+ free_cpumask_var(cpu_topology[cpu].cluster_sibling);
+ }
+
+ XFREE(cpu_topology);
+}
+
+void __init init_cpu_topology(void)
+{
+ unsigned int cpu;
+
+ cpu_topology = xzalloc_array(struct cpu_topology, nr_cpu_ids);
+ if ( !cpu_topology )
+ {
+ printk(XENLOG_ERR "Failed to allocate memory for cpu_topology table\n");
+ return;
+ }
+
+ for ( cpu = 0; cpu < nr_cpu_ids; cpu++ )
+ {
+ if ( !zalloc_cpumask_var(&cpu_topology[cpu].thread_sibling) ||
+ !zalloc_cpumask_var(&cpu_topology[cpu].core_sibling) ||
+ !zalloc_cpumask_var(&cpu_topology[cpu].cluster_sibling) )
+ {
+ free_topology_table();
+ printk(XENLOG_ERR "Failed to allocate memory for cpu_topology table\n");
+ return;
+ }
+ }
+
+ if ( acpi_disabled )
+ dt_init_cpu_topology();
+ else
+ acpi_init_cpu_topology();
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/common/device-tree/Makefile b/xen/common/device-tree/Makefile
index 9036e455d6..6ee670b5f4 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.init.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..b653227ef4
--- /dev/null
+++ b/xen/common/device-tree/cpu-topology.c
@@ -0,0 +1,355 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Derived from Linux kernel 7.0's $drivers/base/arch_topology.c
+ * Parse cpu topology information.
+ */
+
+#include <xen/acpi.h>
+#include <xen/cpu-topology.h>
+#include <xen/cpumask.h>
+#include <xen/device_tree.h>
+#include <xen/errno.h>
+#include <xen/init.h>
+#include <xen/numa.h>
+
+struct cpu_map {
+ unsigned int thread_id;
+ unsigned int core_id;
+ unsigned int cluster_id;
+ unsigned int package_id;
+};
+
+static const unsigned int __initdata invalid_topo_id = ~0U;
+static struct cpu_map __initdata cpu_map[NR_CPUS] = {
+ [0 ... NR_CPUS - 1] = {invalid_topo_id, invalid_topo_id, invalid_topo_id, 0}
+};
+static struct dt_device_node *__initdata dt_cpu_table[NR_CPUS];
+
+static void __init setup_siblings_masks(unsigned int target_cpu)
+{
+ const struct cpu_topology *target_topo = &cpu_topology[target_cpu];
+ const struct cpu_map *target_map = &cpu_map[target_cpu];
+ unsigned int cpu;
+
+ /* Update core and thread sibling masks */
+ for_each_possible_cpu(cpu)
+ {
+ const struct cpu_topology *cpu_topo = &cpu_topology[cpu];
+ const struct cpu_map *map = &cpu_map[cpu];
+
+ if ( target_map->package_id != map->package_id )
+ continue;
+
+ cpumask_set_cpu(target_cpu, cpu_topo->core_sibling);
+ cpumask_set_cpu(cpu, target_topo->core_sibling);
+
+ if ( target_map->cluster_id != map->cluster_id )
+ continue;
+
+ if ( target_map->cluster_id != invalid_topo_id )
+ {
+ cpumask_set_cpu(target_cpu, cpu_topo->cluster_sibling);
+ cpumask_set_cpu(cpu, target_topo->cluster_sibling);
+ }
+
+ if ( target_map->core_id != map->core_id )
+ continue;
+
+ cpumask_set_cpu(target_cpu, cpu_topo->thread_sibling);
+ cpumask_set_cpu(cpu, target_topo->thread_sibling);
+ }
+}
+
+static struct dt_device_node *__init
+ dt_find_child_node_by_name(const struct dt_device_node *dt,
+ const char *name)
+{
+ struct dt_device_node *np;
+
+ dt_for_each_child_node(dt, np)
+ if ( np->name && (dt_node_cmp(np->name, name) == 0) )
+ break;
+
+ return np;
+}
+
+void __init map_cpu_to_dt_node(unsigned int cpu,
+ struct dt_device_node *cpu_node)
+{
+ if ( cpu < ARRAY_SIZE(dt_cpu_table) )
+ dt_cpu_table[cpu] = cpu_node;
+ else
+ printk(XENLOG_WARNING
+ "cpu id %u exceeds the max cores %lu\n",
+ cpu, ARRAY_SIZE(dt_cpu_table));
+}
+
+static unsigned int __init cpu_node_to_id(const struct dt_device_node *cpu_node)
+{
+ unsigned int cpu;
+
+ for_each_possible_cpu(cpu)
+ if ( cpu_node == dt_cpu_table[cpu] )
+ return cpu;
+
+ return invalid_topo_id;
+}
+
+/*
+ * This function returns the logical cpu number of the DT node.
+ */
+static unsigned int __init
+ get_cpu_for_node(const struct dt_device_node *dt_node)
+{
+ const struct dt_device_node *cpu_node = dt_parse_phandle(dt_node, "cpu", 0);
+
+ if ( !cpu_node )
+ return invalid_topo_id;
+
+ return cpu_node_to_id(cpu_node);
+}
+
+static int __init parse_core(const struct dt_device_node *core,
+ unsigned int package_id,
+ unsigned int cluster_id,
+ unsigned int core_id)
+{
+ bool leaf = true;
+ unsigned int i = 0;
+ unsigned int cpu;
+
+ do {
+ const struct dt_device_node *t;
+ char name[20];
+
+ 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: %s: Can't get CPU for thread\n", dt_node_name(t));
+ return -EINVAL;
+ }
+ i++;
+ } while ( true );
+
+ cpu = get_cpu_for_node(core);
+
+ if ( cpu != invalid_topo_id )
+ {
+ if ( !leaf )
+ {
+ printk(XENLOG_ERR "ERROR: %s: Core has both threads and CPU\n",
+ dt_node_name(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 = 0;
+ }
+ else if ( leaf )
+ {
+ printk(XENLOG_ERR
+ "ERROR: %s: Can't get CPU for leaf core\n", dt_node_name(core));
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int __init parse_cluster(const struct dt_device_node *cluster,
+ unsigned int package_id,
+ unsigned int cluster_id,
+ unsigned int depth)
+{
+ bool leaf = true;
+ bool has_cores = false;
+ unsigned int core_id = 0;
+ unsigned int i = 0;
+
+ /*
+ * 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.
+ */
+ do {
+ const struct dt_device_node *c;
+ char name[20];
+ int ret;
+
+ 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 + 1);
+ if ( depth > 0 )
+ 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 = 0;
+ do {
+ const struct dt_device_node *c;
+ char name[20];
+ int ret;
+
+ snprintf(name, sizeof(name), "core%u", i);
+ c = dt_find_child_node_by_name(cluster, name);
+
+ if ( !c )
+ break;
+
+ has_cores = true;
+
+ if ( depth == 0 )
+ {
+ printk(XENLOG_ERR
+ "ERROR: %s: cpu-map children should be clusters\n",
+ dt_node_name(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: %s: Non-leaf cluster with core %s\n",
+ dt_node_name(cluster), name);
+ return -EINVAL;
+ }
+
+ i++;
+ } while ( true );
+
+ if ( leaf && !has_cores )
+ printk(XENLOG_WARNING "WARNING: %s: empty cluster\n",
+ dt_node_name(cluster));
+
+ return 0;
+}
+
+static int __init parse_socket(const struct dt_device_node *socket)
+{
+ bool has_socket = false;
+ unsigned int package_id = 0;
+ int ret;
+
+ do {
+ const struct dt_device_node *c;
+ char name[20];
+
+ 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, 0);
+ if ( ret != 0 )
+ return ret;
+
+ package_id++;
+ } while ( true );
+
+ if ( !has_socket )
+ ret = parse_cluster(socket, 0, invalid_topo_id, 0);
+
+ 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 = 0;
+ unsigned int pkgid = 0;
+
+ 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 = 0;
+ }
+ map->cluster_id = clid++;
+ map->core_id = 0;
+ map->thread_id = 0;
+ }
+}
+
+int __init parse_dt_topology(void)
+{
+ const struct dt_device_node *cpus;
+ const 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;
+
+ BUG_ON(!acpi_disabled);
+ BUG_ON(!cpu_topology);
+
+ if ( parse_dt_topology() )
+ fixup_topology();
+
+ for_each_possible_cpu(cpu)
+ setup_siblings_masks(cpu);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/drivers/acpi/Kconfig b/xen/drivers/acpi/Kconfig
index e3f3d8f4b1..5277b7bf83 100644
--- a/xen/drivers/acpi/Kconfig
+++ b/xen/drivers/acpi/Kconfig
@@ -8,3 +8,6 @@ config ACPI_LEGACY_TABLES_LOOKUP
config ACPI_NUMA
bool
select NUMA
+
+config ACPI_CPU_TOPOLOGY
+ bool
diff --git a/xen/drivers/acpi/Makefile b/xen/drivers/acpi/Makefile
index 477408afbe..bcdb1b5e1b 100644
--- a/xen/drivers/acpi/Makefile
+++ b/xen/drivers/acpi/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_PM_OP) += pm-op.o
obj-$(CONFIG_X86) += hwregs.o
obj-$(CONFIG_X86) += reboot.o
+obj-$(CONFIG_ACPI_CPU_TOPOLOGY) += topology.init.o
diff --git a/xen/drivers/acpi/topology.c b/xen/drivers/acpi/topology.c
new file mode 100644
index 0000000000..6bd2d96ebb
--- /dev/null
+++ b/xen/drivers/acpi/topology.c
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <xen/acpi.h>
+#include <xen/cpu-topology.h>
+#include <xen/cpumask.h>
+#include <xen/init.h>
+
+/*
+ * TODO: Populate the topology information by scanning the ACPI
+ * PPTT (Processor Properties Topology Table).
+ */
+void __init acpi_init_cpu_topology(void)
+{
+ unsigned int cpu;
+
+ /*
+ * Generate temporary cpu topology information for now.
+ * It assumes that the cpu doesn't have SMT and all CPUs
+ * belong to the same socket.
+ */
+ for_each_possible_cpu(cpu)
+ {
+ struct cpu_topology *topo = &cpu_topology[cpu];
+
+ cpumask_set_cpu(cpu, topo->thread_sibling);
+ cpumask_copy(topo->core_sibling, &cpu_possible_map);
+ }
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h
index 2fdf38cf74..bd982ee836 100644
--- a/xen/include/xen/acpi.h
+++ b/xen/include/xen/acpi.h
@@ -135,6 +135,16 @@ static inline int acpi_boot_table_init(void)
#endif /*!CONFIG_ACPI*/
+#ifdef CONFIG_ACPI_CPU_TOPOLOGY
+
+void acpi_init_cpu_topology(void);
+
+#else /* CONFIG_ACPI_CPU_TOPOLOGY */
+
+static inline void acpi_init_cpu_topology(void) {}
+
+#endif /* CONFIG_ACPI_CPU_TOPOLOGY */
+
int get_cpu_id(u32 acpi_id);
unsigned int acpi_register_gsi (u32 gsi, int edge_level, int active_high_low);
diff --git a/xen/include/xen/cpu-topology.h b/xen/include/xen/cpu-topology.h
new file mode 100644
index 0000000000..f64820febf
--- /dev/null
+++ b/xen/include/xen/cpu-topology.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef XEN_CPU_TOPOLOGY_H
+#define XEN_CPU_TOPOLOGY_H
+
+#include <xen/cpumask.h>
+
+#ifdef CONFIG_GENERIC_CPU_TOPOLOGY
+
+struct cpu_topology {
+ cpumask_var_t thread_sibling;
+ cpumask_var_t core_sibling;
+ cpumask_var_t cluster_sibling;
+};
+
+extern struct cpu_topology *cpu_topology;
+void init_cpu_topology(void);
+
+#else /* CONFIG_GENERIC_CPU_TOPOLOGY */
+
+#define cpu_topology ((struct cpu_topology *)NULL)
+static inline void init_cpu_topology(void) {}
+
+#endif /* CONFIG_GENERIC_CPU_TOPOLOGY */
+
+#endif /* XEN_CPU_TOPOLOGY_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/xen/dt-cpu-topology.h b/xen/include/xen/dt-cpu-topology.h
new file mode 100644
index 0000000000..cb8a266479
--- /dev/null
+++ b/xen/include/xen/dt-cpu-topology.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef XEN_DT_CPU_TOPOLOGY_H
+#define XEN_DT_CPU_TOPOLOGY_H
+
+struct dt_device_node;
+
+#ifdef CONFIG_DT_CPU_TOPOLOGY
+
+void map_cpu_to_dt_node(unsigned int cpu, struct dt_device_node *cpu_node);
+void dt_init_cpu_topology(void);
+
+#else /* CONFIG_DT_CPU_TOPOLOGY */
+
+static inline void map_cpu_to_dt_node(unsigned int cpu,
+ struct dt_device_node *cpu_node) {}
+
+#endif /* CONFIG_DT_CPU_TOPOLOGY */
+
+#endif /* XEN_DT_CPU_TOPOLOGY_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
2.43.0
On 10.07.2026 00:05, Hirokazu Takahashi wrote: > --- a/xen/arch/arm/Kconfig > +++ b/xen/arch/arm/Kconfig > @@ -23,6 +23,7 @@ config ARM > select HAS_STACK_PROTECTOR > select HAS_STATIC_MEMORY > select HAS_UBSAN > + select HAS_GENERIC_CPU_TOPOLOGY Please insert at the appropriate spot of this list, not at the bottom. We try to keep such lists sorted (both for easier lookup and for reduced risk of two patches colliding). > --- a/xen/common/Kconfig > +++ b/xen/common/Kconfig > @@ -191,6 +191,21 @@ config VM_EVENT > config NEEDS_LIBELF > bool > > +config HAS_GENERIC_CPU_TOPOLOGY > + bool > + > +config DT_CPU_TOPOLOGY > + bool > + > +config GENERIC_CPU_TOPOLOGY > + bool "CPU topology support (UNSUPPORTED)" if UNSUPPORTED > + depends on HAS_GENERIC_CPU_TOPOLOGY > + select DT_CPU_TOPOLOGY if DEVICE_TREE_PARSE > + select ACPI_CPU_TOPOLOGY if ACPI > + help > + Retrieve CPU topology information from the device tree or the > + ACPI PPTT to optimize virtual CPU scheduling. > + > config NUMA > bool I can't help the impression that none of my v4 comments were taken into account. And not just here. Jan
Hello, > > --- a/xen/arch/arm/Kconfig > > +++ b/xen/arch/arm/Kconfig > > @@ -23,6 +23,7 @@ config ARM > > select HAS_STACK_PROTECTOR > > select HAS_STATIC_MEMORY > > select HAS_UBSAN > > + select HAS_GENERIC_CPU_TOPOLOGY > > Please insert at the appropriate spot of this list, not at the bottom. We > try to keep such lists sorted (both for easier lookup and for reduced risk > of two patches colliding). Okay, I will fix it soon. > > --- a/xen/common/Kconfig > > +++ b/xen/common/Kconfig > > @@ -191,6 +191,21 @@ config VM_EVENT > > config NEEDS_LIBELF > > bool > > > > +config HAS_GENERIC_CPU_TOPOLOGY > > + bool > > + > > +config DT_CPU_TOPOLOGY > > + bool > > + > > +config GENERIC_CPU_TOPOLOGY > > + bool "CPU topology support (UNSUPPORTED)" if UNSUPPORTED > > + depends on HAS_GENERIC_CPU_TOPOLOGY > > + select DT_CPU_TOPOLOGY if DEVICE_TREE_PARSE > > + select ACPI_CPU_TOPOLOGY if ACPI > > + help > > + Retrieve CPU topology information from the device tree or the > > + ACPI PPTT to optimize virtual CPU scheduling. > > + > > config NUMA > > bool > > I can't help the impression that none of my v4 comments were taken into > account. And not just here. I am very sorry, I completely overlooked your feedback on v4. I will address all of your comments right away and ensure they are reflected in the next version. Hirokazu Takahashi.
© 2016 - 2026 Red Hat, Inc.