memcontrol: use N_MEMORY instead N_HIGH_MEMORY
[firefly-linux-kernel-4.4.55.git] / mm / sparse.c
index fac95f2888f2d1fbe923fd83ff7d43786ac89c58..6b5fb762e2caf42eaeddeaef0cf8697175786cfd 100644 (file)
@@ -617,7 +617,7 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
 {
        return; /* XXX: Not implemented yet */
 }
-static void free_map_bootmem(struct page *page, unsigned long nr_pages)
+static void free_map_bootmem(struct page *memmap, unsigned long nr_pages)
 {
 }
 #else
@@ -638,7 +638,6 @@ static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
 got_map_page:
        ret = (struct page *)pfn_to_kaddr(page_to_pfn(page));
 got_map_ptr:
-       memset(ret, 0, memmap_size);
 
        return ret;
 }
@@ -658,10 +657,11 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
                           get_order(sizeof(struct page) * nr_pages));
 }
 
-static void free_map_bootmem(struct page *page, unsigned long nr_pages)
+static void free_map_bootmem(struct page *memmap, unsigned long nr_pages)
 {
        unsigned long maps_section_nr, removing_section_nr, i;
        unsigned long magic;
+       struct page *page = virt_to_page(memmap);
 
        for (i = 0; i < nr_pages; i++, page++) {
                magic = (unsigned long) page->lru.next;
@@ -710,13 +710,10 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap)
         */
 
        if (memmap) {
-               struct page *memmap_page;
-               memmap_page = virt_to_page(memmap);
-
                nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page))
                        >> PAGE_SHIFT;
 
-               free_map_bootmem(memmap_page, nr_pages);
+               free_map_bootmem(memmap, nr_pages);
        }
 }
 
@@ -760,6 +757,8 @@ int __meminit sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
                goto out;
        }
 
+       memset(memmap, 0, sizeof(struct page) * nr_pages);
+
        ms->section_mem_map |= SECTION_MARKED_PRESENT;
 
        ret = sparse_init_one_section(ms, section_nr, memmap, usemap);
@@ -773,6 +772,27 @@ out:
        return ret;
 }
 
+#ifdef CONFIG_MEMORY_FAILURE
+static void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
+{
+       int i;
+
+       if (!memmap)
+               return;
+
+       for (i = 0; i < PAGES_PER_SECTION; i++) {
+               if (PageHWPoison(&memmap[i])) {
+                       atomic_long_sub(1, &mce_bad_pages);
+                       ClearPageHWPoison(&memmap[i]);
+               }
+       }
+}
+#else
+static inline void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
+{
+}
+#endif
+
 void sparse_remove_one_section(struct zone *zone, struct mem_section *ms)
 {
        struct page *memmap = NULL;
@@ -786,6 +806,7 @@ void sparse_remove_one_section(struct zone *zone, struct mem_section *ms)
                ms->pageblock_flags = NULL;
        }
 
+       clear_hwpoisoned_pages(memmap, PAGES_PER_SECTION);
        free_section_usemap(memmap, usemap);
 }
 #endif