aboutsummaryrefslogtreecommitdiffstats
path: root/mm/sparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/sparse.c')
-rw-r--r--mm/sparse.c72
1 files changed, 39 insertions, 33 deletions
diff --git a/mm/sparse.c b/mm/sparse.c
index a37be5f9050d..1c91f0d3f6ab 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -620,6 +620,7 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
620 620
621 vmemmap_free(start, end); 621 vmemmap_free(start, end);
622} 622}
623#ifdef CONFIG_MEMORY_HOTREMOVE
623static void free_map_bootmem(struct page *memmap, unsigned long nr_pages) 624static void free_map_bootmem(struct page *memmap, unsigned long nr_pages)
624{ 625{
625 unsigned long start = (unsigned long)memmap; 626 unsigned long start = (unsigned long)memmap;
@@ -627,6 +628,7 @@ static void free_map_bootmem(struct page *memmap, unsigned long nr_pages)
627 628
628 vmemmap_free(start, end); 629 vmemmap_free(start, end);
629} 630}
631#endif /* CONFIG_MEMORY_HOTREMOVE */
630#else 632#else
631static struct page *__kmalloc_section_memmap(unsigned long nr_pages) 633static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
632{ 634{
@@ -664,6 +666,7 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
664 get_order(sizeof(struct page) * nr_pages)); 666 get_order(sizeof(struct page) * nr_pages));
665} 667}
666 668
669#ifdef CONFIG_MEMORY_HOTREMOVE
667static void free_map_bootmem(struct page *memmap, unsigned long nr_pages) 670static void free_map_bootmem(struct page *memmap, unsigned long nr_pages)
668{ 671{
669 unsigned long maps_section_nr, removing_section_nr, i; 672 unsigned long maps_section_nr, removing_section_nr, i;
@@ -690,40 +693,9 @@ static void free_map_bootmem(struct page *memmap, unsigned long nr_pages)
690 put_page_bootmem(page); 693 put_page_bootmem(page);
691 } 694 }
692} 695}
696#endif /* CONFIG_MEMORY_HOTREMOVE */
693#endif /* CONFIG_SPARSEMEM_VMEMMAP */ 697#endif /* CONFIG_SPARSEMEM_VMEMMAP */
694 698
695static void free_section_usemap(struct page *memmap, unsigned long *usemap)
696{
697 struct page *usemap_page;
698 unsigned long nr_pages;
699
700 if (!usemap)
701 return;
702
703 usemap_page = virt_to_page(usemap);
704 /*
705 * Check to see if allocation came from hot-plug-add
706 */
707 if (PageSlab(usemap_page) || PageCompound(usemap_page)) {
708 kfree(usemap);
709 if (memmap)
710 __kfree_section_memmap(memmap, PAGES_PER_SECTION);
711 return;
712 }
713
714 /*
715 * The usemap came from bootmem. This is packed with other usemaps
716 * on the section which has pgdat at boot time. Just keep it as is now.
717 */
718
719 if (memmap) {
720 nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page))
721 >> PAGE_SHIFT;
722
723 free_map_bootmem(memmap, nr_pages);
724 }
725}
726
727/* 699/*
728 * returns the number of sections whose mem_maps were properly 700 * returns the number of sections whose mem_maps were properly
729 * set. If this is <=0, then that means that the passed-in 701 * set. If this is <=0, then that means that the passed-in
@@ -800,6 +772,39 @@ static inline void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
800} 772}
801#endif 773#endif
802 774
775#ifdef CONFIG_MEMORY_HOTREMOVE
776static void free_section_usemap(struct page *memmap, unsigned long *usemap)
777{
778 struct page *usemap_page;
779 unsigned long nr_pages;
780
781 if (!usemap)
782 return;
783
784 usemap_page = virt_to_page(usemap);
785 /*
786 * Check to see if allocation came from hot-plug-add
787 */
788 if (PageSlab(usemap_page) || PageCompound(usemap_page)) {
789 kfree(usemap);
790 if (memmap)
791 __kfree_section_memmap(memmap, PAGES_PER_SECTION);
792 return;
793 }
794
795 /*
796 * The usemap came from bootmem. This is packed with other usemaps
797 * on the section which has pgdat at boot time. Just keep it as is now.
798 */
799
800 if (memmap) {
801 nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page))
802 >> PAGE_SHIFT;
803
804 free_map_bootmem(memmap, nr_pages);
805 }
806}
807
803void sparse_remove_one_section(struct zone *zone, struct mem_section *ms) 808void sparse_remove_one_section(struct zone *zone, struct mem_section *ms)
804{ 809{
805 struct page *memmap = NULL; 810 struct page *memmap = NULL;
@@ -819,4 +824,5 @@ void sparse_remove_one_section(struct zone *zone, struct mem_section *ms)
819 clear_hwpoisoned_pages(memmap, PAGES_PER_SECTION); 824 clear_hwpoisoned_pages(memmap, PAGES_PER_SECTION);
820 free_section_usemap(memmap, usemap); 825 free_section_usemap(memmap, usemap);
821} 826}
822#endif 827#endif /* CONFIG_MEMORY_HOTREMOVE */
828#endif /* CONFIG_MEMORY_HOTPLUG */