diff options
author | Wen Congyang <wency@cn.fujitsu.com> | 2013-02-22 19:32:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-23 20:50:12 -0500 |
commit | 24d335ca3606b610ec69c66a1e42760c96d89470 (patch) | |
tree | 62d6157cbb273c029ea1052690725037524cbbeb | |
parent | 46c66c4b7ba0f9bb3e2ae3a3cfd40cd3472c8f80 (diff) |
memory-hotplug: introduce new arch_remove_memory() for removing page table
For removing memory, we need to remove page tables. But it depends on
architecture. So the patch introduce arch_remove_memory() for removing
page table. Now it only calls __remove_pages().
Note: __remove_pages() for some archtecuture is not implemented
(I don't know how to implement it for s390).
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Jiang Liu <jiang.liu@huawei.com>
Cc: Jianguo Wu <wujianguo@huawei.com>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Wu Jianguo <wujianguo@huawei.com>
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/ia64/mm/init.c | 18 | ||||
-rw-r--r-- | arch/powerpc/mm/mem.c | 12 | ||||
-rw-r--r-- | arch/s390/mm/init.c | 12 | ||||
-rw-r--r-- | arch/sh/mm/init.c | 17 | ||||
-rw-r--r-- | arch/tile/mm/init.c | 8 | ||||
-rw-r--r-- | arch/x86/mm/init_32.c | 12 | ||||
-rw-r--r-- | arch/x86/mm/init_64.c | 15 | ||||
-rw-r--r-- | include/linux/memory_hotplug.h | 1 | ||||
-rw-r--r-- | mm/memory_hotplug.c | 2 |
9 files changed, 97 insertions, 0 deletions
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index b755ea92aea7..20bc967c7209 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c | |||
@@ -688,6 +688,24 @@ int arch_add_memory(int nid, u64 start, u64 size) | |||
688 | 688 | ||
689 | return ret; | 689 | return ret; |
690 | } | 690 | } |
691 | |||
692 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
693 | int arch_remove_memory(u64 start, u64 size) | ||
694 | { | ||
695 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
696 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
697 | struct zone *zone; | ||
698 | int ret; | ||
699 | |||
700 | zone = page_zone(pfn_to_page(start_pfn)); | ||
701 | ret = __remove_pages(zone, start_pfn, nr_pages); | ||
702 | if (ret) | ||
703 | pr_warn("%s: Problem encountered in __remove_pages() as" | ||
704 | " ret=%d\n", __func__, ret); | ||
705 | |||
706 | return ret; | ||
707 | } | ||
708 | #endif | ||
691 | #endif | 709 | #endif |
692 | 710 | ||
693 | /* | 711 | /* |
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 0dba5066c22a..09c64518b4d0 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
@@ -133,6 +133,18 @@ int arch_add_memory(int nid, u64 start, u64 size) | |||
133 | 133 | ||
134 | return __add_pages(nid, zone, start_pfn, nr_pages); | 134 | return __add_pages(nid, zone, start_pfn, nr_pages); |
135 | } | 135 | } |
136 | |||
137 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
138 | int arch_remove_memory(u64 start, u64 size) | ||
139 | { | ||
140 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
141 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
142 | struct zone *zone; | ||
143 | |||
144 | zone = page_zone(pfn_to_page(start_pfn)); | ||
145 | return __remove_pages(zone, start_pfn, nr_pages); | ||
146 | } | ||
147 | #endif | ||
136 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 148 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
137 | 149 | ||
138 | /* | 150 | /* |
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index ae672f41c464..49ce6bb2c641 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
@@ -228,4 +228,16 @@ int arch_add_memory(int nid, u64 start, u64 size) | |||
228 | vmem_remove_mapping(start, size); | 228 | vmem_remove_mapping(start, size); |
229 | return rc; | 229 | return rc; |
230 | } | 230 | } |
231 | |||
232 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
233 | int arch_remove_memory(u64 start, u64 size) | ||
234 | { | ||
235 | /* | ||
236 | * There is no hardware or firmware interface which could trigger a | ||
237 | * hot memory remove on s390. So there is nothing that needs to be | ||
238 | * implemented. | ||
239 | */ | ||
240 | return -EBUSY; | ||
241 | } | ||
242 | #endif | ||
231 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 243 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 82cc576fab15..105794037143 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c | |||
@@ -558,4 +558,21 @@ int memory_add_physaddr_to_nid(u64 addr) | |||
558 | EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); | 558 | EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); |
559 | #endif | 559 | #endif |
560 | 560 | ||
561 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
562 | int arch_remove_memory(u64 start, u64 size) | ||
563 | { | ||
564 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
565 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
566 | struct zone *zone; | ||
567 | int ret; | ||
568 | |||
569 | zone = page_zone(pfn_to_page(start_pfn)); | ||
570 | ret = __remove_pages(zone, start_pfn, nr_pages); | ||
571 | if (unlikely(ret)) | ||
572 | pr_warn("%s: Failed, __remove_pages() == %d\n", __func__, | ||
573 | ret); | ||
574 | |||
575 | return ret; | ||
576 | } | ||
577 | #endif | ||
561 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 578 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c index ef29d6c5e10e..2749515a0547 100644 --- a/arch/tile/mm/init.c +++ b/arch/tile/mm/init.c | |||
@@ -935,6 +935,14 @@ int remove_memory(u64 start, u64 size) | |||
935 | { | 935 | { |
936 | return -EINVAL; | 936 | return -EINVAL; |
937 | } | 937 | } |
938 | |||
939 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
940 | int arch_remove_memory(u64 start, u64 size) | ||
941 | { | ||
942 | /* TODO */ | ||
943 | return -EBUSY; | ||
944 | } | ||
945 | #endif | ||
938 | #endif | 946 | #endif |
939 | 947 | ||
940 | struct kmem_cache *pgd_cache; | 948 | struct kmem_cache *pgd_cache; |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index b299724f6e34..2d19001151d5 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -862,6 +862,18 @@ int arch_add_memory(int nid, u64 start, u64 size) | |||
862 | 862 | ||
863 | return __add_pages(nid, zone, start_pfn, nr_pages); | 863 | return __add_pages(nid, zone, start_pfn, nr_pages); |
864 | } | 864 | } |
865 | |||
866 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
867 | int arch_remove_memory(u64 start, u64 size) | ||
868 | { | ||
869 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
870 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
871 | struct zone *zone; | ||
872 | |||
873 | zone = page_zone(pfn_to_page(start_pfn)); | ||
874 | return __remove_pages(zone, start_pfn, nr_pages); | ||
875 | } | ||
876 | #endif | ||
865 | #endif | 877 | #endif |
866 | 878 | ||
867 | /* | 879 | /* |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 3eba7f429880..b6dd1c480b30 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -707,6 +707,21 @@ int arch_add_memory(int nid, u64 start, u64 size) | |||
707 | } | 707 | } |
708 | EXPORT_SYMBOL_GPL(arch_add_memory); | 708 | EXPORT_SYMBOL_GPL(arch_add_memory); |
709 | 709 | ||
710 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
711 | int __ref arch_remove_memory(u64 start, u64 size) | ||
712 | { | ||
713 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
714 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
715 | struct zone *zone; | ||
716 | int ret; | ||
717 | |||
718 | zone = page_zone(pfn_to_page(start_pfn)); | ||
719 | ret = __remove_pages(zone, start_pfn, nr_pages); | ||
720 | WARN_ON_ONCE(ret); | ||
721 | |||
722 | return ret; | ||
723 | } | ||
724 | #endif | ||
710 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 725 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
711 | 726 | ||
712 | static struct kcore_list kcore_vsyscall; | 727 | static struct kcore_list kcore_vsyscall; |
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 8dd0950a6a7a..31a563bbd936 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h | |||
@@ -96,6 +96,7 @@ extern void __online_page_free(struct page *page); | |||
96 | 96 | ||
97 | #ifdef CONFIG_MEMORY_HOTREMOVE | 97 | #ifdef CONFIG_MEMORY_HOTREMOVE |
98 | extern bool is_pageblock_removable_nolock(struct page *page); | 98 | extern bool is_pageblock_removable_nolock(struct page *page); |
99 | extern int arch_remove_memory(u64 start, u64 size); | ||
99 | #endif /* CONFIG_MEMORY_HOTREMOVE */ | 100 | #endif /* CONFIG_MEMORY_HOTREMOVE */ |
100 | 101 | ||
101 | /* reasonably generic interface to expand the physical pages in a zone */ | 102 | /* reasonably generic interface to expand the physical pages in a zone */ |
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index a776dbf3fa00..942b43f6d736 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -1513,6 +1513,8 @@ repeat: | |||
1513 | /* remove memmap entry */ | 1513 | /* remove memmap entry */ |
1514 | firmware_map_remove(start, start + size, "System RAM"); | 1514 | firmware_map_remove(start, start + size, "System RAM"); |
1515 | 1515 | ||
1516 | arch_remove_memory(start, size); | ||
1517 | |||
1516 | unlock_memory_hotplug(); | 1518 | unlock_memory_hotplug(); |
1517 | 1519 | ||
1518 | return 0; | 1520 | return 0; |