Commit 24d335ca3606b610ec69c66a1e42760c96d89470

Authored by Wen Congyang
Committed by Linus Torvalds
1 parent 46c66c4b7b

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>

Showing 9 changed files with 97 additions and 0 deletions Side-by-side Diff

... ... @@ -688,6 +688,24 @@
688 688  
689 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 709 #endif
692 710  
693 711 /*
arch/powerpc/mm/mem.c
... ... @@ -133,6 +133,18 @@
133 133  
134 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 148 #endif /* CONFIG_MEMORY_HOTPLUG */
137 149  
138 150 /*
... ... @@ -228,5 +228,17 @@
228 228 vmem_remove_mapping(start, size);
229 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 243 #endif /* CONFIG_MEMORY_HOTPLUG */
... ... @@ -558,5 +558,22 @@
558 558 EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
559 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 578 #endif /* CONFIG_MEMORY_HOTPLUG */
... ... @@ -935,6 +935,14 @@
935 935 {
936 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 946 #endif
939 947  
940 948 struct kmem_cache *pgd_cache;
arch/x86/mm/init_32.c
... ... @@ -862,6 +862,18 @@
862 862  
863 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 877 #endif
866 878  
867 879 /*
arch/x86/mm/init_64.c
... ... @@ -707,6 +707,21 @@
707 707 }
708 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 725 #endif /* CONFIG_MEMORY_HOTPLUG */
711 726  
712 727 static struct kcore_list kcore_vsyscall;
include/linux/memory_hotplug.h
... ... @@ -96,6 +96,7 @@
96 96  
97 97 #ifdef CONFIG_MEMORY_HOTREMOVE
98 98 extern bool is_pageblock_removable_nolock(struct page *page);
  99 +extern int arch_remove_memory(u64 start, u64 size);
99 100 #endif /* CONFIG_MEMORY_HOTREMOVE */
100 101  
101 102 /* reasonably generic interface to expand the physical pages in a zone */
... ... @@ -1513,6 +1513,8 @@
1513 1513 /* remove memmap entry */
1514 1514 firmware_map_remove(start, start + size, "System RAM");
1515 1515  
  1516 + arch_remove_memory(start, size);
  1517 +
1516 1518 unlock_memory_hotplug();
1517 1519  
1518 1520 return 0;