diff --git a/board/recalbox/rpi/kernel-6.6-defconfig-fragment.config b/board/recalbox/rpi/kernel-6.6-defconfig-fragment.config index a3d71e41c51e802ccccd097d598bd571c57bc2f2..30539c4bcbfc7271cb2dc1c0c326f7c1344821c4 100644 --- a/board/recalbox/rpi/kernel-6.6-defconfig-fragment.config +++ b/board/recalbox/rpi/kernel-6.6-defconfig-fragment.config @@ -29,3 +29,8 @@ CONFIG_ZEROPLUS_FF=y # disable module compression CONFIG_MODULE_COMPRESS_NONE=y + +# enable numa emulation +CONFIG_NUMA=y +CONFIG_NODES_SHIFT=4 +CONFIG_NUMA_EMULATION=y \ No newline at end of file diff --git a/board/recalbox/rpi/kernel_patches/6.6/0008-numa-Add-simple-generic-NUMA-emulation.patch b/board/recalbox/rpi/kernel_patches/6.6/0008-numa-Add-simple-generic-NUMA-emulation.patch new file mode 100644 index 0000000000000000000000000000000000000000..53b6785432bdbc6439bef84737b24e0b22a2238b --- /dev/null +++ b/board/recalbox/rpi/kernel_patches/6.6/0008-numa-Add-simple-generic-NUMA-emulation.patch @@ -0,0 +1,208 @@ +From bad99275c0894955845deaeca95476395a6dc7a1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ma=C3=ADra=20Canal?= +Date: Tue, 25 Jun 2024 13:58:03 +0100 +Subject: [PATCH] numa: Add simple generic NUMA emulation + +Add some common code for splitting the memory into N emulated NUMA memory +nodes. + +Individual architecture can then enable selecting this option and use the +existing numa=fake= kernel argument to enable it. + +Memory is always split into equally sized chunks. +--- + arch/arm64/Kconfig | 10 ++++++ + drivers/base/Kconfig | 7 ++++ + drivers/base/Makefile | 1 + + drivers/base/arch_numa.c | 6 ++++ + drivers/base/numa_emulation.c | 67 +++++++++++++++++++++++++++++++++++ + drivers/base/numa_emulation.h | 21 +++++++++++ + 6 files changed, 112 insertions(+) + create mode 100644 drivers/base/numa_emulation.c + create mode 100644 drivers/base/numa_emulation.h + +diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig +index 6d05b69f2318..103200d8c542 100644 +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -1499,6 +1499,16 @@ config NODES_SHIFT + Specify the maximum number of NUMA Nodes available on the target + system. Increases memory reserved to accommodate various tables. + ++config NUMA_EMULATION ++ bool "NUMA emulation" ++ depends on NUMA ++ select GENERIC_ARCH_NUMA_EMULATION ++ help ++ Enable NUMA emulation support. A flat machine will be split into ++ virtual nodes when booted with "numa=fake=N", where N is the number ++ of nodes, the system RAM will be split into N equal chunks, and ++ assigned to each node. ++ + source "kernel/Kconfig.hz" + + config ARCH_SPARSEMEM_ENABLE +diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig +index 2b8fd6bb7da0..1f60cd4dd057 100644 +--- a/drivers/base/Kconfig ++++ b/drivers/base/Kconfig +@@ -230,6 +230,13 @@ config GENERIC_ARCH_NUMA + Enable support for generic NUMA implementation. Currently, RISC-V + and ARM64 use it. + ++config GENERIC_ARCH_NUMA_EMULATION ++ bool ++ depends on GENERIC_ARCH_NUMA ++ help ++ Enable NUMA emulation. Note that NUMA emulation will only be used if ++ the machine has no NUMA node. ++ + config FW_DEVLINK_SYNC_STATE_TIMEOUT + bool "sync_state() behavior defaults to timeout instead of strict" + help +diff --git a/drivers/base/Makefile b/drivers/base/Makefile +index 3079bfe53d04..34fcf5bd7370 100644 +--- a/drivers/base/Makefile ++++ b/drivers/base/Makefile +@@ -25,6 +25,7 @@ obj-$(CONFIG_DEV_COREDUMP) += devcoredump.o + obj-$(CONFIG_GENERIC_MSI_IRQ) += platform-msi.o + obj-$(CONFIG_GENERIC_ARCH_TOPOLOGY) += arch_topology.o + obj-$(CONFIG_GENERIC_ARCH_NUMA) += arch_numa.o ++obj-$(CONFIG_GENERIC_ARCH_NUMA_EMULATION) += numa_emulation.o + obj-$(CONFIG_ACPI) += physical_location.o + + obj-y += test/ +diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c +index 5b59d133b6af..6ad08f681b3c 100644 +--- a/drivers/base/arch_numa.c ++++ b/drivers/base/arch_numa.c +@@ -15,6 +15,8 @@ + + #include + ++#include "numa_emulation.h" ++ + struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; + EXPORT_SYMBOL(node_data); + nodemask_t numa_nodes_parsed __initdata; +@@ -30,6 +32,8 @@ static __init int numa_parse_early_param(char *opt) + return -EINVAL; + if (str_has_prefix(opt, "off")) + numa_off = true; ++ if (str_has_prefix(opt, "fake=")) ++ return numa_emu_cmdline(opt + 5); + + return 0; + } +@@ -471,6 +475,8 @@ void __init arch_numa_init(void) + return; + if (acpi_disabled && !numa_init(of_numa_init)) + return; ++ if (!numa_init(numa_emu_init)) ++ return; + } + + numa_init(dummy_numa_init); +diff --git a/drivers/base/numa_emulation.c b/drivers/base/numa_emulation.c +new file mode 100644 +index 000000000000..df652fa8351b +--- /dev/null ++++ b/drivers/base/numa_emulation.c +@@ -0,0 +1,67 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Simple NUMA emulation. ++ * ++ * Copyright © 2024 Raspberry Pi Ltd ++ * ++ * Author: Maíra Canal ++ * Author: Tvrtko Ursulin ++ */ ++#include ++ ++#include "numa_emulation.h" ++ ++static unsigned int emu_nodes; ++ ++int __init numa_emu_cmdline(char *str) ++{ ++ int ret; ++ ++ ret = kstrtouint(str, 10, &emu_nodes); ++ if (ret) ++ return ret; ++ ++ if (emu_nodes > MAX_NUMNODES) { ++ pr_notice("numa=fake=%u too large, reducing to %u\n", ++ emu_nodes, MAX_NUMNODES); ++ emu_nodes = MAX_NUMNODES; ++ } ++ ++ return 0; ++} ++ ++int __init numa_emu_init(void) ++{ ++ phys_addr_t start, end; ++ unsigned long size; ++ unsigned int i; ++ int ret; ++ ++ if (!emu_nodes) ++ return -EINVAL; ++ ++ start = memblock_start_of_DRAM(); ++ end = memblock_end_of_DRAM() - 1; ++ ++ size = DIV_ROUND_DOWN_ULL(end - start + 1, emu_nodes); ++ size = PAGE_ALIGN_DOWN(size); ++ ++ for (i = 0; i < emu_nodes; i++) { ++ u64 s, e; ++ ++ s = start + i * size; ++ e = s + size - 1; ++ ++ if (i == (emu_nodes - 1) && e != end) ++ e = end; ++ ++ pr_info("Faking a node at [mem %pap-%pap]\n", &s, &e); ++ ret = numa_add_memblk(i, s, e + 1); ++ if (ret) { ++ pr_err("Failed to add fake NUMA node %d!\n", i); ++ break; ++ } ++ } ++ ++ return ret; ++} +diff --git a/drivers/base/numa_emulation.h b/drivers/base/numa_emulation.h +new file mode 100644 +index 000000000000..62b38215a2f0 +--- /dev/null ++++ b/drivers/base/numa_emulation.h +@@ -0,0 +1,21 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * NUMA emulation header ++ * ++ * Copyright © 2024 Raspberry Pi Ltd ++ */ ++ ++#ifdef CONFIG_GENERIC_ARCH_NUMA_EMULATION ++int numa_emu_cmdline(char *str); ++int __init numa_emu_init(void); ++#else ++static inline int numa_emu_cmdline(char *str) ++{ ++ return -EINVAL; ++} ++ ++static int __init numa_emu_init(void) ++{ ++ return -EOPNOTSUPP; ++} ++#endif /* CONFIG_NUMA_EMU */ +-- +2.43.0 + diff --git a/configs/recalbox-rpi5_64_defconfig b/configs/recalbox-rpi5_64_defconfig index c2aa1192b50c004a4bf20e41aeb688f00d257ad5..712fec027253c588fe6c8cb49e6cb839a90a8483 100644 --- a/configs/recalbox-rpi5_64_defconfig +++ b/configs/recalbox-rpi5_64_defconfig @@ -364,3 +364,4 @@ BR2_PACKAGE_RTL88X2BU=y BR2_PACKAGE_RTW89=y BR2_PACKAGE_RPI_FIRMWARE_CMDLINE_FILE="$(BR2_EXTERNAL_RECALBOX_PATH)/board/recalbox/rpi/cmdline.txt" BR2_PACKAGE_XPADNEO=y +BR2_PACKAGE_NUMACTL=y \ No newline at end of file