On Tue, Jan 19, 2021 at 08:43:27PM -0500, Pavel Tatashin wrote: > On some platforms ZERO_PAGE(0) might end-up in a movable zone. Do not > migrate zero page in gup during longterm pinning as migration of zero page > is not allowed. > > For example, in x86 QEMU with 16G of memory and kernelcore=5G parameter, I > see the following: > > Boot#1: zero_pfn 0x48a8d zero_pfn zone: ZONE_DMA32 > Boot#2: zero_pfn 0x20168d zero_pfn zone: ZONE_MOVABLE > > On x86, empty_zero_page is declared in .bss and depending on the loader > may end up in different physical locations during boots. > > Signed-off-by: Pavel Tatashin <pasha.tatashin@xxxxxxxxxx> > include/linux/mmzone.h | 4 ++++ > mm/gup.c | 2 ++ > 2 files changed, 6 insertions(+) > > diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h > index fc99e9241846..f67427a8f22b 100644 > +++ b/include/linux/mmzone.h > @@ -427,6 +427,10 @@ enum zone_type { > * techniques might use alloc_contig_range() to hide previously > * exposed pages from the buddy again (e.g., to implement some sort > * of memory unplug in virtio-mem). > + * 6. ZERO_PAGE(0), kernelcore/movablecore setups might create > + * situations where ZERO_PAGE(0) which is allocated differently > + * on different platforms may end up in a movable zone. ZERO_PAGE(0) > + * cannot be migrated. > * > * In general, no unmovable allocations that degrade memory offlining > * should end up in ZONE_MOVABLE. Allocators (like alloc_contig_range()) > diff --git a/mm/gup.c b/mm/gup.c > index 857b273e32ac..fdd5cda30a07 100644 > +++ b/mm/gup.c > @@ -1580,6 +1580,8 @@ static long check_and_migrate_cma_pages(struct mm_struct *mm, > * of the CMA zone if possible. > */ > if (is_migrate_cma_page(head)) { > + if (is_zero_pfn(page_to_pfn(head))) > + continue; I think you should put this logic in is_pinnable_page() Jason