Message ID | 20210107184032.11815-1-catalin.marinas@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | arm64: Remove arm64_dma32_phys_limit and its uses | expand |
On Thu, Jan 07, 2021 at 06:40:32PM +0000, Catalin Marinas wrote: > With the introduction of a dynamic ZONE_DMA range based on DT or IORT > information, there's no need for CMA allocations from the wider > ZONE_DMA32 since on most platforms ZONE_DMA will cover the 32-bit > addressable range. Remove the arm64_dma32_phys_limit and set > arm64_dma_phys_limit to cover the smallest DMA range required on the > platform. CMA allocation and crashkernel reservation now goes in > the dynamically sized ZONE_DMA. > > Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> > Cc: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> > Cc: Chen Zhou <chenzhou10@huawei.com> > --- > > This patch goes on top of the ARCH_LOW_ADDRESS_LIMIT fix from Nicolas, > already in the arm64 for-next/fixes which fixes a 5.5 issue with > !CONFIG_ZONE_DMA. The changes here depend on the patches in 5.11-rc1. > While they look mostly like clean-ups, they still fix a potential issue > with !CONFIG_ZONE_DMA32 configurations where arm64_dma32_phys_limit > would be equal to PHYS_MASK but we still have a limited ZONE_DMA. In > addition, it now allows proper CMA and crashkernel reservations for > RPi4. [...] > @@ -394,16 +399,9 @@ void __init arm64_memblock_init(void) > > early_init_fdt_scan_reserved_mem(); > > - if (IS_ENABLED(CONFIG_ZONE_DMA32)) > - arm64_dma32_phys_limit = max_zone_phys(32); > - else > - arm64_dma32_phys_limit = PHYS_MASK + 1; > - > reserve_elfcorehdr(); > > high_memory = __va(memblock_end_of_DRAM() - 1) + 1; > - > - dma_contiguous_reserve(arm64_dma32_phys_limit); > } > > void __init bootmem_init(void) > @@ -438,6 +436,11 @@ void __init bootmem_init(void) > sparse_init(); > zone_sizes_init(min, max); > > + /* > + * Reserve the CMA area after arm64_dma_phys_limit was initialised. > + */ > + dma_contiguous_reserve(arm64_dma_phys_limit); Prior to this patch, disabling CONFIG_ZONE_DMA32 leads to CMA allocation from the whole RAM as arm64_dma32_phys_limit becomes PHYS_MASK+1. With this patch (which I plan to merge in 5.11-rc4), we limit the CMA allocation to the 32-bit addressable RAM (if any) even if we don't describe anything in DT or IORT since ZONE_DMA is capped at 32-bit. We could relax this so that ZONE_DMA can be expanded beyond 32-bit with ZONE_DMA32 disabled and no DT/IORT information. Is there a real use-case for such configuration? We might as well make ZONE_DMA depend on ZONE_DMA32 (though given the EXPERT dependency, people should know what they are doing...). An alternative would be to change max_zone_phys() to avoid the U32_MAX cap if ZONE_DMA32 is disabled but I don't think it's worth as I don't see much point in a kernel config with ZONE_DMA enabled and ZONE_DMA32 disabled.
On Mon, 2021-01-11 at 16:57 +0000, Catalin Marinas wrote: > On Thu, Jan 07, 2021 at 06:40:32PM +0000, Catalin Marinas wrote: > > With the introduction of a dynamic ZONE_DMA range based on DT or IORT > > information, there's no need for CMA allocations from the wider > > ZONE_DMA32 since on most platforms ZONE_DMA will cover the 32-bit > > addressable range. Remove the arm64_dma32_phys_limit and set > > arm64_dma_phys_limit to cover the smallest DMA range required on the > > platform. CMA allocation and crashkernel reservation now goes in > > the dynamically sized ZONE_DMA. > > > > Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> > > Cc: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> > > Cc: Chen Zhou <chenzhou10@huawei.com> > > --- > > > > This patch goes on top of the ARCH_LOW_ADDRESS_LIMIT fix from Nicolas, > > already in the arm64 for-next/fixes which fixes a 5.5 issue with > > !CONFIG_ZONE_DMA. The changes here depend on the patches in 5.11-rc1. > > While they look mostly like clean-ups, they still fix a potential issue > > with !CONFIG_ZONE_DMA32 configurations where arm64_dma32_phys_limit > > would be equal to PHYS_MASK but we still have a limited ZONE_DMA. In > > addition, it now allows proper CMA and crashkernel reservations for > > RPi4. > [...] > > @@ -394,16 +399,9 @@ void __init arm64_memblock_init(void) > > > > > > early_init_fdt_scan_reserved_mem(); > > > > > > - if (IS_ENABLED(CONFIG_ZONE_DMA32)) > > - arm64_dma32_phys_limit = max_zone_phys(32); > > - else > > - arm64_dma32_phys_limit = PHYS_MASK + 1; > > - > > reserve_elfcorehdr(); > > > > > > high_memory = __va(memblock_end_of_DRAM() - 1) + 1; > > - > > - dma_contiguous_reserve(arm64_dma32_phys_limit); > > } > > > > > > void __init bootmem_init(void) > > @@ -438,6 +436,11 @@ void __init bootmem_init(void) > > sparse_init(); > > zone_sizes_init(min, max); > > > > > > + /* > > + * Reserve the CMA area after arm64_dma_phys_limit was initialised. > > + */ > > + dma_contiguous_reserve(arm64_dma_phys_limit); > > Prior to this patch, disabling CONFIG_ZONE_DMA32 leads to CMA allocation > from the whole RAM as arm64_dma32_phys_limit becomes PHYS_MASK+1. With > this patch (which I plan to merge in 5.11-rc4), we limit the CMA > allocation to the 32-bit addressable RAM (if any) even if we don't > describe anything in DT or IORT since ZONE_DMA is capped at 32-bit. We > could relax this so that ZONE_DMA can be expanded beyond 32-bit with > ZONE_DMA32 disabled and no DT/IORT information. Is there a real use-case > for such configuration? AFAIK there is a good amount of PCIe cards that depend on 32-bit addressing. So expanding ZONE_DMA beyond 32-bit would potentially break those. That said I don't have any concrete example of people using this. > We might as well make ZONE_DMA depend on ZONE_DMA32 (though given the EXPERT > dependency, people should know what they are doing...). I guess in the long run it'll make things easier to mantain, so it has its value. > An alternative would be to change max_zone_phys() to avoid the U32_MAX > cap if ZONE_DMA32 is disabled but I don't think it's worth as I don't > see much point in a kernel config with ZONE_DMA enabled and ZONE_DMA32 > disabled. Agree, it seems a pointless configuration. On top of that, AFAIK, there isn't any drawback to having a zero sized ZONE_DMA32. Regards, Nicolas
On Thu, 2021-01-07 at 18:40 +0000, Catalin Marinas wrote: > With the introduction of a dynamic ZONE_DMA range based on DT or IORT > information, there's no need for CMA allocations from the wider > ZONE_DMA32 since on most platforms ZONE_DMA will cover the 32-bit > addressable range. Remove the arm64_dma32_phys_limit and set > arm64_dma_phys_limit to cover the smallest DMA range required on the > platform. CMA allocation and crashkernel reservation now goes in > the dynamically sized ZONE_DMA. > > Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> > Cc: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> > Cc: Chen Zhou <chenzhou10@huawei.com> > --- Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> Tested-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> # On RPi4B Regards, Nicolas
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 69ad25fbeae4..ca2cd75d3286 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -94,8 +94,7 @@ #endif /* CONFIG_ARM64_FORCE_52BIT */ extern phys_addr_t arm64_dma_phys_limit; -extern phys_addr_t arm64_dma32_phys_limit; -#define ARCH_LOW_ADDRESS_LIMIT ((arm64_dma_phys_limit ? : arm64_dma32_phys_limit) - 1) +#define ARCH_LOW_ADDRESS_LIMIT (arm64_dma_phys_limit - 1) struct debug_info { #ifdef CONFIG_HAVE_HW_BREAKPOINT diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 7deddf56f7c3..709d98fea90c 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -53,13 +53,13 @@ s64 memstart_addr __ro_after_init = -1; EXPORT_SYMBOL(memstart_addr); /* - * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of - * memory as some devices, namely the Raspberry Pi 4, have peripherals with - * this limited view of the memory. ZONE_DMA32 will cover the rest of the 32 - * bit addressable memory area. + * If the corresponding config options are enabled, we create both ZONE_DMA + * and ZONE_DMA32. By default ZONE_DMA covers the 32-bit addressable memory + * unless restricted on specific platforms (e.g. 30-bit on Raspberry Pi 4). + * In such case, ZONE_DMA32 covers the rest of the 32-bit addressable memory, + * otherwise it is empty. */ phys_addr_t arm64_dma_phys_limit __ro_after_init; -phys_addr_t arm64_dma32_phys_limit __ro_after_init; #ifdef CONFIG_KEXEC_CORE /* @@ -84,7 +84,7 @@ static void __init reserve_crashkernel(void) if (crash_base == 0) { /* Current arm64 boot protocol requires 2MB alignment */ - crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit, + crash_base = memblock_find_in_range(0, arm64_dma_phys_limit, crash_size, SZ_2M); if (crash_base == 0) { pr_warn("cannot allocate crashkernel (size:0x%llx)\n", @@ -196,6 +196,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) unsigned long max_zone_pfns[MAX_NR_ZONES] = {0}; unsigned int __maybe_unused acpi_zone_dma_bits; unsigned int __maybe_unused dt_zone_dma_bits; + phys_addr_t __maybe_unused dma32_phys_limit = max_zone_phys(32); #ifdef CONFIG_ZONE_DMA acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address()); @@ -205,8 +206,12 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit); #endif #ifdef CONFIG_ZONE_DMA32 - max_zone_pfns[ZONE_DMA32] = PFN_DOWN(arm64_dma32_phys_limit); + max_zone_pfns[ZONE_DMA32] = PFN_DOWN(dma32_phys_limit); + if (!arm64_dma_phys_limit) + arm64_dma_phys_limit = dma32_phys_limit; #endif + if (!arm64_dma_phys_limit) + arm64_dma_phys_limit = PHYS_MASK + 1; max_zone_pfns[ZONE_NORMAL] = max; free_area_init(max_zone_pfns); @@ -394,16 +399,9 @@ void __init arm64_memblock_init(void) early_init_fdt_scan_reserved_mem(); - if (IS_ENABLED(CONFIG_ZONE_DMA32)) - arm64_dma32_phys_limit = max_zone_phys(32); - else - arm64_dma32_phys_limit = PHYS_MASK + 1; - reserve_elfcorehdr(); high_memory = __va(memblock_end_of_DRAM() - 1) + 1; - - dma_contiguous_reserve(arm64_dma32_phys_limit); } void __init bootmem_init(void) @@ -438,6 +436,11 @@ void __init bootmem_init(void) sparse_init(); zone_sizes_init(min, max); + /* + * Reserve the CMA area after arm64_dma_phys_limit was initialised. + */ + dma_contiguous_reserve(arm64_dma_phys_limit); + /* * request_standard_resources() depends on crashkernel's memory being * reserved, so do it here. @@ -455,7 +458,7 @@ void __init bootmem_init(void) void __init mem_init(void) { if (swiotlb_force == SWIOTLB_FORCE || - max_pfn > PFN_DOWN(arm64_dma_phys_limit ? : arm64_dma32_phys_limit)) + max_pfn > PFN_DOWN(arm64_dma_phys_limit)) swiotlb_init(1); else swiotlb_force = SWIOTLB_NO_FORCE;
With the introduction of a dynamic ZONE_DMA range based on DT or IORT information, there's no need for CMA allocations from the wider ZONE_DMA32 since on most platforms ZONE_DMA will cover the 32-bit addressable range. Remove the arm64_dma32_phys_limit and set arm64_dma_phys_limit to cover the smallest DMA range required on the platform. CMA allocation and crashkernel reservation now goes in the dynamically sized ZONE_DMA. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> Cc: Chen Zhou <chenzhou10@huawei.com> --- This patch goes on top of the ARCH_LOW_ADDRESS_LIMIT fix from Nicolas, already in the arm64 for-next/fixes which fixes a 5.5 issue with !CONFIG_ZONE_DMA. The changes here depend on the patches in 5.11-rc1. While they look mostly like clean-ups, they still fix a potential issue with !CONFIG_ZONE_DMA32 configurations where arm64_dma32_phys_limit would be equal to PHYS_MASK but we still have a limited ZONE_DMA. In addition, it now allows proper CMA and crashkernel reservations for RPi4. arch/arm64/include/asm/processor.h | 3 +-- arch/arm64/mm/init.c | 33 ++++++++++++++++-------------- 2 files changed, 19 insertions(+), 17 deletions(-)