-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
arm64: topology: Implement basic CPU topology support
Add basic CPU topology support to arm64, based on the existing pre-v8 code and some work done by Mark Hambleton. This patch does not implement any topology discovery support since that should be based on information from firmware, it merely implements the scaffolding for integration of topology support in the architecture. No locking of the topology data is done since it is only modified during CPU bringup with external serialisation from the SMP code. The goal is to separate the architecture hookup for providing topology information from the DT parsing in order to ease review and avoid blocking the architecture code (which will be built on by other work) with the DT code review by providing something simple and basic. Following patches will implement support for interpreting topology information from MPIDR and for parsing the DT topology bindings for ARM, similar patches will be needed for ACPI. Signed-off-by: Mark Brown <broonie@linaro.org> Acked-by: Mark Rutland <mark.rutland@arm.com> [catalin.marinas@arm.com: removed CONFIG_CPU_TOPOLOGY, always on if SMP] Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
- Loading branch information
Mark Brown
authored and
Catalin Marinas
committed
Mar 4, 2014
1 parent
4cf761c
commit f6e763b
Showing
5 changed files
with
162 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#ifndef __ASM_TOPOLOGY_H | ||
#define __ASM_TOPOLOGY_H | ||
|
||
#ifdef CONFIG_SMP | ||
|
||
#include <linux/cpumask.h> | ||
|
||
struct cpu_topology { | ||
int thread_id; | ||
int core_id; | ||
int cluster_id; | ||
cpumask_t thread_sibling; | ||
cpumask_t core_sibling; | ||
}; | ||
|
||
extern struct cpu_topology cpu_topology[NR_CPUS]; | ||
|
||
#define topology_physical_package_id(cpu) (cpu_topology[cpu].cluster_id) | ||
#define topology_core_id(cpu) (cpu_topology[cpu].core_id) | ||
#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling) | ||
#define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_sibling) | ||
|
||
#define mc_capable() (cpu_topology[0].cluster_id != -1) | ||
#define smt_capable() (cpu_topology[0].thread_id != -1) | ||
|
||
void init_cpu_topology(void); | ||
void store_cpu_topology(unsigned int cpuid); | ||
const struct cpumask *cpu_coregroup_mask(int cpu); | ||
|
||
#else | ||
|
||
static inline void init_cpu_topology(void) { } | ||
static inline void store_cpu_topology(unsigned int cpuid) { } | ||
|
||
#endif | ||
|
||
#include <asm-generic/topology.h> | ||
|
||
#endif /* _ASM_ARM_TOPOLOGY_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* arch/arm64/kernel/topology.c | ||
* | ||
* Copyright (C) 2011,2013,2014 Linaro Limited. | ||
* | ||
* Based on the arm32 version written by Vincent Guittot in turn based on | ||
* arch/sh/kernel/topology.c | ||
* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file "COPYING" in the main directory of this archive | ||
* for more details. | ||
*/ | ||
|
||
#include <linux/cpu.h> | ||
#include <linux/cpumask.h> | ||
#include <linux/init.h> | ||
#include <linux/percpu.h> | ||
#include <linux/node.h> | ||
#include <linux/nodemask.h> | ||
#include <linux/sched.h> | ||
|
||
#include <asm/topology.h> | ||
|
||
/* | ||
* cpu topology table | ||
*/ | ||
struct cpu_topology cpu_topology[NR_CPUS]; | ||
EXPORT_SYMBOL_GPL(cpu_topology); | ||
|
||
const struct cpumask *cpu_coregroup_mask(int cpu) | ||
{ | ||
return &cpu_topology[cpu].core_sibling; | ||
} | ||
|
||
static void update_siblings_masks(unsigned int cpuid) | ||
{ | ||
struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; | ||
int cpu; | ||
|
||
if (cpuid_topo->cluster_id == -1) { | ||
/* | ||
* DT does not contain topology information for this cpu | ||
* reset it to default behaviour | ||
*/ | ||
pr_debug("CPU%u: No topology information configured\n", cpuid); | ||
cpuid_topo->core_id = 0; | ||
cpumask_set_cpu(cpuid, &cpuid_topo->core_sibling); | ||
cpumask_set_cpu(cpuid, &cpuid_topo->thread_sibling); | ||
return; | ||
} | ||
|
||
/* update core and thread sibling masks */ | ||
for_each_possible_cpu(cpu) { | ||
cpu_topo = &cpu_topology[cpu]; | ||
|
||
if (cpuid_topo->cluster_id != cpu_topo->cluster_id) | ||
continue; | ||
|
||
cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); | ||
if (cpu != cpuid) | ||
cpumask_set_cpu(cpu, &cpuid_topo->core_sibling); | ||
|
||
if (cpuid_topo->core_id != cpu_topo->core_id) | ||
continue; | ||
|
||
cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling); | ||
if (cpu != cpuid) | ||
cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling); | ||
} | ||
} | ||
|
||
void store_cpu_topology(unsigned int cpuid) | ||
{ | ||
update_siblings_masks(cpuid); | ||
} | ||
|
||
/* | ||
* init_cpu_topology is called at boot when only one cpu is running | ||
* which prevent simultaneous write access to cpu_topology array | ||
*/ | ||
void __init init_cpu_topology(void) | ||
{ | ||
unsigned int cpu; | ||
|
||
/* init core mask and power*/ | ||
for_each_possible_cpu(cpu) { | ||
struct cpu_topology *cpu_topo = &cpu_topology[cpu]; | ||
|
||
cpu_topo->thread_id = -1; | ||
cpu_topo->core_id = -1; | ||
cpu_topo->cluster_id = -1; | ||
cpumask_clear(&cpu_topo->core_sibling); | ||
cpumask_clear(&cpu_topo->thread_sibling); | ||
} | ||
} |