On Wed, Mar 10, 2021 at 02:58:56PM -0800, akpm@xxxxxxxxxxxxxxxxxxxx wrote: > ------------------------------------------------------ > From: Oscar Salvador <osalvador@xxxxxxx> > Subject: x86/vmemmap: handle unpopulated sub-pmd ranges > > When sizeof(struct page) is not a power of 2, sections do not span a PMD > anymore and so when populating them some parts of the PMD will remain > unused. > > Because of this, PMDs will be left behind when depopulating sections since > remove_pmd_table() thinks that those unused parts are still in use. > > Fix this by marking the unused parts with PAGE_UNUSED, so memchr_inv() > will do the right thing and will let us free the PMD when the last user of > it is gone. > > This patch is based on a similar patch by David Hildenbrand: > > https://lore.kernel.org/linux-mm/20200722094558.9828-9-david@xxxxxxxxxx/ > > Link: https://lkml.kernel.org/r/20210309214050.4674-4-osalvador@xxxxxxx > Signed-off-by: Oscar Salvador <osalvador@xxxxxxx> > Reviewed-by: David Hildenbrand <david@xxxxxxxxxx> > Acked-by: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx> > Cc: Andy Lutomirski <luto@xxxxxxxxxx> > Cc: Borislav Petkov <bp@xxxxxxxxx> > Cc: "H . Peter Anvin" <hpa@xxxxxxxxx> > Cc: Ingo Molnar <mingo@xxxxxxxxxx> > Cc: Michal Hocko <mhocko@xxxxxxxxxx> > Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> > Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> > Cc: Zi Yan <ziy@xxxxxxxxxx> > Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Hi Andrew, Could you squash the following on top? It seems that we need to go back to the ifdef version as the IS_ENABLED does not properly work and throws a warning. Thanks a lot diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 13187a3debe9..bbef99622370 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -1123,15 +1123,16 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end, pmd_clear(pmd); spin_unlock(&init_mm.page_table_lock); pages++; - } else if (IS_ENABLED(CONFIG_SPARSEMEM_VMEMMAP) && - vmemmap_pmd_is_unused(addr, next)) { + } +#ifdef CONFIG_SPARSEMEM_VMEMMAP + else if (vmemmap_pmd_is_unused(addr, next)) { free_hugepage_table(pmd_page(*pmd), altmap); spin_lock(&init_mm.page_table_lock); pmd_clear(pmd); spin_unlock(&init_mm.page_table_lock); } - +#endif continue; } -- Oscar Salvador SUSE L3