mm: migrate: check mapcount for THP instead of refcount
[linux-block.git] / mm / memory_hotplug.c
index 70620d0dd923a23bd77bffef4dd8b68f6e33eb14..492560b619998f4827afd988309f92ade519174f 100644 (file)
@@ -154,122 +154,6 @@ static void release_memory_resource(struct resource *res)
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
-void get_page_bootmem(unsigned long info,  struct page *page,
-                     unsigned long type)
-{
-       page->freelist = (void *)type;
-       SetPagePrivate(page);
-       set_page_private(page, info);
-       page_ref_inc(page);
-}
-
-void put_page_bootmem(struct page *page)
-{
-       unsigned long type;
-
-       type = (unsigned long) page->freelist;
-       BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE ||
-              type > MEMORY_HOTPLUG_MAX_BOOTMEM_TYPE);
-
-       if (page_ref_dec_return(page) == 1) {
-               page->freelist = NULL;
-               ClearPagePrivate(page);
-               set_page_private(page, 0);
-               INIT_LIST_HEAD(&page->lru);
-               free_reserved_page(page);
-       }
-}
-
-#ifdef CONFIG_HAVE_BOOTMEM_INFO_NODE
-#ifndef CONFIG_SPARSEMEM_VMEMMAP
-static void register_page_bootmem_info_section(unsigned long start_pfn)
-{
-       unsigned long mapsize, section_nr, i;
-       struct mem_section *ms;
-       struct page *page, *memmap;
-       struct mem_section_usage *usage;
-
-       section_nr = pfn_to_section_nr(start_pfn);
-       ms = __nr_to_section(section_nr);
-
-       /* Get section's memmap address */
-       memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr);
-
-       /*
-        * Get page for the memmap's phys address
-        * XXX: need more consideration for sparse_vmemmap...
-        */
-       page = virt_to_page(memmap);
-       mapsize = sizeof(struct page) * PAGES_PER_SECTION;
-       mapsize = PAGE_ALIGN(mapsize) >> PAGE_SHIFT;
-
-       /* remember memmap's page */
-       for (i = 0; i < mapsize; i++, page++)
-               get_page_bootmem(section_nr, page, SECTION_INFO);
-
-       usage = ms->usage;
-       page = virt_to_page(usage);
-
-       mapsize = PAGE_ALIGN(mem_section_usage_size()) >> PAGE_SHIFT;
-
-       for (i = 0; i < mapsize; i++, page++)
-               get_page_bootmem(section_nr, page, MIX_SECTION_INFO);
-
-}
-#else /* CONFIG_SPARSEMEM_VMEMMAP */
-static void register_page_bootmem_info_section(unsigned long start_pfn)
-{
-       unsigned long mapsize, section_nr, i;
-       struct mem_section *ms;
-       struct page *page, *memmap;
-       struct mem_section_usage *usage;
-
-       section_nr = pfn_to_section_nr(start_pfn);
-       ms = __nr_to_section(section_nr);
-
-       memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr);
-
-       register_page_bootmem_memmap(section_nr, memmap, PAGES_PER_SECTION);
-
-       usage = ms->usage;
-       page = virt_to_page(usage);
-
-       mapsize = PAGE_ALIGN(mem_section_usage_size()) >> PAGE_SHIFT;
-
-       for (i = 0; i < mapsize; i++, page++)
-               get_page_bootmem(section_nr, page, MIX_SECTION_INFO);
-}
-#endif /* !CONFIG_SPARSEMEM_VMEMMAP */
-
-void __init register_page_bootmem_info_node(struct pglist_data *pgdat)
-{
-       unsigned long i, pfn, end_pfn, nr_pages;
-       int node = pgdat->node_id;
-       struct page *page;
-
-       nr_pages = PAGE_ALIGN(sizeof(struct pglist_data)) >> PAGE_SHIFT;
-       page = virt_to_page(pgdat);
-
-       for (i = 0; i < nr_pages; i++, page++)
-               get_page_bootmem(node, page, NODE_INFO);
-
-       pfn = pgdat->node_start_pfn;
-       end_pfn = pgdat_end_pfn(pgdat);
-
-       /* register section info */
-       for (; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
-               /*
-                * Some platforms can assign the same pfn to multiple nodes - on
-                * node0 as well as nodeN.  To avoid registering a pfn against
-                * multiple nodes we check that this pfn does not already
-                * reside in some other nodes.
-                */
-               if (pfn_valid(pfn) && (early_pfn_to_nid(pfn) == node))
-                       register_page_bootmem_info_section(pfn);
-       }
-}
-#endif /* CONFIG_HAVE_BOOTMEM_INFO_NODE */
-
 static int check_pfn_span(unsigned long pfn, unsigned long nr_pages,
                const char *reason)
 {
@@ -961,7 +845,6 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, struct zone *z
        node_states_set_node(nid, &arg);
        if (need_zonelists_rebuild)
                build_all_zonelists(NULL);
-       zone_pcp_update(zone);
 
        /* Basic onlining is complete, allow allocation of onlined pages. */
        undo_isolate_page_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE);
@@ -974,6 +857,7 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, struct zone *z
         */
        shuffle_zone(zone);
 
+       /* reinitialise watermarks and update pcp limits */
        init_per_zone_wmark_min();
 
        kswapd_run(nid);
@@ -1172,6 +1056,7 @@ bool mhp_supports_memmap_on_memory(unsigned long size)
         *       populate a single PMD.
         */
        return memmap_on_memory &&
+              !hugetlb_free_vmemmap_enabled &&
               IS_ENABLED(CONFIG_MHP_MEMMAP_ON_MEMORY) &&
               size == memory_block_size_bytes() &&
               IS_ALIGNED(vmemmap_size, PMD_SIZE) &&
@@ -1829,13 +1714,13 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages)
        adjust_managed_page_count(pfn_to_page(start_pfn), -nr_pages);
        adjust_present_page_count(zone, -nr_pages);
 
+       /* reinitialise watermarks and update pcp limits */
        init_per_zone_wmark_min();
 
        if (!populated_zone(zone)) {
                zone_pcp_reset(zone);
                build_all_zonelists(NULL);
-       } else
-               zone_pcp_update(zone);
+       }
 
        node_states_clear_node(node, &arg);
        if (arg.status_change_nid >= 0) {