[PATCH v9 2/4] xen/sched: Link CPU topology to scheduler
Hirokazu Takahashi <[email protected]>
| Newsgroups | org.xenproject.lists.xen-devel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> Acked-by: Jan Beulich <[email protected]> Reviewed-by: Juergen Gross <[email protected]> # scheduler part --- xen/arch/arm/include/asm/processor.h | 4 -- xen/arch/arm/smpboot.c | 8 +--- xen/arch/ppc/include/asm/processor.h | 4 -- xen/arch/riscv/include/asm/processor.h | 4 -- xen/common/device-tree/cpu-topology.c | 65 ++++++++++++++++++++++++++ xen/common/sched/credit2.c | 6 +++ xen/common/sysctl.c | 1 + xen/drivers/acpi/topology.c | 3 ++ xen/include/xen/cpu-topology.h | 39 +++++++++++++++- 9 files changed, 114 insertions(+), 20 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 d957553a44..88b01bcfd2 100644 --- a/xen/arch/arm/smpboot.c +++ b/xen/arch/arm/smpboot.c @@ -92,13 +92,7 @@ static int setup_cpu_sibling_map(int cpu) !zalloc_cpumask_var(&per_cpu(cpu_core_mask, cpu)) ) return -ENOMEM; - /* - * 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). - */ - cpumask_set_cpu(cpu, per_cpu(cpu_sibling_mask, cpu)); - cpumask_copy(per_cpu(cpu_core_mask, cpu), &cpu_possible_map); + init_cpu_sibling_map(cpu); return 0; } diff --git a/xen/arch/ppc/include/asm/processor.h b/xen/arch/ppc/include/asm/processor.h index 242346cab9..1bf6f6c66c 100644 --- a/xen/arch/ppc/include/asm/processor.h +++ b/xen/arch/ppc/include/asm/processor.h @@ -141,10 +141,6 @@ /* Macro to adjust thread priority for hardware multithreading */ #define HMT_very_low() asm volatile ( "or %r31, %r31, %r31" ) -/* TODO: This isn't correct */ -#define cpu_to_core(cpu) (0) -#define cpu_to_socket(cpu) (0) - /* * User-accessible registers: most of these need to be saved/restored * for every nested Xen invocation. diff --git a/xen/arch/riscv/include/asm/processor.h b/xen/arch/riscv/include/asm/processor.h index 6b89df4a2d..d478ffb76b 100644 --- a/xen/arch/riscv/include/asm/processor.h +++ b/xen/arch/riscv/include/asm/processor.h @@ -54,10 +54,6 @@ struct cpu_user_regs unsigned long pregs; }; -/* TODO: need to implement */ -#define cpu_to_core(cpu) 0 -#define cpu_to_socket(cpu) 0 - static inline void cpu_relax(void) { #ifdef __riscv_zihintpause diff --git a/xen/common/device-tree/cpu-topology.c b/xen/common/device-tree/cpu-topology.c index 9259be73bc..36560dc228 100644 --- a/xen/common/device-tree/cpu-topology.c +++ b/xen/common/device-tree/cpu-topology.c @@ -317,6 +317,67 @@ static 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 = 0; + unsigned int next_cluster_id = 0; + unsigned int next_socket_id = 0; + + for_each_possible_cpu(cpu) + { + unsigned int first_cpu; + struct cpu_topology *topo = &cpu_topology[cpu]; + + first_cpu = cpumask_first(topo->thread_sibling); + ASSERT(first_cpu < nr_cpu_ids); + + 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 >= nr_cpu_ids ) + { + /* Clustering is not supported */ + topo->phys_cluster_id = 0; + } + else + { + 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); + ASSERT(first_cpu < nr_cpu_ids); + + 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); + } +} + int __init dt_init_cpu_topology(void) { unsigned int cpu; @@ -327,9 +388,13 @@ int __init dt_init_cpu_topology(void) ret = parse_dt_topology(); if ( ret == 0 ) + { for_each_possible_cpu(cpu) setup_siblings_masks(cpu); + setup_cpu_topology_ids(); + } + return ret; } diff --git a/xen/common/sched/credit2.c b/xen/common/sched/credit2.c index 95946634d1..b4a3b59601 100644 --- a/xen/common/sched/credit2.c +++ b/xen/common/sched/credit2.c @@ -9,6 +9,7 @@ * Based on an earlier verson by Emmanuel Ackaouy. */ +#include <xen/cpu-topology.h> #include <xen/errno.h> #include <xen/init.h> #include <xen/lib.h> @@ -35,6 +36,11 @@ */ static unsigned int cpu_nr_siblings(unsigned int cpu) { +#ifdef CONFIG_GENERIC_CPU_TOPOLOGY + if ( cpu_topology ) + return cpu_topology[cpu].num_siblings; +#endif + #ifdef CONFIG_X86 return cpu_data[cpu].x86_num_siblings; #else 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/drivers/acpi/topology.c b/xen/drivers/acpi/topology.c index 45d1f2c5be..56fcfa4945 100644 --- a/xen/drivers/acpi/topology.c +++ b/xen/drivers/acpi/topology.c @@ -22,6 +22,9 @@ int __init acpi_init_cpu_topology(void) { struct cpu_topology *topo = &cpu_topology[cpu]; + topo->phys_core_id = cpu; + topo->num_siblings = 1; + cpumask_set_cpu(cpu, topo->thread_sibling); cpumask_copy(topo->core_sibling, &cpu_possible_map); cpumask_copy(topo->cluster_sibling, &cpu_possible_map); diff --git a/xen/include/xen/cpu-topology.h b/xen/include/xen/cpu-topology.h index 7cfe3752cd..52ee93d4d0 100644 --- a/xen/include/xen/cpu-topology.h +++ b/xen/include/xen/cpu-topology.h @@ -4,22 +4,59 @@ #define XEN_CPU_TOPOLOGY_H #include <xen/cpumask.h> +#include <xen/percpu.h> -#ifdef CONFIG_GENERIC_CPU_TOPOLOGY +#include <asm/processor.h> +#include <asm/smp.h> struct cpu_topology { cpumask_var_t thread_sibling; cpumask_var_t core_sibling; cpumask_var_t cluster_sibling; + unsigned int phys_core_id; + unsigned int phys_cluster_id; + unsigned int phys_socket_id; + unsigned int num_siblings; }; extern struct cpu_topology *cpu_topology; + +static inline void init_cpu_sibling_map(unsigned int cpu) +{ + if ( IS_ENABLED(CONFIG_GENERIC_CPU_TOPOLOGY) && 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 + { + /* Assume all CPUs reside in the same socket and no threading. */ + cpumask_set_cpu(cpu, per_cpu(cpu_sibling_mask, cpu)); + cpumask_copy(per_cpu(cpu_core_mask, cpu), &cpu_possible_map); + } +} + +#ifdef CONFIG_GENERIC_CPU_TOPOLOGY + void init_cpu_topology(void); +#define cpu_to_core(cpu) (cpu_topology ? cpu_topology[cpu].phys_core_id : 0) +#define cpu_to_socket(cpu) (cpu_topology ? cpu_topology[cpu].phys_socket_id : 0) + #else /* CONFIG_GENERIC_CPU_TOPOLOGY */ static inline void init_cpu_topology(void) {} +#ifndef cpu_to_core +#define cpu_to_core(cpu) (0) +#endif + +#ifndef cpu_to_socket +#define cpu_to_socket(cpu) (0) +#endif + #endif /* CONFIG_GENERIC_CPU_TOPOLOGY */ #endif /* XEN_CPU_TOPOLOGY_H */ -- 2.43.0