From 00159a2013269bc0a617de885e4b921349192bd0 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Tue, 14 Jan 2014 14:21:13 -0500 Subject: ACPI / memhotplug: add parameter to disable memory hotplug When booting a kexec/kdump kernel on a system that has specific memory hotplug regions the boot will fail with warnings like: swapper/0: page allocation failure: order:9, mode:0x84d0 CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.10.0-65.el7.x86_64 #1 Hardware name: QCI QSSC-S4R/QSSC-S4R, BIOS QSSC-S4R.QCI.01.00.S013.032920111005 03/29/2011 0000000000000000 ffff8800341bd8c8 ffffffff815bcc67 ffff8800341bd950 ffffffff8113b1a0 ffff880036339b00 0000000000000009 00000000000084d0 ffff8800341bd950 ffffffff815b87ee 0000000000000000 0000000000000200 Call Trace: [] dump_stack+0x19/0x1b [] warn_alloc_failed+0xf0/0x160 [] ? __alloc_pages_direct_compact+0xac/0x196 [] __alloc_pages_nodemask+0x7ff/0xa00 [] vmemmap_alloc_block+0x62/0xba [] vmemmap_alloc_block_buf+0x15/0x3b [] vmemmap_populate+0xb4/0x21b [] sparse_mem_map_populate+0x27/0x35 [] sparse_add_one_section+0x7a/0x185 [] __add_pages+0xaf/0x240 [] arch_add_memory+0x59/0xd0 [] add_memory+0xb9/0x1b0 [] acpi_memory_device_add+0x18d/0x26d [] acpi_bus_device_attach+0x7d/0xcd [] acpi_ns_walk_namespace+0xc8/0x17f [] ? acpi_bus_type_and_status+0x90/0x90 [] ? acpi_bus_type_and_status+0x90/0x90 [] acpi_walk_namespace+0x95/0xc5 [] acpi_bus_scan+0x8b/0x9d [] acpi_scan_init+0x63/0x160 [] acpi_init+0x25d/0x2a6 [] ? acpi_sleep_proc_init+0x2a/0x2a [] do_one_initcall+0xe2/0x190 [] kernel_init_freeable+0x17c/0x207 [] ? do_early_param+0x88/0x88 [] ? rest_init+0x80/0x80 [] kernel_init+0xe/0x180 [] ret_from_fork+0x7c/0xb0 [] ? rest_init+0x80/0x80 Mem-Info: Node 0 DMA per-cpu: CPU 0: hi: 0, btch: 1 usd: 0 Node 0 DMA32 per-cpu: CPU 0: hi: 42, btch: 7 usd: 0 active_anon:0 inactive_anon:0 isolated_anon:0 active_file:0 inactive_file:0 isolated_file:0 unevictable:0 dirty:0 writeback:0 unstable:0 free:872 slab_reclaimable:13 slab_unreclaimable:1880 mapped:0 shmem:0 pagetables:0 bounce:0 free_cma:0 because the system has run out of memory at boot time. This occurs because of the following sequence in the boot: Main kernel boots and sets E820 map. The second kernel is booted with a map generated by the kdump service using memmap= and memmap=exactmap. These parameters are added to the kernel parameters of the kexec/kdump kernel. The kexec/kdump kernel has limited memory resources so as not to severely impact the main kernel. The system then panics and the kdump/kexec kernel boots (which is a completely new kernel boot). During this boot ACPI is initialized and the kernel (as can be seen above) traverses the ACPI namespace and finds an entry for a memory device to be hotadded. ie) [] __add_pages+0xaf/0x240 [] arch_add_memory+0x59/0xd0 [] add_memory+0xb9/0x1b0 [] acpi_memory_device_add+0x18d/0x26d [] acpi_bus_device_attach+0x7d/0xcd [] acpi_ns_walk_namespace+0xc8/0x17f [] ? acpi_bus_type_and_status+0x90/0x90 [] ? acpi_bus_type_and_status+0x90/0x90 [] acpi_walk_namespace+0x95/0xc5 [] acpi_bus_scan+0x8b/0x9d [] acpi_scan_init+0x63/0x160 [] acpi_init+0x25d/0x2a6 At this point the kernel adds page table information and the the kexec/kdump kernel runs out of memory. This can also be reproduced by using the memmap=exactmap and mem=X parameters on the main kernel and booting. This patchset resolves the problem by adding a kernel parameter, acpi_no_memhotplug, to disable ACPI memory hotplug. Signed-off-by: Prarit Bhargava Acked-by: Vivek Goyal Acked-by: Toshi Kani Acked-by: David Rientjes Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_memhotplug.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 9aeacdfca410..b67be85ff0fc 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -360,7 +360,19 @@ static void acpi_memory_device_remove(struct acpi_device *device) acpi_memory_device_free(mem_device); } +static bool __initdata acpi_no_memhotplug; + void __init acpi_memory_hotplug_init(void) { + if (acpi_no_memhotplug) + return; + acpi_scan_add_handler_with_hotplug(&memory_device_handler, "memory"); } + +static int __init disable_acpi_memory_hotplug(char *str) +{ + acpi_no_memhotplug = true; + return 1; +} +__setup("acpi_no_memhotplug", disable_acpi_memory_hotplug); -- cgit v1.2.3