mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
3.5 KiB
142 lines
3.5 KiB
/* |
|
* arch/parisc/kernel/topology.c |
|
* |
|
* Copyright (C) 2017 Helge Deller <[email protected]> |
|
* |
|
* based on arch/arm/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/percpu.h> |
|
#include <linux/sched.h> |
|
#include <linux/sched/topology.h> |
|
|
|
#include <asm/topology.h> |
|
|
|
/* |
|
* cpu topology table |
|
*/ |
|
struct cputopo_parisc cpu_topology[NR_CPUS] __read_mostly; |
|
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 cputopo_parisc *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; |
|
int cpu; |
|
|
|
/* update core and thread sibling masks */ |
|
for_each_possible_cpu(cpu) { |
|
cpu_topo = &cpu_topology[cpu]; |
|
|
|
if (cpuid_topo->socket_id != cpu_topo->socket_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); |
|
} |
|
smp_wmb(); |
|
} |
|
|
|
static int dualcores_found __initdata; |
|
|
|
/* |
|
* store_cpu_topology is called at boot when only one cpu is running |
|
* and with the mutex cpu_hotplug.lock locked, when several cpus have booted, |
|
* which prevents simultaneous write access to cpu_topology array |
|
*/ |
|
void __init store_cpu_topology(unsigned int cpuid) |
|
{ |
|
struct cputopo_parisc *cpuid_topo = &cpu_topology[cpuid]; |
|
struct cpuinfo_parisc *p; |
|
int max_socket = -1; |
|
unsigned long cpu; |
|
|
|
/* If the cpu topology has been already set, just return */ |
|
if (cpuid_topo->core_id != -1) |
|
return; |
|
|
|
/* create cpu topology mapping */ |
|
cpuid_topo->thread_id = -1; |
|
cpuid_topo->core_id = 0; |
|
|
|
p = &per_cpu(cpu_data, cpuid); |
|
for_each_online_cpu(cpu) { |
|
const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu); |
|
|
|
if (cpu == cpuid) /* ignore current cpu */ |
|
continue; |
|
|
|
if (cpuinfo->cpu_loc == p->cpu_loc) { |
|
cpuid_topo->core_id = cpu_topology[cpu].core_id; |
|
if (p->cpu_loc) { |
|
cpuid_topo->core_id++; |
|
cpuid_topo->socket_id = cpu_topology[cpu].socket_id; |
|
dualcores_found = 1; |
|
continue; |
|
} |
|
} |
|
|
|
if (cpuid_topo->socket_id == -1) |
|
max_socket = max(max_socket, cpu_topology[cpu].socket_id); |
|
} |
|
|
|
if (cpuid_topo->socket_id == -1) |
|
cpuid_topo->socket_id = max_socket + 1; |
|
|
|
update_siblings_masks(cpuid); |
|
|
|
pr_info("CPU%u: thread %d, cpu %d, socket %d\n", |
|
cpuid, cpu_topology[cpuid].thread_id, |
|
cpu_topology[cpuid].core_id, |
|
cpu_topology[cpuid].socket_id); |
|
} |
|
|
|
static struct sched_domain_topology_level parisc_mc_topology[] = { |
|
#ifdef CONFIG_SCHED_MC |
|
{ cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) }, |
|
#endif |
|
|
|
{ cpu_cpu_mask, SD_INIT_NAME(DIE) }, |
|
{ NULL, }, |
|
}; |
|
|
|
/* |
|
* 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 capacity */ |
|
for_each_possible_cpu(cpu) { |
|
struct cputopo_parisc *cpu_topo = &(cpu_topology[cpu]); |
|
|
|
cpu_topo->thread_id = -1; |
|
cpu_topo->core_id = -1; |
|
cpu_topo->socket_id = -1; |
|
cpumask_clear(&cpu_topo->core_sibling); |
|
cpumask_clear(&cpu_topo->thread_sibling); |
|
} |
|
smp_wmb(); |
|
|
|
/* Set scheduler topology descriptor */ |
|
if (dualcores_found) |
|
set_sched_topology(parisc_mc_topology); |
|
}
|
|
|