diff options
Diffstat (limited to 'mm/sparse.c')
-rw-r--r-- | mm/sparse.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/mm/sparse.c b/mm/sparse.c index a83de2f72b30..6b5fb762e2ca 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
@@ -638,7 +638,6 @@ static struct page *__kmalloc_section_memmap(unsigned long nr_pages) | |||
638 | got_map_page: | 638 | got_map_page: |
639 | ret = (struct page *)pfn_to_kaddr(page_to_pfn(page)); | 639 | ret = (struct page *)pfn_to_kaddr(page_to_pfn(page)); |
640 | got_map_ptr: | 640 | got_map_ptr: |
641 | memset(ret, 0, memmap_size); | ||
642 | 641 | ||
643 | return ret; | 642 | return ret; |
644 | } | 643 | } |
@@ -758,6 +757,8 @@ int __meminit sparse_add_one_section(struct zone *zone, unsigned long start_pfn, | |||
758 | goto out; | 757 | goto out; |
759 | } | 758 | } |
760 | 759 | ||
760 | memset(memmap, 0, sizeof(struct page) * nr_pages); | ||
761 | |||
761 | ms->section_mem_map |= SECTION_MARKED_PRESENT; | 762 | ms->section_mem_map |= SECTION_MARKED_PRESENT; |
762 | 763 | ||
763 | ret = sparse_init_one_section(ms, section_nr, memmap, usemap); | 764 | ret = sparse_init_one_section(ms, section_nr, memmap, usemap); |
@@ -771,6 +772,27 @@ out: | |||
771 | return ret; | 772 | return ret; |
772 | } | 773 | } |
773 | 774 | ||
775 | #ifdef CONFIG_MEMORY_FAILURE | ||
776 | static void clear_hwpoisoned_pages(struct page *memmap, int nr_pages) | ||
777 | { | ||
778 | int i; | ||
779 | |||
780 | if (!memmap) | ||
781 | return; | ||
782 | |||
783 | for (i = 0; i < PAGES_PER_SECTION; i++) { | ||
784 | if (PageHWPoison(&memmap[i])) { | ||
785 | atomic_long_sub(1, &mce_bad_pages); | ||
786 | ClearPageHWPoison(&memmap[i]); | ||
787 | } | ||
788 | } | ||
789 | } | ||
790 | #else | ||
791 | static inline void clear_hwpoisoned_pages(struct page *memmap, int nr_pages) | ||
792 | { | ||
793 | } | ||
794 | #endif | ||
795 | |||
774 | void sparse_remove_one_section(struct zone *zone, struct mem_section *ms) | 796 | void sparse_remove_one_section(struct zone *zone, struct mem_section *ms) |
775 | { | 797 | { |
776 | struct page *memmap = NULL; | 798 | struct page *memmap = NULL; |
@@ -784,6 +806,7 @@ void sparse_remove_one_section(struct zone *zone, struct mem_section *ms) | |||
784 | ms->pageblock_flags = NULL; | 806 | ms->pageblock_flags = NULL; |
785 | } | 807 | } |
786 | 808 | ||
809 | clear_hwpoisoned_pages(memmap, PAGES_PER_SECTION); | ||
787 | free_section_usemap(memmap, usemap); | 810 | free_section_usemap(memmap, usemap); |
788 | } | 811 | } |
789 | #endif | 812 | #endif |