From 970175c12f4443f0c6762e8b0e9748a68e4536f7 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 17 Jul 2024 09:33:21 +0100 Subject: [PATCH 1/6] dma-buf: system_heap: Allow specifying maximum allocation order system_heap.max_order= Signed-off-by: Tvrtko Ursulin --- drivers/dma-buf/heaps/system_heap.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index d78cdb9d01e5e4..7518268e882462 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -54,6 +54,11 @@ static gfp_t order_flags[] = {HIGH_ORDER_GFP, HIGH_ORDER_GFP, LOW_ORDER_GFP}; static const unsigned int orders[] = {8, 4, 0}; #define NUM_ORDERS ARRAY_SIZE(orders) +static unsigned int module_max_order = orders[0]; + +module_param_named(max_order, module_max_order, uint, 0400); +MODULE_PARM_DESC(max_order, "Maximum allocation order override."); + static struct sg_table *dup_sg_table(struct sg_table *table) { struct sg_table *new_table; @@ -339,7 +344,7 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap, struct system_heap_buffer *buffer; DEFINE_DMA_BUF_EXPORT_INFO(exp_info); unsigned long size_remaining = len; - unsigned int max_order = orders[0]; + unsigned int max_order = module_max_order; struct dma_buf *dmabuf; struct sg_table *table; struct scatterlist *sg; @@ -433,6 +438,9 @@ static int system_heap_create(void) if (IS_ERR(sys_heap)) return PTR_ERR(sys_heap); + if (module_max_order > orders[0]) + module_max_order = orders[0]; + return 0; } module_init(system_heap_create); From bc40daf5c51bbaca44d53460ed4c18b476a018ab Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 22 May 2024 17:12:16 +0100 Subject: [PATCH 2/6] mm/numa: Allow override of kernel's default NUMA policy Add numa_policy kernel argument to allow overriding the kernel's default NUMA policy at boot time. Syntax identical to what tmpfs accepts as it's mpol argument is accepted. Some examples: numa_policy=interleave numa_policy=interleave=skip-interleave numa_policy=bind:0-3,5,7,9-15 numa_policy=bind=static:1-2 Signed-off-by: Tvrtko Ursulin --- mm/mempolicy.c | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index b646fab3e45e10..25667a45225140 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -3142,7 +3142,9 @@ void __init numa_policy_init(void) /* Reset policy of current process to default */ void numa_default_policy(void) { - do_set_mempolicy(MPOL_DEFAULT, 0, NULL); + struct mempolicy *pol = &default_policy; + + do_set_mempolicy(pol->mode, pol->flags, &pol->nodes); } /* @@ -3159,7 +3161,6 @@ static const char * const policy_modes[] = [MPOL_PREFERRED_MANY] = "prefer (many)", }; -#ifdef CONFIG_TMPFS /** * mpol_parse_str - parse string to mempolicy, for tmpfs mpol mount option. * @str: string containing mempolicy to parse @@ -3172,13 +3173,18 @@ static const char * const policy_modes[] = */ int mpol_parse_str(char *str, struct mempolicy **mpol) { - struct mempolicy *new = NULL; + struct mempolicy *new; unsigned short mode_flags; nodemask_t nodes; char *nodelist = strchr(str, ':'); char *flags = strchr(str, '='); int err = 1, mode; + if (*mpol) + new = *mpol; + else + new = NULL; + if (flags) *flags++ = '\0'; /* terminate mode string */ @@ -3258,9 +3264,16 @@ int mpol_parse_str(char *str, struct mempolicy **mpol) goto out; } - new = mpol_new(mode, mode_flags, &nodes); - if (IS_ERR(new)) - goto out; + if (!new) { + new = mpol_new(mode, mode_flags, &nodes); + if (IS_ERR(new)) + goto out; + } else { + atomic_set(&new->refcnt, 1); + new->mode = mode; + new->flags = mode_flags; + new->home_node = NUMA_NO_NODE; + } /* * Save nodes for mpol_to_str() to show the tmpfs mount options @@ -3293,7 +3306,29 @@ int mpol_parse_str(char *str, struct mempolicy **mpol) *mpol = new; return err; } -#endif /* CONFIG_TMPFS */ + +static int __init setup_numapolicy(char *str) +{ + struct mempolicy pol = { }, *ppol = &pol; + char buf[128]; + int ret; + + if (str) + ret = mpol_parse_str(str, &ppol); + else + ret = -EINVAL; + + if (!ret) { + default_policy = pol; + mpol_to_str(buf, sizeof(buf), &pol); + pr_info("NUMA default policy overridden to '%s'\n", buf); + } else { + pr_warn("Unable to parse numa_policy=\n"); + } + + return ret == 0; +} +__setup("numa_policy=", setup_numapolicy); /** * mpol_to_str - format a mempolicy structure for printing From 6bdfa4c4927c83aed58f9612c86d1d9a5fa61c19 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 29 Jul 2024 16:53:18 +0100 Subject: [PATCH 3/6] numa/emulation: Check emulated zones around the CMA window ... Make sure CMA zones do not straddle the emulated NUMA nodes ... Signed-off-by: Tvrtko Ursulin --- include/linux/cma.h | 6 ++++++ mm/cma.c | 36 ++++++++++++++++++++++++++++++++++++ mm/numa_emulation.c | 6 ++++++ 3 files changed, 48 insertions(+) diff --git a/include/linux/cma.h b/include/linux/cma.h index d15b64f51336df..961e452312cd6d 100644 --- a/include/linux/cma.h +++ b/include/linux/cma.h @@ -56,6 +56,7 @@ extern void cma_reserve_pages_on_error(struct cma *cma); #ifdef CONFIG_CMA struct folio *cma_alloc_folio(struct cma *cma, int order, gfp_t gfp); bool cma_free_folio(struct cma *cma, const struct folio *folio); +int cma_check_range(u64 *start, u64 *end); #else static inline struct folio *cma_alloc_folio(struct cma *cma, int order, gfp_t gfp) { @@ -66,6 +67,11 @@ static inline bool cma_free_folio(struct cma *cma, const struct folio *folio) { return false; } + +static inline int cma_check_range(u64 *start, u64 *end) +{ + return 0; +} #endif #endif diff --git a/mm/cma.c b/mm/cma.c index 2d9fae9392835b..65d2a04ffb985e 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -602,3 +602,39 @@ int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data) return 0; } + +struct cma_check_range_data { + u64 start, end; +}; + +static int check_range(struct cma *cma_, void *data) +{ + struct cma_check_range_data *range = data; + struct cma_check_range_data cma; + bool starts_in_range; + bool ends_in_range; + + cma.start = cma_get_base(cma_); + cma.end = cma.start + cma_get_size(cma_) - 1; + + starts_in_range = cma.start >= range->start && cma.start <= range->end; + ends_in_range = cma.end >= range->start && cma.end <= range->end; + + if (starts_in_range == ends_in_range) + return 0; + + pr_notice("CMA %s [%llx-%llx] straddles range [%llx-%llx]\n", + cma_->name, cma.start, cma.end, range->start, range->end); + + return -EINVAL; +} + +int cma_check_range(u64 *start, u64 *end) +{ + struct cma_check_range_data range = { + .start = *start, + .end = *end, + }; + + return cma_for_each_area(check_range, &range); +} diff --git a/mm/numa_emulation.c b/mm/numa_emulation.c index 031fb9961bf7b2..ef43d8b571c61f 100644 --- a/mm/numa_emulation.c +++ b/mm/numa_emulation.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #define FAKE_NODE_MIN_SIZE ((u64)32 << 20) @@ -51,6 +52,7 @@ static int __init emu_setup_memblk(struct numa_meminfo *ei, { struct numa_memblk *eb = &ei->blk[ei->nr_blks]; struct numa_memblk *pb = &pi->blk[phys_blk]; + int ret; if (ei->nr_blks >= NR_NODE_MEMBLKS) { pr_err("NUMA: Too many emulated memblks, failing emulation\n"); @@ -62,6 +64,10 @@ static int __init emu_setup_memblk(struct numa_meminfo *ei, eb->end = pb->start + size; eb->nid = nid; + ret = cma_check_range(&eb->start, &eb->end); + if (ret) + return ret; + if (emu_nid_to_phys[nid] == NUMA_NO_NODE) emu_nid_to_phys[nid] = pb->nid; From 7b8eb3fd1f6a5e4c30944df3b7c0b3ed7a0893d1 Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Tue, 7 May 2024 19:14:56 +0100 Subject: [PATCH 4/6] config: bcm2711_defconfig/bcm2712_defconfig: Enable NUMA Allow NUMA and NUMA_EMULATION on 64-bit Pi kernels Signed-off-by: Dom Cobley --- arch/arm64/configs/bcm2711_defconfig | 2 ++ arch/arm64/configs/bcm2712_defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm64/configs/bcm2711_defconfig b/arch/arm64/configs/bcm2711_defconfig index 574d867dde98b8..dc58413781539d 100644 --- a/arch/arm64/configs/bcm2711_defconfig +++ b/arch/arm64/configs/bcm2711_defconfig @@ -50,6 +50,7 @@ CONFIG_ARM64_ERRATUM_2441009=y CONFIG_ARM64_VA_BITS_39=y CONFIG_NR_CPUS=4 CONFIG_HOTPLUG_CPU=y +CONFIG_NUMA=y CONFIG_COMPAT=y CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y @@ -90,6 +91,7 @@ CONFIG_CMA=y CONFIG_CMA_AREAS=7 CONFIG_LRU_GEN=y CONFIG_LRU_GEN_ENABLED=y +CONFIG_NUMA_EMU=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_XFRM_USER=m diff --git a/arch/arm64/configs/bcm2712_defconfig b/arch/arm64/configs/bcm2712_defconfig index 2f62f1d6f16576..3a876a259c4068 100644 --- a/arch/arm64/configs/bcm2712_defconfig +++ b/arch/arm64/configs/bcm2712_defconfig @@ -51,6 +51,7 @@ CONFIG_ARM64_16K_PAGES=y CONFIG_ARM64_VA_BITS_47=y CONFIG_NR_CPUS=4 CONFIG_HOTPLUG_CPU=y +CONFIG_NUMA=y CONFIG_COMPAT=y CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y @@ -93,6 +94,7 @@ CONFIG_CMA=y CONFIG_CMA_AREAS=7 CONFIG_LRU_GEN=y CONFIG_LRU_GEN_ENABLED=y +CONFIG_NUMA_EMU=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_XFRM_USER=m From 23f7deac88f7f5fe921fa34d27f494b6606b44f3 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 23 Jul 2024 15:55:54 +0100 Subject: [PATCH 5/6] dts: Move some common rpi settings into rpi files Most 2711 devices and all 2712 device share common bootargs (command lines). Make the common values shared defaults, overriding them were necessary. Signed-off-by: Phil Elwell --- arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts | 4 ---- arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts | 4 ---- arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi | 1 + arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 5 ----- arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi | 5 ----- arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 5 +++++ 6 files changed, 6 insertions(+), 18 deletions(-) diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts index 3906f7cc25af78..a4aae12775dc55 100644 --- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts +++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts @@ -300,10 +300,6 @@ #include "bcm283x-rpi-i2c0mux_0_44.dtsi" / { - chosen { - bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; - }; - /delete-node/ wifi-pwrseq; }; diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts index d876f3d8f0bd9b..668e31d67cf8ea 100644 --- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts +++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts @@ -274,10 +274,6 @@ #include "bcm283x-rpi-i2c0mux_0_44.dtsi" / { - chosen { - bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; - }; - /delete-node/ wifi-pwrseq; }; diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi b/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi index d44bf7bcc7777f..3d4f0a5d8b1ab2 100644 --- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi +++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi @@ -3,6 +3,7 @@ / { chosen: chosen { + bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; }; __overrides__ { diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts index 31e5692f7ed1ca..30a59c577aef05 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts +++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts @@ -389,11 +389,6 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { }; }; / { - chosen: chosen { - bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe"; - stdout-path = "serial10:115200n8"; - }; - fan: cooling_fan { status = "disabled"; compatible = "pwm-fan"; diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi index 6b098c2dd53c0c..0b8dc8027e0ea3 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi +++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi @@ -379,11 +379,6 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { }; }; / { - chosen: chosen { - bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe"; - stdout-path = "serial10:115200n8"; - }; - fan: cooling_fan { status = "disabled"; compatible = "pwm-fan"; diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi index 2986778e0c72d8..be6619f51c6091 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi +++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi @@ -98,6 +98,11 @@ }; / { + chosen: chosen { + bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe"; + stdout-path = "serial10:115200n8"; + }; + aliases: aliases { blconfig = &blconfig; blpubkey = &blpubkey; From f956eb02736650f4d87445be627566a28b75f2b4 Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Thu, 18 Jul 2024 20:22:18 +0100 Subject: [PATCH 6/6] dts: Set preferred numa options in bootargs The default cmdline adjustment is now numa_policy=interleave for 2711 and 2712, and additionally system_heap.max_order=0 iommu_dma_numa_policy=interleave for just 2712 (due to its better iommu support). The key setting numa=fake= is not set here, so we will boot with a single numa region and behaviour should be pretty much unchanged from before this PR. Signed-off-by: Dom Cobley --- arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts | 2 +- arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi | 2 +- arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts index 0a0dfcb733ec57..342d3f0fe22375 100644 --- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts +++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts @@ -148,7 +148,7 @@ / { chosen { - bootargs = "coherent_pool=1M snd_bcm2835.enable_headphones=0"; + bootargs = "coherent_pool=1M snd_bcm2835.enable_headphones=0 numa_policy=interleave"; }; aliases { diff --git a/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi b/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi index 3d4f0a5d8b1ab2..d54b48ea5043a0 100644 --- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi +++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-ds.dtsi @@ -3,7 +3,7 @@ / { chosen: chosen { - bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0"; + bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_headphones=0 numa_policy=interleave"; }; __overrides__ { diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi index be6619f51c6091..e15ee27e5025e6 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi +++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi @@ -99,7 +99,7 @@ / { chosen: chosen { - bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe"; + bootargs = "reboot=w coherent_pool=1M 8250.nr_uarts=1 pci=pcie_bus_safe numa_policy=interleave iommu_dma_numa_policy=interleave system_heap.max_order=0"; stdout-path = "serial10:115200n8"; };