riscv: Add numa support for riscv64 platform
Use the generic numa implementation to add NUMA support for RISC-V. This is based on Greentime's patch[1] but modified to use generic NUMA implementation and few more fixes. [1] https://lkml.org/lkml/2020/1/10/233 Co-developed-by: Greentime Hu <greentime.hu@sifive.com> Signed-off-by: Greentime Hu <greentime.hu@sifive.com> Signed-off-by: Atish Patra <atish.patra@wdc.com> Reviewed-by: Anup Patel <anup@brainfault.org> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com> Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
This commit is contained in:
parent
3e5b0bdb2a
commit
4f0e8eef77
7 changed files with 87 additions and 5 deletions
|
@ -143,7 +143,7 @@ config PAGE_OFFSET
|
||||||
default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB
|
default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB
|
||||||
|
|
||||||
config ARCH_FLATMEM_ENABLE
|
config ARCH_FLATMEM_ENABLE
|
||||||
def_bool y
|
def_bool !NUMA
|
||||||
|
|
||||||
config ARCH_SPARSEMEM_ENABLE
|
config ARCH_SPARSEMEM_ENABLE
|
||||||
def_bool y
|
def_bool y
|
||||||
|
@ -298,6 +298,35 @@ config TUNE_GENERIC
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
# Common NUMA Features
|
||||||
|
config NUMA
|
||||||
|
bool "NUMA Memory Allocation and Scheduler Support"
|
||||||
|
select GENERIC_ARCH_NUMA
|
||||||
|
select OF_NUMA
|
||||||
|
select ARCH_SUPPORTS_NUMA_BALANCING
|
||||||
|
help
|
||||||
|
Enable NUMA (Non-Uniform Memory Access) support.
|
||||||
|
|
||||||
|
The kernel will try to allocate memory used by a CPU on the
|
||||||
|
local memory of the CPU and add some more NUMA awareness to the kernel.
|
||||||
|
|
||||||
|
config NODES_SHIFT
|
||||||
|
int "Maximum NUMA Nodes (as a power of 2)"
|
||||||
|
range 1 10
|
||||||
|
default "2"
|
||||||
|
depends on NEED_MULTIPLE_NODES
|
||||||
|
help
|
||||||
|
Specify the maximum number of NUMA Nodes available on the target
|
||||||
|
system. Increases memory reserved to accommodate various tables.
|
||||||
|
|
||||||
|
config USE_PERCPU_NUMA_NODE_ID
|
||||||
|
def_bool y
|
||||||
|
depends on NUMA
|
||||||
|
|
||||||
|
config NEED_PER_CPU_EMBED_FIRST_CHUNK
|
||||||
|
def_bool y
|
||||||
|
depends on NUMA
|
||||||
|
|
||||||
config RISCV_ISA_C
|
config RISCV_ISA_C
|
||||||
bool "Emit compressed instructions when building Linux"
|
bool "Emit compressed instructions when building Linux"
|
||||||
default y
|
default y
|
||||||
|
|
13
arch/riscv/include/asm/mmzone.h
Normal file
13
arch/riscv/include/asm/mmzone.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
#ifndef __ASM_MMZONE_H
|
||||||
|
#define __ASM_MMZONE_H
|
||||||
|
|
||||||
|
#ifdef CONFIG_NUMA
|
||||||
|
|
||||||
|
#include <asm/numa.h>
|
||||||
|
|
||||||
|
extern struct pglist_data *node_data[];
|
||||||
|
#define NODE_DATA(nid) (node_data[(nid)])
|
||||||
|
|
||||||
|
#endif /* CONFIG_NUMA */
|
||||||
|
#endif /* __ASM_MMZONE_H */
|
8
arch/riscv/include/asm/numa.h
Normal file
8
arch/riscv/include/asm/numa.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
#ifndef __ASM_NUMA_H
|
||||||
|
#define __ASM_NUMA_H
|
||||||
|
|
||||||
|
#include <asm/topology.h>
|
||||||
|
#include <asm-generic/numa.h>
|
||||||
|
|
||||||
|
#endif /* __ASM_NUMA_H */
|
|
@ -32,6 +32,20 @@ static inline int pci_proc_domain(struct pci_bus *bus)
|
||||||
/* always show the domain in /proc */
|
/* always show the domain in /proc */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NUMA
|
||||||
|
|
||||||
|
static inline int pcibus_to_node(struct pci_bus *bus)
|
||||||
|
{
|
||||||
|
return dev_to_node(&bus->dev);
|
||||||
|
}
|
||||||
|
#ifndef cpumask_of_pcibus
|
||||||
|
#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \
|
||||||
|
cpu_all_mask : \
|
||||||
|
cpumask_of_node(pcibus_to_node(bus)))
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_NUMA */
|
||||||
|
|
||||||
#endif /* CONFIG_PCI */
|
#endif /* CONFIG_PCI */
|
||||||
|
|
||||||
#endif /* _ASM_RISCV_PCI_H */
|
#endif /* _ASM_RISCV_PCI_H */
|
||||||
|
|
|
@ -273,13 +273,19 @@ void __init setup_arch(char **cmdline_p)
|
||||||
|
|
||||||
static int __init topology_init(void)
|
static int __init topology_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i, ret;
|
||||||
|
|
||||||
|
for_each_online_node(i)
|
||||||
|
register_one_node(i);
|
||||||
|
|
||||||
for_each_possible_cpu(i) {
|
for_each_possible_cpu(i) {
|
||||||
struct cpu *cpu = &per_cpu(cpu_devices, i);
|
struct cpu *cpu = &per_cpu(cpu_devices, i);
|
||||||
|
|
||||||
cpu->hotpluggable = cpu_has_hotplug(i);
|
cpu->hotpluggable = cpu_has_hotplug(i);
|
||||||
register_cpu(cpu, i);
|
ret = register_cpu(cpu, i);
|
||||||
|
if (unlikely(ret))
|
||||||
|
pr_warn("Warning: %s: register_cpu %d failed (%d)\n",
|
||||||
|
__func__, i, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <asm/cpu_ops.h>
|
#include <asm/cpu_ops.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
|
#include <asm/numa.h>
|
||||||
#include <asm/tlbflush.h>
|
#include <asm/tlbflush.h>
|
||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
#include <asm/sbi.h>
|
#include <asm/sbi.h>
|
||||||
|
@ -45,13 +46,18 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
|
||||||
{
|
{
|
||||||
int cpuid;
|
int cpuid;
|
||||||
int ret;
|
int ret;
|
||||||
|
unsigned int curr_cpuid;
|
||||||
|
|
||||||
|
curr_cpuid = smp_processor_id();
|
||||||
|
numa_store_cpu_info(curr_cpuid);
|
||||||
|
numa_add_cpu(curr_cpuid);
|
||||||
|
|
||||||
/* This covers non-smp usecase mandated by "nosmp" option */
|
/* This covers non-smp usecase mandated by "nosmp" option */
|
||||||
if (max_cpus == 0)
|
if (max_cpus == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for_each_possible_cpu(cpuid) {
|
for_each_possible_cpu(cpuid) {
|
||||||
if (cpuid == smp_processor_id())
|
if (cpuid == curr_cpuid)
|
||||||
continue;
|
continue;
|
||||||
if (cpu_ops[cpuid]->cpu_prepare) {
|
if (cpu_ops[cpuid]->cpu_prepare) {
|
||||||
ret = cpu_ops[cpuid]->cpu_prepare(cpuid);
|
ret = cpu_ops[cpuid]->cpu_prepare(cpuid);
|
||||||
|
@ -59,6 +65,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
set_cpu_present(cpuid, true);
|
set_cpu_present(cpuid, true);
|
||||||
|
numa_store_cpu_info(cpuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +86,7 @@ void __init setup_smp(void)
|
||||||
if (hart == cpuid_to_hartid_map(0)) {
|
if (hart == cpuid_to_hartid_map(0)) {
|
||||||
BUG_ON(found_boot_cpu);
|
BUG_ON(found_boot_cpu);
|
||||||
found_boot_cpu = 1;
|
found_boot_cpu = 1;
|
||||||
|
early_map_cpu_to_node(0, of_node_to_nid(dn));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cpuid >= NR_CPUS) {
|
if (cpuid >= NR_CPUS) {
|
||||||
|
@ -88,6 +96,7 @@ void __init setup_smp(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuid_to_hartid_map(cpuid) = hart;
|
cpuid_to_hartid_map(cpuid) = hart;
|
||||||
|
early_map_cpu_to_node(cpuid, of_node_to_nid(dn));
|
||||||
cpuid++;
|
cpuid++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +162,7 @@ asmlinkage __visible void smp_callin(void)
|
||||||
current->active_mm = mm;
|
current->active_mm = mm;
|
||||||
|
|
||||||
notify_cpu_starting(curr_cpuid);
|
notify_cpu_starting(curr_cpuid);
|
||||||
|
numa_add_cpu(curr_cpuid);
|
||||||
update_siblings_masks(curr_cpuid);
|
update_siblings_masks(curr_cpuid);
|
||||||
set_cpu_online(curr_cpuid, 1);
|
set_cpu_online(curr_cpuid, 1);
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <asm/soc.h>
|
#include <asm/soc.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/ptdump.h>
|
#include <asm/ptdump.h>
|
||||||
|
#include <asm/numa.h>
|
||||||
|
|
||||||
#include "../kernel/head.h"
|
#include "../kernel/head.h"
|
||||||
|
|
||||||
|
@ -199,7 +200,6 @@ void __init setup_bootmem(void)
|
||||||
early_init_fdt_scan_reserved_mem();
|
early_init_fdt_scan_reserved_mem();
|
||||||
dma_contiguous_reserve(dma32_phys_limit);
|
dma_contiguous_reserve(dma32_phys_limit);
|
||||||
memblock_allow_resize();
|
memblock_allow_resize();
|
||||||
memblock_dump_all();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MMU
|
#ifdef CONFIG_MMU
|
||||||
|
@ -654,8 +654,10 @@ void __init paging_init(void)
|
||||||
|
|
||||||
void __init misc_mem_init(void)
|
void __init misc_mem_init(void)
|
||||||
{
|
{
|
||||||
|
arch_numa_init();
|
||||||
sparse_init();
|
sparse_init();
|
||||||
zone_sizes_init();
|
zone_sizes_init();
|
||||||
|
memblock_dump_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
||||||
|
|
Loading…
Add table
Reference in a new issue