diff mbox

[v22,2/8] arm64: limit memory regions based on DT property, usable-memory-range

Message ID 20160721005756.GN20774@linaro.org
State New
Headers show

Commit Message

AKASHI Takahiro July 21, 2016, 12:57 a.m. UTC
James,

On Mon, Jul 18, 2016 at 07:04:33PM +0100, James Morse wrote:
> Hi!

> 

> (CC: Dennis Chen)

> 

> On 12/07/16 06:05, AKASHI Takahiro wrote:

> > Crash dump kernel will be run with a limited range of memory as System

> > RAM.

> > 

> > On arm64, we will use a device-tree property under /chosen,

> >    linux,usable-memory-range = <BASE SIZE>

> > in order for primary kernel either on uefi or non-uefi (device tree only)

> > system to hand over the information about usable memory region to crash

> > dump kernel. This property will supercede entries in uefi memory map table

> > and "memory" nodes in a device tree.

> 

> > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c

> > index 51b1302..d8b296f 100644

> > --- a/arch/arm64/mm/init.c

> > +++ b/arch/arm64/mm/init.c

> > @@ -300,10 +300,48 @@ static int __init early_mem(char *p)

> >  }

> >  early_param("mem", early_mem);

> >  

> > +static int __init early_init_dt_scan_usablemem(unsigned long node,

> > +		const char *uname, int depth, void *data)

> > +{

> > +	struct memblock_region *usablemem = (struct memblock_region *)data;

> > +	const __be32 *reg;

> > +	int len;

> > +

> > +	usablemem->size = 0;

> > +

> > +	if (depth != 1 || strcmp(uname, "chosen") != 0)

> > +		return 0;

> > +

> > +	reg = of_get_flat_dt_prop(node, "linux,usable-memory-range", &len);

> > +	if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))

> > +		return 1;

> > +

> > +	usablemem->base = dt_mem_next_cell(dt_root_addr_cells, &reg);

> > +	usablemem->size = dt_mem_next_cell(dt_root_size_cells, &reg);

> > +

> > +	return 1;

> > +}

> > +

> > +static void __init fdt_enforce_memory_region(void)

