Loading arch/arm64/mm/init.c +27 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ static void __init arm64_memory_present(void) #endif static phys_addr_t memory_limit = (phys_addr_t)ULLONG_MAX; static phys_addr_t bootloader_memory_limit; /* * Limit the memory size that was specified via FDT. Loading Loading @@ -205,6 +206,11 @@ void __init arm64_memblock_init(void) * via the linear mapping. */ if (memory_limit != (phys_addr_t)ULLONG_MAX) { /* * Save bootloader imposed memory limit before we overwirte * memblock. */ bootloader_memory_limit = memblock_end_of_DRAM(); memblock_enforce_memory_limit(memory_limit); memblock_add(__pa(_text), (u64)(_end - _text)); } Loading Loading @@ -607,4 +613,25 @@ int arch_remove_memory(u64 start, u64 size) } #endif /* CONFIG_MEMORY_HOTREMOVE */ static int arm64_online_page(struct page *page) { unsigned long target_pfn = page_to_pfn(page); unsigned long limit = __phys_to_pfn(bootloader_memory_limit); if (target_pfn >= limit) return -EINVAL; __online_page_set_limits(page); __online_page_increment_counters(page); __online_page_free(page); return 0; } static int __init arm64_memory_hotplug_init(void) { set_online_page_callback(&arm64_online_page); return 0; } subsys_initcall(arm64_memory_hotplug_init); #endif /* CONFIG_MEMORY_HOTPLUG */ include/linux/memory_hotplug.h +1 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ extern int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn, unsigned long *valid_start, unsigned long *valid_end); extern void __offline_isolated_pages(unsigned long, unsigned long); typedef void (*online_page_callback_t)(struct page *page); typedef int (*online_page_callback_t)(struct page *page); extern int set_online_page_callback(online_page_callback_t callback); extern int restore_online_page_callback(online_page_callback_t callback); Loading mm/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -187,7 +187,7 @@ config MEMORY_HOTPLUG bool "Allow for memory hot-add" depends on SPARSEMEM || X86_64_ACPI_NUMA depends on ARCH_ENABLE_MEMORY_HOTPLUG depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390) depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390 || ARM64) config MEMORY_HOTPLUG_SPARSE def_bool y Loading mm/memory_hotplug.c +7 −4 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ * and restore_online_page_callback() for generic callback restore. */ static void generic_online_page(struct page *page); static int generic_online_page(struct page *page); static online_page_callback_t online_page_callback = generic_online_page; static DEFINE_MUTEX(online_page_callback_lock); Loading Loading @@ -857,11 +857,12 @@ void __online_page_free(struct page *page) } EXPORT_SYMBOL_GPL(__online_page_free); static void generic_online_page(struct page *page) static int generic_online_page(struct page *page) { __online_page_set_limits(page); __online_page_increment_counters(page); __online_page_free(page); return 0; } static int online_pages_range(unsigned long start_pfn, unsigned long nr_pages, Loading @@ -870,10 +871,12 @@ static int online_pages_range(unsigned long start_pfn, unsigned long nr_pages, unsigned long i; unsigned long onlined_pages = *(unsigned long *)arg; struct page *page; int ret; if (PageReserved(pfn_to_page(start_pfn))) for (i = 0; i < nr_pages; i++) { page = pfn_to_page(start_pfn + i); (*online_page_callback)(page); ret = (*online_page_callback)(page); if (!ret) onlined_pages++; } *(unsigned long *)arg = onlined_pages; Loading Loading
arch/arm64/mm/init.c +27 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ static void __init arm64_memory_present(void) #endif static phys_addr_t memory_limit = (phys_addr_t)ULLONG_MAX; static phys_addr_t bootloader_memory_limit; /* * Limit the memory size that was specified via FDT. Loading Loading @@ -205,6 +206,11 @@ void __init arm64_memblock_init(void) * via the linear mapping. */ if (memory_limit != (phys_addr_t)ULLONG_MAX) { /* * Save bootloader imposed memory limit before we overwirte * memblock. */ bootloader_memory_limit = memblock_end_of_DRAM(); memblock_enforce_memory_limit(memory_limit); memblock_add(__pa(_text), (u64)(_end - _text)); } Loading Loading @@ -607,4 +613,25 @@ int arch_remove_memory(u64 start, u64 size) } #endif /* CONFIG_MEMORY_HOTREMOVE */ static int arm64_online_page(struct page *page) { unsigned long target_pfn = page_to_pfn(page); unsigned long limit = __phys_to_pfn(bootloader_memory_limit); if (target_pfn >= limit) return -EINVAL; __online_page_set_limits(page); __online_page_increment_counters(page); __online_page_free(page); return 0; } static int __init arm64_memory_hotplug_init(void) { set_online_page_callback(&arm64_online_page); return 0; } subsys_initcall(arm64_memory_hotplug_init); #endif /* CONFIG_MEMORY_HOTPLUG */
include/linux/memory_hotplug.h +1 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ extern int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn, unsigned long *valid_start, unsigned long *valid_end); extern void __offline_isolated_pages(unsigned long, unsigned long); typedef void (*online_page_callback_t)(struct page *page); typedef int (*online_page_callback_t)(struct page *page); extern int set_online_page_callback(online_page_callback_t callback); extern int restore_online_page_callback(online_page_callback_t callback); Loading
mm/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -187,7 +187,7 @@ config MEMORY_HOTPLUG bool "Allow for memory hot-add" depends on SPARSEMEM || X86_64_ACPI_NUMA depends on ARCH_ENABLE_MEMORY_HOTPLUG depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390) depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390 || ARM64) config MEMORY_HOTPLUG_SPARSE def_bool y Loading
mm/memory_hotplug.c +7 −4 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ * and restore_online_page_callback() for generic callback restore. */ static void generic_online_page(struct page *page); static int generic_online_page(struct page *page); static online_page_callback_t online_page_callback = generic_online_page; static DEFINE_MUTEX(online_page_callback_lock); Loading Loading @@ -857,11 +857,12 @@ void __online_page_free(struct page *page) } EXPORT_SYMBOL_GPL(__online_page_free); static void generic_online_page(struct page *page) static int generic_online_page(struct page *page) { __online_page_set_limits(page); __online_page_increment_counters(page); __online_page_free(page); return 0; } static int online_pages_range(unsigned long start_pfn, unsigned long nr_pages, Loading @@ -870,10 +871,12 @@ static int online_pages_range(unsigned long start_pfn, unsigned long nr_pages, unsigned long i; unsigned long onlined_pages = *(unsigned long *)arg; struct page *page; int ret; if (PageReserved(pfn_to_page(start_pfn))) for (i = 0; i < nr_pages; i++) { page = pfn_to_page(start_pfn + i); (*online_page_callback)(page); ret = (*online_page_callback)(page); if (!ret) onlined_pages++; } *(unsigned long *)arg = onlined_pages; Loading