diff options
| author | Michal Hocko <mhocko@suse.com> | 2017-09-08 19:11:39 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-08 21:26:46 -0400 |
| commit | 3072e413e305e353cd4654f8a57d953b66e85bf3 (patch) | |
| tree | 8b3d1fd0db081bdbfc58c31a8c590a48ba0cccce | |
| parent | 74eee180b935fcb9b83a56dd7648fb75caf38f0e (diff) | |
mm/memory_hotplug: introduce add_pages
There are new users of memory hotplug emerging. Some of them require
different subset of arch_add_memory. There are some which only require
allocation of struct pages without mapping those pages to the kernel
address space. We currently have __add_pages for that purpose. But this
is rather lowlevel and not very suitable for the code outside of the
memory hotplug. E.g. x86_64 wants to update max_pfn which should be done
by the caller. Introduce add_pages() which should care about those
details if they are needed. Each architecture should define its
implementation and select CONFIG_ARCH_HAS_ADD_PAGES. All others use the
currently existing __add_pages.
Link: http://lkml.kernel.org/r/20170817000548.32038-7-jglisse@redhat.com
Signed-off-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Jérôme Glisse <jglisse@redhat.com>
Acked-by: Balbir Singh <bsingharora@gmail.com>
Cc: Aneesh Kumar <aneesh.kumar@linux.vnet.ibm.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Nellans <dnellans@nvidia.com>
Cc: Evgeny Baskakov <ebaskakov@nvidia.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Mark Hairgrove <mhairgrove@nvidia.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
Cc: Sherry Cheung <SCheung@nvidia.com>
Cc: Subhash Gutti <sgutti@nvidia.com>
Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
Cc: Bob Liu <liubo95@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | arch/x86/Kconfig | 4 | ||||
| -rw-r--r-- | arch/x86/mm/init_64.c | 22 | ||||
| -rw-r--r-- | include/linux/memory_hotplug.h | 11 |
3 files changed, 30 insertions, 7 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 07d9b6c75328..a3e6e6136a47 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -2323,6 +2323,10 @@ source "kernel/livepatch/Kconfig" | |||
| 2323 | 2323 | ||
| 2324 | endmenu | 2324 | endmenu |
| 2325 | 2325 | ||
| 2326 | config ARCH_HAS_ADD_PAGES | ||
| 2327 | def_bool y | ||
| 2328 | depends on X86_64 && ARCH_ENABLE_MEMORY_HOTPLUG | ||
| 2329 | |||
| 2326 | config ARCH_ENABLE_MEMORY_HOTPLUG | 2330 | config ARCH_ENABLE_MEMORY_HOTPLUG |
| 2327 | def_bool y | 2331 | def_bool y |
| 2328 | depends on X86_64 || (X86_32 && HIGHMEM) | 2332 | depends on X86_64 || (X86_32 && HIGHMEM) |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 136422d7d539..048fbe8fc274 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
| @@ -761,7 +761,7 @@ void __init paging_init(void) | |||
| 761 | * After memory hotplug the variables max_pfn, max_low_pfn and high_memory need | 761 | * After memory hotplug the variables max_pfn, max_low_pfn and high_memory need |
| 762 | * updating. | 762 | * updating. |
| 763 | */ | 763 | */ |
| 764 | static void update_end_of_memory_vars(u64 start, u64 size) | 764 | static void update_end_of_memory_vars(u64 start, u64 size) |
| 765 | { | 765 | { |
| 766 | unsigned long end_pfn = PFN_UP(start + size); | 766 | unsigned long end_pfn = PFN_UP(start + size); |
| 767 | 767 | ||
| @@ -772,22 +772,30 @@ static void update_end_of_memory_vars(u64 start, u64 size) | |||
| 772 | } | 772 | } |
| 773 | } | 773 | } |
| 774 | 774 | ||
| 775 | int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) | 775 | int add_pages(int nid, unsigned long start_pfn, |
| 776 | unsigned long nr_pages, bool want_memblock) | ||
| 776 | { | 777 | { |
| 777 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
| 778 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
| 779 | int ret; | 778 | int ret; |
| 780 | 779 | ||
| 781 | init_memory_mapping(start, start + size); | ||
| 782 | |||
| 783 | ret = __add_pages(nid, start_pfn, nr_pages, want_memblock); | 780 | ret = __add_pages(nid, start_pfn, nr_pages, want_memblock); |
| 784 | WARN_ON_ONCE(ret); | 781 | WARN_ON_ONCE(ret); |
| 785 | 782 | ||
| 786 | /* update max_pfn, max_low_pfn and high_memory */ | 783 | /* update max_pfn, max_low_pfn and high_memory */ |
| 787 | update_end_of_memory_vars(start, size); | 784 | update_end_of_memory_vars(start_pfn << PAGE_SHIFT, |
| 785 | nr_pages << PAGE_SHIFT); | ||
| 788 | 786 | ||
| 789 | return ret; | 787 | return ret; |
| 790 | } | 788 | } |
| 789 | |||
| 790 | int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) | ||
| 791 | { | ||
| 792 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
| 793 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
| 794 | |||
| 795 | init_memory_mapping(start, start + size); | ||
| 796 | |||
| 797 | return add_pages(nid, start_pfn, nr_pages, want_memblock); | ||
| 798 | } | ||
| 791 | EXPORT_SYMBOL_GPL(arch_add_memory); | 799 | EXPORT_SYMBOL_GPL(arch_add_memory); |
| 792 | 800 | ||
| 793 | #define PAGE_INUSE 0xFD | 801 | #define PAGE_INUSE 0xFD |
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 5e6e4cc36ff4..0995e1a2b458 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h | |||
| @@ -133,6 +133,17 @@ extern int __remove_pages(struct zone *zone, unsigned long start_pfn, | |||
| 133 | extern int __add_pages(int nid, unsigned long start_pfn, | 133 | extern int __add_pages(int nid, unsigned long start_pfn, |
| 134 | unsigned long nr_pages, bool want_memblock); | 134 | unsigned long nr_pages, bool want_memblock); |
| 135 | 135 | ||
| 136 | #ifndef CONFIG_ARCH_HAS_ADD_PAGES | ||
| 137 | static inline int add_pages(int nid, unsigned long start_pfn, | ||
| 138 | unsigned long nr_pages, bool want_memblock) | ||
| 139 | { | ||
| 140 | return __add_pages(nid, start_pfn, nr_pages, want_memblock); | ||
| 141 | } | ||
| 142 | #else /* ARCH_HAS_ADD_PAGES */ | ||
| 143 | int add_pages(int nid, unsigned long start_pfn, | ||
| 144 | unsigned long nr_pages, bool want_memblock); | ||
| 145 | #endif /* ARCH_HAS_ADD_PAGES */ | ||
| 146 | |||
| 136 | #ifdef CONFIG_NUMA | 147 | #ifdef CONFIG_NUMA |
| 137 | extern int memory_add_physaddr_to_nid(u64 start); | 148 | extern int memory_add_physaddr_to_nid(u64 start); |
| 138 | #else | 149 | #else |