> > +{

> > +	struct memblock_region reg;

> > +

> > +	of_scan_flat_dt(early_init_dt_scan_usablemem, &reg);

> > +

> > +	if (reg.size) {

> > +		memblock_remove(0, PAGE_ALIGN(reg.base));

> > +		memblock_remove(round_down(reg.base + reg.size, PAGE_SIZE),

> > +				ULLONG_MAX);

> 

> I think this is a new way to trip the problem Dennis Chen has been working on

> [0]. If I kdump with --reuse-cmdline on a kernel booted with 'acpi=on', I get

> the panic below [1]...

> 

> It looks like Dennis's fix involves changes in mm/memblock.c, maybe they can be

> extended to support a range instead of just a limit?


Could you please apply the diff attached below and confirm that
kdump works in your environment?
I can't test it by myself since my hikey board seems to be broken now.

Thanks,
-Takahiro AKASHI

> (It looks like x86 explicitly adds the acpi regions to the crash-kernels memory

> map in crash_setup_memmap_entries()).

> 

> 

> 

> Is it possible for the kernel text to be outside this range? (a bug in

> kexec-tools, or another user of the DT property) If we haven't already failed in

> this case, it may be worth printing a warning, or refusing to

> restrict-memory/expose-vmcore.

> 

> 

> 

> Thanks,

> 

> James

> 

> 

> [0] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/443356.html

> [1]

> [    0.000000] efi: Getting EFI parameters from FDT:

> [    0.000000] efi: EFI v2.50 by ARM Juno EFI Nov 24 2015 12:36:35

> [    0.000000] efi:  ACPI=0xf95b0000  ACPI 2.0=0xf95b0014  PROP=0xfe8db4d8

> [    0.000000] Reserving 1KB of memory at 0x9fffff000 for elfcorehdr

> [    0.000000] cma: Reserved 16 MiB at 0x00000009fec00000

> [    0.000000] ACPI: Early table checksum verification disabled

> [    0.000000] ACPI: RSDP 0x00000000F95B0014 000024 (v02 ARMLTD)

> [    0.000000] ACPI: XSDT 0x00000000F95A00E8 00004C (v01 ARMLTD ARM-JUNO 2014072

> 7      01000013)

> [    0.000000] ACPI: FACP 0x00000000F9500000 00010C (v05 ARMLTD ARM-JUNO 2014072

> 7 ARM  00000099)

> [    0.000000] ACPI: DSDT 0x00000000F94C0000 000396 (v01 ARMLTD ARM-JUNO 2014072

> 7 INTL 20150619)

> [    0.000000] ACPI: GTDT 0x00000000F94F0000 000060 (v02 ARMLTD ARM-JUNO 2014072

> 7 ARM  00000099)

> [    0.000000] ACPI: APIC 0x00000000F94E0000 000224 (v03 ARMLTD ARM-JUNO 2014072

> 7 ARM  00000099)

> [    0.000000] ACPI: SSDT 0x00000000F94D0000 0001E3 (v01 ARMLTD ARM-JUNO 2014072

> 7 INTL 20150619)

> [    0.000000] ACPI: MCFG 0x00000000F94B0000 00003C (v01 ARMLTD ARM-JUNO 2014072

> 7 ARM  00000099)

> ...

> [    0.737577] Serial: AMBA PL011 UART driver

> [    0.786086] HugeTLB registered 2 MB page size, pre-allocated 0 pages

> [    0.794203] ACPI: Added _OSI(Module Device)

> [    0.798659] ACPI: Added _OSI(Processor Device)

> [    0.803190] ACPI: Added _OSI(3.0 _SCP Extensions)

> [    0.807973] ACPI: Added _OSI(Processor Aggregator Device)

> [    0.813653] Unable to handle kernel paging request at virtual address ffff000

> 00804e027

> [    0.821704] pgd = ffff000008cce000

> [    0.825155] [ffff00000804e027] *pgd=00000009ffffd003, *pud=00000009ffffc003,

> *pmd=00000009ffffb003, *pte=00e80000f94c0707

> [    0.836319] Internal error: Oops: 96000021 [#1] PREEMPT SMP

> [    0.841972] Modules linked in:

> [    0.845073] CPU: 2 PID: 1 Comm: swapper/0 Tainted: G S              4.7.0-rc4

> + #4569

> [    0.852927] Hardware name: ARM Juno development board (r1) (DT)

> [    0.858936] task: ffff80003d898000 ti: ffff80003d894000 task.ti: ffff80003d89

> 4000

> [    0.866537] PC is at acpi_ns_lookup+0x23c/0x378

> [    0.871131] LR is at acpi_ds_load1_begin_op+0x88/0x260

> [    0.876340] pc : [<ffff0000084061a4>] lr : [<ffff0000083fc08c>] pstate: 60000

> 045

> [    0.883846] sp : ffff80003d8979b0

> [    0.887206] x29: ffff80003d8979b0 x28: 0000000000000000

> [    0.892596] x27: 000000000000001b x26: ffff000008a80a07

> [    0.897986] x25: ffff80003d897a48 x24: 0000000000000001

> [    0.903377] x23: 0000000000000001 x22: ffff00000804e027

> [    0.908769] x21: 000000000000001b x20: 0000000000000001

> [    0.914158] x19: 0000000000000000 x18: ffff00000804efff

> [    0.919547] x17: 00000000000038ff x16: 0000000000000002

> [    0.924937] x15: ffff00000804efff x14: 0000008000000000

> [    0.930326] x13: ffff000008c942b2 x12: ffff00000804efff

> [    0.935717] x11: ffff000008bf0000 x10: 00000000ffffff76

> [    0.941107] x9 : 0000000000000000 x8 : ffff000008cb6000

> [    0.946498] x7 : 0000000000000000 x6 : ffff80003d897aa8

> [    0.951891] x5 : ffff80003d028400 x4 : 0000000000000001

> [    0.957281] x3 : 0000000000000003 x2 : ffff000008cb6090

> [    0.962673] x1 : 000000000000005f x0 : 0000000000000000

> [    0.968063]

> [    0.969569] Process swapper/0 (pid: 1, stack limit = 0xffff80003d894020)

> [    1.387661] Call trace:

> ...

> [    1.473172] [<ffff0000084061a4>] acpi_ns_lookup+0x23c/0x378

> [    1.478832] [<ffff0000083fc08c>] acpi_ds_load1_begin_op+0x88/0x260

> [    1.485105] [<ffff00000840c0e8>] acpi_ps_build_named_op+0xa8/0x170

> [    1.491378] [<ffff00000840c2e0>] acpi_ps_create_op+0x130/0x230

> [    1.497299] [<ffff00000840bc28>] acpi_ps_parse_loop+0x168/0x580

> [    1.503302] [<ffff00000840cb44>] acpi_ps_parse_aml+0xa0/0x278

> [    1.509135] [<ffff0000084081d0>] acpi_ns_one_complete_parse+0x128/0x150

> [    1.515852] [<ffff00000840821c>] acpi_ns_parse_table+0x24/0x44

> [    1.521775] [<ffff0000084079e8>] acpi_ns_load_table+0x54/0xdc

> [    1.527612] [<ffff000008411038>] acpi_tb_load_namespace+0xd0/0x230

> [    1.533887] [<ffff000008b2695c>] acpi_load_tables+0x3c/0xa8

> [    1.539542] [<ffff000008b25974>] acpi_init+0x88/0x2b0

> [    1.544670] [<ffff000008081a08>] do_one_initcall+0x38/0x128

> [    1.550325] [<ffff000008b00cc0>] kernel_init_freeable+0x14c/0x1f0

> [    1.556517] [<ffff0000087d2088>] kernel_init+0x10/0x100

> [    1.561823] [<ffff000008084e10>] ret_from_fork+0x10/0x40

> [    1.567216] Code: b9008fbb 2a000318 36380054 32190318 (b94002c0)

> [    1.573451] ---[ end trace dec6cecdcba673b7 ]---

> [    1.578158] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00

> 00000b

> [    1.578158]

> [    1.587428] SMP: stopping secondary CPUs

> [    1.591411] ---[ end Kernel panic - not syncing: Attempted to kill init! exit

> code=0x0000000b

> [    0.969225] Process swapper/0 (pid: 1, stack limit = 0xffff80003d894020)

> 

> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Comments

AKASHI Takahiro July 25, 2016, 5:27 a.m. UTC | #1
James,

On Fri, Jul 22, 2016 at 02:55:02PM +0100, James Morse wrote:
> Hi,

> 

> On 21/07/16 01:57, AKASHI Takahiro wrote:

> > Could you please apply the diff attached below and confirm that

> > kdump works in your environment?

> > I can't test it by myself since my hikey board seems to be broken now.

> 

> With this I get a failure even earlier, even with 'acpi=off'.

> With this patch, on boot of the kdump kernel I get:


I think you ran into the problem that I mentioned in:
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/444500.html

You may want to
- apply the change stated above, or
  (Given that we don't know about the configuration of crash dump kernel,
  checking for CONFIG_ZONE_DMA doesn't make sense. Instead, we'd better
  always enforce ARCH_LOW_ADDRESS_LIMIT.)
- explicitly specify the start address (Y) below ARCH_LOW_ADDRESS_LIMIT
  at "crashkernel=X@Y"
Either would work.

Thanks,
-Takahiro AKASHI

> [    0.000000] Linux version 4.7.0-rc4+ (morse@melchizedek) (gcc version 5.2.1 6

> [    0.000000] Boot CPU: AArch64 Processor [411fd071]

> [    0.000000] earlycon: pl11 at MMIO 0x000000007ff80000 (options '')

> [    0.000000] bootconsole [pl11] enabled

> [    0.000000] debug: ignoring loglevel setting.

> [    0.000000] efi: Getting EFI parameters from FDT:

> [    0.000000] efi: EFI v2.50 by ARM Juno EFI Nov 24 2015 12:36:35

> [    0.000000] efi:  ACPI=0xf95b0000  ACPI 2.0=0xf95b0014  PROP=0xfe8db4d8

> [    0.000000] Reserving 1KB of memory at 0x9fffff000 for elfcorehdr

> [    0.000000] cma: Failed to reserve 16 MiB

> [    0.000000] On node 0 totalpages: 132160

> [    0.000000]   DMA zone: 17 pages used for memmap

> [    0.000000]   DMA zone: 0 pages reserved

> [    0.000000]   DMA zone: 1088 pages, LIFO batch:0

> [    0.000000]   Normal zone: 2048 pages used for memmap

> [    0.000000]   Normal zone: 131072 pages, LIFO batch:31

> [    0.000000] bootmem alloc of 64 bytes failed!

> [    0.000000] Kernel panic - not syncing: Out of memory

> [    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.7.0-rc4+ #4600

> [    0.000000] Hardware name: ARM Juno development board (r1) (DT)

> [    0.000000] Call trace:

> [    0.000000] [<ffff0000080889a8>] dump_backtrace+0x0/0x1e8

> [    0.000000] [<ffff000008088ba4>] show_stack+0x14/0x20

> [    0.000000] [<ffff000008363274>] dump_stack+0x94/0xb8

> [    0.000000] [<ffff00000816192c>] panic+0x10c/0x278

> [    0.000000] [<ffff000008b14980>] free_bootmem_late+0x0/0xa0

> [    0.000000] [<ffff000008b14e68>] __alloc_bootmem_low+0x2c/0x38

> [    0.000000] [<ffff000008b02954>] setup_arch+0x2e4/0x5ac

> [    0.000000] [<ffff000008b00854>] start_kernel+0x70/0x390

> [    0.000000] [<ffff000008b001bc>] __primary_switched+0x30/0x6c

> [    0.000000] ---[ end Kernel panic - not syncing: Out of memory

> 

> 

> Trying again, booted with:

> > console=ttyAMA0,115200 earlycon=pl011,0x7ff80000 root=/dev/nfs

> > nfsroot=10.X.X.X:/ubuntu-15.04-server-arm64,v3 resume=/dev/sda2 no_console_suspend

> > ip=dhcp rw crashkernel=512M stacktrace ignore_loglevel=1 acpi=off efi=debug

> memblock=debug

> 

> kexec-tools invoked as:

> > kexec -x --reuse-cmdline --dtb=/sys/firmware/fdt -p /aarch64-Image

> 

> cat /proc/iomem | grep Crash:

> > 9e0000000-9ffffffff : Crash kernel

> 

> crash kernel memblock before call to memblock_cap_memory_range():

> [    0.000000] MEMBLOCK configuration:

> [    0.000000]  memory size = 0x1fef10000 reserved size = 0x4f3b

> [    0.000000]  memory.cnt  = 0x9

> [    0.000000]  memory[0x0]     [0x00000080000000-0x000000dfffffff], 0x60000000

> bytes flags: 0x0

> [    0.000000]  memory[0x1]     [0x000000e00f0000-0x000000f949ffff], 0x193b0000

> bytes flags: 0x0

> (uefi runtime code|data|acpi:)

> [    0.000000]  memory[0x2]     [0x000000f94a0000-0x000000f984ffff], 0x3b0000

> bytes flags: 0x4

> [    0.000000]  memory[0x3]     [0x000000f9850000-0x000000fe81ffff], 0x4fd0000

> bytes flags: 0x0

> (uefi runtime data:)

> [    0.000000]  memory[0x4]     [0x000000fe820000-0x000000fe85ffff], 0x40000

> bytes flags: 0x4

> [    0.000000]  memory[0x5]     [0x000000fe860000-0x000000fe86ffff], 0x10000

> bytes flags: 0x0

> (uefi runtime data:)

> [    0.000000]  memory[0x6]     [0x000000fe870000-0x000000fe8bffff], 0x50000

> bytes flags: 0x4

> [    0.000000]  memory[0x7]     [0x000000fe8c0000-0x000000feffffff], 0x740000

> bytes flags: 0x0

> [    0.000000]  memory[0x8]     [0x00000880000000-0x000009ffffffff], 0x180000000

> bytes flags: 0x0

> [    0.000000]  reserved.cnt  = 0x2

> (uefi memory map:)

> [    0.000000]  reserved[0x0]   [0x000000f985a000-0x000000f985afff], 0x1000

> bytes flags: 0x0

> (device tree:)

> [    0.000000]  reserved[0x1]   [0x000009e0ce0000-0x000009e0ce3f3a], 0x3f3b

> bytes flags: 0x0

> 

> crash kernel memblock after call to memblock_cap_memory_range():

> [    0.000000] MEMBLOCK configuration:

> [    0.000000]  memory size = 0x20440000 reserved size = 0x3f3b

> [    0.000000]  memory.cnt  = 0x4

> [    0.000000]  memory[0x0]     [0x000000f94a0000-0x000000f984ffff], 0x3b0000

> bytes flags: 0x4

> [    0.000000]  memory[0x1]     [0x000000fe820000-0x000000fe85ffff], 0x40000

> bytes flags: 0x4

> [    0.000000]  memory[0x2]     [0x000000fe870000-0x000000fe8bffff], 0x50000

> bytes flags: 0x4

> [    0.000000]  memory[0x3]     [0x000009e0000000-0x000009ffffffff], 0x20000000

> bytes flags: 0x0

> [    0.000000]  reserved.cnt  = 0x1

> [    0.000000]  reserved[0x0]   [0x000009e0ce0000-0x000009e0ce3f3a], 0x3f3b

> bytes flags: 0x0

> (reserve kernel text:)

> [    0.000000] memblock_reserve: [0x000009e0080000-0x000009e0cd0fff] flags 0x0

> arm64_memblock_init+0x1e0/0x40c

> (reserve elfcorehdr:)

> [    0.000000] memblock_reserve: [0x000009fffff000-0x000009fffff3ff] flags 0x0

> arm64_memblock_init+0x37c/0x40c

> [    0.000000] Reserving 1KB of memory at 0x9fffff000 for elfcorehdr

> [    0.000000] cma: Failed to reserve 16 MiB

> ...

> 

> It looks like memblock_cap_memory_range() did exactly what you intended

> 

> This first fault seems to be because memblock_start_of_DRAM() is being dragged

> down by the preserved nomap areas, this means there isn't any usable memory

> within ~4G of memblock_start_of_DRAM()...

> 

> I will dig into the bootmem alloc failure next week...

> 

> (let me know if you want the full boot logs... they are more noise than signal)

> 

> 

> Thanks,

> 

> James

> 

> 

> 

> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
AKASHI Takahiro Aug. 4, 2016, 6:21 a.m. UTC | #2
James,

On Mon, Jul 25, 2016 at 02:27:55PM +0900, AKASHI Takahiro wrote:
> James,

> 

> On Fri, Jul 22, 2016 at 02:55:02PM +0100, James Morse wrote:

> > Hi,

> > 

> > On 21/07/16 01:57, AKASHI Takahiro wrote:

> > > Could you please apply the diff attached below and confirm that

> > > kdump works in your environment?

> > > I can't test it by myself since my hikey board seems to be broken now.

> > 

> > With this I get a failure even earlier, even with 'acpi=off'.

> > With this patch, on boot of the kdump kernel I get:

> 

> I think you ran into the problem that I mentioned in:

> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/444500.html

> 

> You may want to

> - apply the change stated above, or

>   (Given that we don't know about the configuration of crash dump kernel,

>   checking for CONFIG_ZONE_DMA doesn't make sense. Instead, we'd better

>   always enforce ARCH_LOW_ADDRESS_LIMIT.)

> - explicitly specify the start address (Y) below ARCH_LOW_ADDRESS_LIMIT

>   at "crashkernel=X@Y"

> Either would work.


Have these methods fixed your problem in the end?

-Takahiro AKASHI

> Thanks,

> -Takahiro AKASHI

> 

> > [    0.000000] Linux version 4.7.0-rc4+ (morse@melchizedek) (gcc version 5.2.1 6

> > [    0.000000] Boot CPU: AArch64 Processor [411fd071]

> > [    0.000000] earlycon: pl11 at MMIO 0x000000007ff80000 (options '')

> > [    0.000000] bootconsole [pl11] enabled

> > [    0.000000] debug: ignoring loglevel setting.

> > [    0.000000] efi: Getting EFI parameters from FDT:

> > [    0.000000] efi: EFI v2.50 by ARM Juno EFI Nov 24 2015 12:36:35

> > [    0.000000] efi:  ACPI=0xf95b0000  ACPI 2.0=0xf95b0014  PROP=0xfe8db4d8

> > [    0.000000] Reserving 1KB of memory at 0x9fffff000 for elfcorehdr

> > [    0.000000] cma: Failed to reserve 16 MiB

> > [    0.000000] On node 0 totalpages: 132160

> > [    0.000000]   DMA zone: 17 pages used for memmap

> > [    0.000000]   DMA zone: 0 pages reserved

> > [    0.000000]   DMA zone: 1088 pages, LIFO batch:0

> > [    0.000000]   Normal zone: 2048 pages used for memmap

> > [    0.000000]   Normal zone: 131072 pages, LIFO batch:31

> > [    0.000000] bootmem alloc of 64 bytes failed!

> > [    0.000000] Kernel panic - not syncing: Out of memory

> > [    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.7.0-rc4+ #4600

> > [    0.000000] Hardware name: ARM Juno development board (r1) (DT)

> > [    0.000000] Call trace:

> > [    0.000000] [<ffff0000080889a8>] dump_backtrace+0x0/0x1e8

> > [    0.000000] [<ffff000008088ba4>] show_stack+0x14/0x20

> > [    0.000000] [<ffff000008363274>] dump_stack+0x94/0xb8

> > [    0.000000] [<ffff00000816192c>] panic+0x10c/0x278

> > [    0.000000] [<ffff000008b14980>] free_bootmem_late+0x0/0xa0

> > [    0.000000] [<ffff000008b14e68>] __alloc_bootmem_low+0x2c/0x38

> > [    0.000000] [<ffff000008b02954>] setup_arch+0x2e4/0x5ac

> > [    0.000000] [<ffff000008b00854>] start_kernel+0x70/0x390

> > [    0.000000] [<ffff000008b001bc>] __primary_switched+0x30/0x6c

> > [    0.000000] ---[ end Kernel panic - not syncing: Out of memory

> > 

> > 

> > Trying again, booted with:

> > > console=ttyAMA0,115200 earlycon=pl011,0x7ff80000 root=/dev/nfs

> > > nfsroot=10.X.X.X:/ubuntu-15.04-server-arm64,v3 resume=/dev/sda2 no_console_suspend

> > > ip=dhcp rw crashkernel=512M stacktrace ignore_loglevel=1 acpi=off efi=debug

> > memblock=debug

> > 

> > kexec-tools invoked as:

> > > kexec -x --reuse-cmdline --dtb=/sys/firmware/fdt -p /aarch64-Image

> > 

> > cat /proc/iomem | grep Crash:

> > > 9e0000000-9ffffffff : Crash kernel

> > 

> > crash kernel memblock before call to memblock_cap_memory_range():

> > [    0.000000] MEMBLOCK configuration:

> > [    0.000000]  memory size = 0x1fef10000 reserved size = 0x4f3b

> > [    0.000000]  memory.cnt  = 0x9

> > [    0.000000]  memory[0x0]     [0x00000080000000-0x000000dfffffff], 0x60000000

> > bytes flags: 0x0

> > [    0.000000]  memory[0x1]     [0x000000e00f0000-0x000000f949ffff], 0x193b0000

> > bytes flags: 0x0

> > (uefi runtime code|data|acpi:)

> > [    0.000000]  memory[0x2]     [0x000000f94a0000-0x000000f984ffff], 0x3b0000

> > bytes flags: 0x4

> > [    0.000000]  memory[0x3]     [0x000000f9850000-0x000000fe81ffff], 0x4fd0000

> > bytes flags: 0x0

> > (uefi runtime data:)

> > [    0.000000]  memory[0x4]     [0x000000fe820000-0x000000fe85ffff], 0x40000

> > bytes flags: 0x4

> > [    0.000000]  memory[0x5]     [0x000000fe860000-0x000000fe86ffff], 0x10000

> > bytes flags: 0x0

> > (uefi runtime data:)

> > [    0.000000]  memory[0x6]     [0x000000fe870000-0x000000fe8bffff], 0x50000

> > bytes flags: 0x4

> > [    0.000000]  memory[0x7]     [0x000000fe8c0000-0x000000feffffff], 0x740000

> > bytes flags: 0x0

> > [    0.000000]  memory[0x8]     [0x00000880000000-0x000009ffffffff], 0x180000000

> > bytes flags: 0x0

> > [    0.000000]  reserved.cnt  = 0x2

> > (uefi memory map:)

> > [    0.000000]  reserved[0x0]   [0x000000f985a000-0x000000f985afff], 0x1000

> > bytes flags: 0x0

> > (device tree:)

> > [    0.000000]  reserved[0x1]   [0x000009e0ce0000-0x000009e0ce3f3a], 0x3f3b

> > bytes flags: 0x0

> > 

> > crash kernel memblock after call to memblock_cap_memory_range():

> > [    0.000000] MEMBLOCK configuration:

> > [    0.000000]  memory size = 0x20440000 reserved size = 0x3f3b

> > [    0.000000]  memory.cnt  = 0x4

> > [    0.000000]  memory[0x0]     [0x000000f94a0000-0x000000f984ffff], 0x3b0000

> > bytes flags: 0x4

> > [    0.000000]  memory[0x1]     [0x000000fe820000-0x000000fe85ffff], 0x40000

> > bytes flags: 0x4

> > [    0.000000]  memory[0x2]     [0x000000fe870000-0x000000fe8bffff], 0x50000

> > bytes flags: 0x4

> > [    0.000000]  memory[0x3]     [0x000009e0000000-0x000009ffffffff], 0x20000000

> > bytes flags: 0x0

> > [    0.000000]  reserved.cnt  = 0x1

> > [    0.000000]  reserved[0x0]   [0x000009e0ce0000-0x000009e0ce3f3a], 0x3f3b

> > bytes flags: 0x0

> > (reserve kernel text:)

> > [    0.000000] memblock_reserve: [0x000009e0080000-0x000009e0cd0fff] flags 0x0

> > arm64_memblock_init+0x1e0/0x40c

> > (reserve elfcorehdr:)

> > [    0.000000] memblock_reserve: [0x000009fffff000-0x000009fffff3ff] flags 0x0

> > arm64_memblock_init+0x37c/0x40c

> > [    0.000000] Reserving 1KB of memory at 0x9fffff000 for elfcorehdr

> > [    0.000000] cma: Failed to reserve 16 MiB

> > ...

> > 

> > It looks like memblock_cap_memory_range() did exactly what you intended

> > 

> > This first fault seems to be because memblock_start_of_DRAM() is being dragged

> > down by the preserved nomap areas, this means there isn't any usable memory

> > within ~4G of memblock_start_of_DRAM()...

> > 

> > I will dig into the bootmem alloc failure next week...

> > 

> > (let me know if you want the full boot logs... they are more noise than signal)

> > 

> > 

> > Thanks,

> > 

> > James

> > 

> > 

> > 

> > 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
diff mbox

Patch

===8<===
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 4bd55cd..c027275 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -380,11 +380,8 @@  static void __init fdt_enforce_memory_region(void)
 
 	of_scan_flat_dt(early_init_dt_scan_usablemem, &reg);
 
-	if (reg.size) {
-		memblock_remove(0, PAGE_ALIGN(reg.base));
-		memblock_remove(round_down(reg.base + reg.size, PAGE_SIZE),
-				ULLONG_MAX);
-	}
+	if (reg.size)
+		memblock_cap_memory_range(reg.base, reg.size);
 }
 
 void __init arm64_memblock_init(void)
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 3106ac1..9ab17a9 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -333,6 +333,7 @@  phys_addr_t memblock_mem_size(unsigned long limit_pfn);
 phys_addr_t memblock_start_of_DRAM(void);
 phys_addr_t memblock_end_of_DRAM(void);
 void memblock_enforce_memory_limit(phys_addr_t memory_limit);
+void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
 bool memblock_is_memory(phys_addr_t addr);
 int memblock_is_map_memory(phys_addr_t addr);
 int memblock_is_region_memory(phys_addr_t base, phys_addr_t size);
diff --git a/mm/memblock.c b/mm/memblock.c
index ac12489..30badf1 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1486,6 +1486,34 @@  void __init memblock_enforce_memory_limit(phys_addr_t limit)
 			      (phys_addr_t)ULLONG_MAX);
 }
 
+void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size)
+{
+	int start_rgn, end_rgn;
+	int i, ret;
+
+	if (!size)
+		return;
+
+	ret = memblock_isolate_range(&memblock.memory, base, size,
+						&start_rgn, &end_rgn);
+	if (ret)
+		return;
+
+	/* remove all the MAP regions */
+	for (i = memblock.memory.cnt - 1; i >= end_rgn; i--)
+		if (!memblock_is_nomap(&memblock.memory.regions[i]))
+			memblock_remove_region(&memblock.memory, i);
+
+	for (i = start_rgn - 1; i >= 0; i--)
+		if (!memblock_is_nomap(&memblock.memory.regions[i]))
+			memblock_remove_region(&memblock.memory, i);
+
+	/* truncate the reserved regions */
+	memblock_remove_range(&memblock.reserved, 0, base);
+	memblock_remove_range(&memblock.reserved,
+			base + size, (phys_addr_t)ULLONG_MAX);
+}
+
 static int __init_memblock memblock_search(struct memblock_type *type, phys_addr_t addr)
 {
 	unsigned int left = 0, right = type->cnt;