From: Greg Kroah-Hartman Date: Wed, 27 Jan 2021 09:57:50 +0000 (+0100) Subject: drop queue-5.10/mm-fix-initialization-of-struct-page-for-holes-in-memory-layout.patch X-Git-Tag: v4.19.171~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8399ea8341ae62bddc429c8d7d034a8380e35197;p=thirdparty%2Fkernel%2Fstable-queue.git drop queue-5.10/mm-fix-initialization-of-struct-page-for-holes-in-memory-layout.patch --- diff --git a/queue-5.10/mm-fix-initialization-of-struct-page-for-holes-in-memory-layout.patch b/queue-5.10/mm-fix-initialization-of-struct-page-for-holes-in-memory-layout.patch deleted file mode 100644 index 41c71376511..00000000000 --- a/queue-5.10/mm-fix-initialization-of-struct-page-for-holes-in-memory-layout.patch +++ /dev/null @@ -1,192 +0,0 @@ -From d3921cb8be29ce5668c64e23ffdaeec5f8c69399 Mon Sep 17 00:00:00 2001 -From: Mike Rapoport -Date: Sat, 23 Jan 2021 21:01:02 -0800 -Subject: mm: fix initialization of struct page for holes in memory layout - -From: Mike Rapoport - -commit d3921cb8be29ce5668c64e23ffdaeec5f8c69399 upstream. - -There could be struct pages that are not backed by actual physical -memory. This can happen when the actual memory bank is not a multiple -of SECTION_SIZE or when an architecture does not register memory holes -reserved by the firmware as memblock.memory. - -Such pages are currently initialized using init_unavailable_mem() -function that iterates through PFNs in holes in memblock.memory and if -there is a struct page corresponding to a PFN, the fields if this page -are set to default values and the page is marked as Reserved. - -init_unavailable_mem() does not take into account zone and node the page -belongs to and sets both zone and node links in struct page to zero. - -On a system that has firmware reserved holes in a zone above ZONE_DMA, -for instance in a configuration below: - - # grep -A1 E820 /proc/iomem - 7a17b000-7a216fff : Unknown E820 type - 7a217000-7bffffff : System RAM - -unset zone link in struct page will trigger - - VM_BUG_ON_PAGE(!zone_spans_pfn(page_zone(page), pfn), page); - -because there are pages in both ZONE_DMA32 and ZONE_DMA (unset zone link -in struct page) in the same pageblock. - -Update init_unavailable_mem() to use zone constraints defined by an -architecture to properly setup the zone link and use node ID of the -adjacent range in memblock.memory to set the node link. - -Link: https://lkml.kernel.org/r/20210111194017.22696-3-rppt@kernel.org -Fixes: 73a6e474cb37 ("mm: memmap_init: iterate over memblock regions rather that check each PFN") -Signed-off-by: Mike Rapoport -Reported-by: Andrea Arcangeli -Cc: Andrea Arcangeli -Cc: Baoquan He -Cc: Borislav Petkov -Cc: David Hildenbrand -Cc: "H. Peter Anvin" -Cc: Ingo Molnar -Cc: Mel Gorman -Cc: Michal Hocko -Cc: Qian Cai -Cc: Thomas Gleixner -Cc: Vlastimil Babka -Cc: -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - mm/page_alloc.c | 84 +++++++++++++++++++++++++++++++++----------------------- - 1 file changed, 50 insertions(+), 34 deletions(-) - ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -7003,23 +7003,26 @@ void __init free_area_init_memoryless_no - * Initialize all valid struct pages in the range [spfn, epfn) and mark them - * PageReserved(). Return the number of struct pages that were initialized. - */ --static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn) -+static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn, -+ int zone, int nid) - { -- unsigned long pfn; -+ unsigned long pfn, zone_spfn, zone_epfn; - u64 pgcnt = 0; - -+ zone_spfn = arch_zone_lowest_possible_pfn[zone]; -+ zone_epfn = arch_zone_highest_possible_pfn[zone]; -+ -+ spfn = clamp(spfn, zone_spfn, zone_epfn); -+ epfn = clamp(epfn, zone_spfn, zone_epfn); -+ - for (pfn = spfn; pfn < epfn; pfn++) { - if (!pfn_valid(ALIGN_DOWN(pfn, pageblock_nr_pages))) { - pfn = ALIGN_DOWN(pfn, pageblock_nr_pages) - + pageblock_nr_pages - 1; - continue; - } -- /* -- * Use a fake node/zone (0) for now. Some of these pages -- * (in memblock.reserved but not in memblock.memory) will -- * get re-initialized via reserve_bootmem_region() later. -- */ -- __init_single_page(pfn_to_page(pfn), pfn, 0, 0); -+ -+ __init_single_page(pfn_to_page(pfn), pfn, zone, nid); - __SetPageReserved(pfn_to_page(pfn)); - pgcnt++; - } -@@ -7028,51 +7031,64 @@ static u64 __init init_unavailable_range - } - - /* -- * Only struct pages that are backed by physical memory are zeroed and -- * initialized by going through __init_single_page(). But, there are some -- * struct pages which are reserved in memblock allocator and their fields -- * may be accessed (for example page_to_pfn() on some configuration accesses -- * flags). We must explicitly initialize those struct pages. -+ * Only struct pages that correspond to ranges defined by memblock.memory -+ * are zeroed and initialized by going through __init_single_page() during -+ * memmap_init(). - * -- * This function also addresses a similar issue where struct pages are left -- * uninitialized because the physical address range is not covered by -- * memblock.memory or memblock.reserved. That could happen when memblock -- * layout is manually configured via memmap=, or when the highest physical -- * address (max_pfn) does not end on a section boundary. -+ * But, there could be struct pages that correspond to holes in -+ * memblock.memory. This can happen because of the following reasons: -+ * - phyiscal memory bank size is not necessarily the exact multiple of the -+ * arbitrary section size -+ * - early reserved memory may not be listed in memblock.memory -+ * - memory layouts defined with memmap= kernel parameter may not align -+ * nicely with memmap sections -+ * -+ * Explicitly initialize those struct pages so that: -+ * - PG_Reserved is set -+ * - zone link is set accorging to the architecture constrains -+ * - node is set to node id of the next populated region except for the -+ * trailing hole where last node id is used - */ --static void __init init_unavailable_mem(void) -+static void __init init_zone_unavailable_mem(int zone) - { -- phys_addr_t start, end; -- u64 i, pgcnt; -- phys_addr_t next = 0; -+ unsigned long start, end; -+ int i, nid; -+ u64 pgcnt; -+ unsigned long next = 0; - - /* -- * Loop through unavailable ranges not covered by memblock.memory. -+ * Loop through holes in memblock.memory and initialize struct -+ * pages corresponding to these holes - */ - pgcnt = 0; -- for_each_mem_range(i, &start, &end) { -+ for_each_mem_pfn_range(i, MAX_NUMNODES, &start, &end, &nid) { - if (next < start) -- pgcnt += init_unavailable_range(PFN_DOWN(next), -- PFN_UP(start)); -+ pgcnt += init_unavailable_range(next, start, zone, nid); - next = end; - } - - /* -- * Early sections always have a fully populated memmap for the whole -- * section - see pfn_valid(). If the last section has holes at the -- * end and that section is marked "online", the memmap will be -- * considered initialized. Make sure that memmap has a well defined -- * state. -+ * Last section may surpass the actual end of memory (e.g. we can -+ * have 1Gb section and 512Mb of RAM pouplated). -+ * Make sure that memmap has a well defined state in this case. - */ -- pgcnt += init_unavailable_range(PFN_DOWN(next), -- round_up(max_pfn, PAGES_PER_SECTION)); -+ end = round_up(max_pfn, PAGES_PER_SECTION); -+ pgcnt += init_unavailable_range(next, end, zone, nid); - - /* - * Struct pages that do not have backing memory. This could be because - * firmware is using some of this memory, or for some other reasons. - */ - if (pgcnt) -- pr_info("Zeroed struct page in unavailable ranges: %lld pages", pgcnt); -+ pr_info("Zone %s: zeroed struct page in unavailable ranges: %lld pages", zone_names[zone], pgcnt); -+} -+ -+static void __init init_unavailable_mem(void) -+{ -+ int zone; -+ -+ for (zone = 0; zone < ZONE_MOVABLE; zone++) -+ init_zone_unavailable_mem(zone); - } - #else - static inline void __init init_unavailable_mem(void) diff --git a/queue-5.10/series b/queue-5.10/series index 772c3a03189..62105821961 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -121,7 +121,6 @@ x86-topology-make-__max_die_per_package-available-unconditionally.patch x86-mmx-use-kfpu_387-for-mmx-string-operations.patch x86-setup-don-t-remove-e820_type_ram-for-pfn-0.patch proc_sysctl-fix-oops-caused-by-incorrect-command-parameters.patch -mm-fix-initialization-of-struct-page-for-holes-in-memory-layout.patch mm-memcg-slab-optimize-objcg-stock-draining.patch mm-memcg-fix-memcg-file_dirty-numa-stat.patch mm-fix-numa-stats-for-thp-migration.patch