Private nodes are already kept out of policy nodemasks (only N_MEMORY nodes are allowed), but an mbind(MPOL_MF_MOVE) walk can still encounter a private-node folio in the range. Skip such folios so mempolicy-driven migration never moves private-node memory.
We already do this for ZONE_DEVICE folios - use the same filter points for ZONE_DEVICE (with an additional point for large pages). Signed-off-by: Gregory Price <[email protected]> --- mm/mempolicy.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 5720f7f54d942..8e8763f6e5f5b 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -111,6 +111,7 @@ #include <linux/mmu_notifier.h> #include <linux/printk.h> #include <linux/leafops.h> +#include <linux/node_private.h> #include <linux/gcd.h> #include <asm/tlbflush.h> @@ -668,6 +669,8 @@ static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk) } if (!queue_folio_required(folio, qp)) return; + if (folio_is_private_node(folio)) + return; if (!(qp->flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) || !vma_migratable(walk->vma) || !migrate_folio_add(folio, qp->pagelist, qp->flags)) @@ -722,7 +725,7 @@ static int queue_folios_pte_range(pmd_t *pmd, unsigned long addr, continue; } folio = vm_normal_folio(vma, addr, ptent); - if (!folio || folio_is_zone_device(folio)) + if (!folio || folio_is_private_managed(folio)) continue; if (folio_test_large(folio) && max_nr != 1) nr = folio_pte_batch(folio, pte, ptent, max_nr); @@ -797,6 +800,8 @@ static int queue_folios_hugetlb(pte_t *pte, unsigned long hmask, folio = pfn_folio(pte_pfn(ptep)); if (!queue_folio_required(folio, qp)) goto unlock; + if (folio_is_private_node(folio)) + goto unlock; if (!(flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) || !vma_migratable(walk->vma)) { qp->nr_failed++; -- 2.53.0-Meta

