// SPDX-License-Identifier: GPL-2.0
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/sched/mm.h>
#include <linux/mmu_notifier.h>
#include <linux/rmap.h>
#include <linux/swap.h>
#include <linux/mm_inline.h>
#include <linux/kthread.h>
#include <linux/khugepaged.h>
#include <linux/freezer.h>
#include <linux/mman.h>
#include <linux/hashtable.h>
#include <linux/userfaultfd_k.h>
#include <linux/page_idle.h>
#include <linux/page_table_check.h>
#include <linux/rcupdate_wait.h>
#include <linux/leafops.h>
#include <linux/shmem_fs.h>
#include <linux/dax.h>
#include <linux/ksm.h>
#include <linux/pgalloc.h>
#include <linux/backing-dev.h>
#include <linux/cleanup.h>

#include <asm/tlb.h>
#include "internal.h"
#include "page_alloc.h"
#include "mm_slot.h"

enum scan_result {
	SCAN_FAIL,
	SCAN_SUCCEED,
	SCAN_NO_PTE_TABLE,
	SCAN_PMD_MAPPED,
	SCAN_EXCEED_NONE_PTE,
	SCAN_EXCEED_SWAP_PTE,
	SCAN_EXCEED_SHARED_PTE,
	SCAN_PTE_NON_PRESENT,
	SCAN_PTE_UFFD,
	SCAN_PTE_MAPPED_HUGEPAGE,
	SCAN_LACK_REFERENCED_PAGE,
	SCAN_PAGE_NULL,
	SCAN_SCAN_ABORT,
	SCAN_PAGE_COUNT,
	SCAN_PAGE_LRU,
	SCAN_PAGE_LOCK,
	SCAN_PAGE_ANON,
	SCAN_PAGE_LAZYFREE,
	SCAN_PAGE_COMPOUND,
	SCAN_ANY_PROCESS,
	SCAN_VMA_NULL,
	SCAN_VMA_CHECK,
	SCAN_ADDRESS_RANGE,
	SCAN_DEL_PAGE_LRU,
	SCAN_ALLOC_HUGE_PAGE_FAIL,
	SCAN_CGROUP_CHARGE_FAIL,
	SCAN_TRUNCATED,
	SCAN_PAGE_HAS_PRIVATE,
	SCAN_STORE_FAILED,
	SCAN_COPY_MC,
	SCAN_PAGE_FILLED,
	SCAN_PAGE_DIRTY_OR_WRITEBACK,
};

#define CREATE_TRACE_POINTS
#include <trace/events/huge_memory.h>

static struct task_struct *khugepaged_thread __read_mostly;
static DEFINE_MUTEX(khugepaged_mutex);

/*
 * default scan 8*HPAGE_PMD_NR ptes, pte_mapped_hugepage, pmd_mapped,
 * no_pte_table or vmas every 10 second.
 */
static unsigned int khugepaged_pages_to_scan __read_mostly;
static unsigned int khugepaged_pages_collapsed;
static unsigned int khugepaged_full_scans;
static unsigned int khugepaged_scan_sleep_millisecs __read_mostly = 10000;
/* during fragmentation poll the hugepage allocator once every minute */
static unsigned int khugepaged_alloc_sleep_millisecs __read_mostly = 60000;
static unsigned long khugepaged_sleep_expire;
static DEFINE_SPINLOCK(khugepaged_mm_lock);
static DECLARE_WAIT_QUEUE_HEAD(khugepaged_wait);
/*
 * default collapse hugepages if there is at least one pte mapped like
 * it would have happened if the vma was large enough during page
 * fault.
 *
 * Note that these are only respected if collapse was initiated by khugepaged.
 */
#define KHUGEPAGED_MAX_PTES_LIMIT (HPAGE_PMD_NR - 1)
unsigned int khugepaged_max_ptes_none __read_mostly;
static unsigned int khugepaged_max_ptes_swap __read_mostly;
static unsigned int khugepaged_max_ptes_shared __read_mostly;

#define MM_SLOTS_HASH_BITS 10
static DEFINE_READ_MOSTLY_HASHTABLE(mm_slots_hash, MM_SLOTS_HASH_BITS);

static struct kmem_cache *mm_slot_cache __ro_after_init;

#define KHUGEPAGED_MIN_MTHP_ORDER	2

struct collapse_control {
	bool is_khugepaged;

	/* Num pages scanned per node */
	u32 node_load[MAX_NUMNODES];

	/* Num pages scanned (see khugepaged_pages_to_scan) */
	unsigned int progress;

	/* nodemask for allocation fallback */
	nodemask_t alloc_nmask;

	/* Each bit represents a single occupied (!none/zero) page. */
	DECLARE_BITMAP(mthp_present_ptes, MAX_PTRS_PER_PTE);
};

/**
 * struct khugepaged_scan - cursor for scanning
 * @mm_head: the head of the mm list to scan
 * @mm_slot: the current mm_slot we are scanning
 * @address: the next address inside that to be scanned
 *
 * There is only the one khugepaged_scan instance of this cursor structure.
 */
struct khugepaged_scan {
	struct list_head mm_head;
	struct mm_slot *mm_slot;
	unsigned long address;
};

static struct khugepaged_scan khugepaged_scan = {
	.mm_head = LIST_HEAD_INIT(khugepaged_scan.mm_head),
};

#ifdef CONFIG_SYSFS
static ssize_t scan_sleep_millisecs_show(struct kobject *kobj,
					 struct kobj_attribute *attr,
					 char *buf)
{
	return sysfs_emit(buf, "%u\n", khugepaged_scan_sleep_millisecs);
}

static ssize_t __sleep_millisecs_store(const char *buf, size_t count,
				       unsigned int *millisecs)
{
	unsigned int msecs;
	int err;

	err = kstrtouint(buf, 10, &msecs);
	if (err)
		return -EINVAL;

	*millisecs = msecs;
	khugepaged_sleep_expire = 0;
	wake_up_interruptible(&khugepaged_wait);

	return count;
}

static ssize_t scan_sleep_millisecs_store(struct kobject *kobj,
					  struct kobj_attribute *attr,
					  const char *buf, size_t count)
{
	return __sleep_millisecs_store(buf, count, &khugepaged_scan_sleep_millisecs);
}
static struct kobj_attribute scan_sleep_millisecs_attr =
	__ATTR_RW(scan_sleep_millisecs);

static ssize_t alloc_sleep_millisecs_show(struct kobject *kobj,
					  struct kobj_attribute *attr,
					  char *buf)
{
	return sysfs_emit(buf, "%u\n", khugepaged_alloc_sleep_millisecs);
}

static ssize_t alloc_sleep_millisecs_store(struct kobject *kobj,
					   struct kobj_attribute *attr,
					   const char *buf, size_t count)
{
	return __sleep_millisecs_store(buf, count, &khugepaged_alloc_sleep_millisecs);
}
static struct kobj_attribute alloc_sleep_millisecs_attr =
	__ATTR_RW(alloc_sleep_millisecs);

static ssize_t pages_to_scan_show(struct kobject *kobj,
				  struct kobj_attribute *attr,
				  char *buf)
{
	return sysfs_emit(buf, "%u\n", khugepaged_pages_to_scan);
}
static ssize_t pages_to_scan_store(struct kobject *kobj,
				   struct kobj_attribute *attr,
				   const char *buf, size_t count)
{
	unsigned int pages;
	int err;

	err = kstrtouint(buf, 10, &pages);
	if (err || !pages)
		return -EINVAL;

	khugepaged_pages_to_scan = pages;

	return count;
}
static struct kobj_attribute pages_to_scan_attr =
	__ATTR_RW(pages_to_scan);

static ssize_t pages_collapsed_show(struct kobject *kobj,
				    struct kobj_attribute *attr,
				    char *buf)
{
	return sysfs_emit(buf, "%u\n", khugepaged_pages_collapsed);
}
static struct kobj_attribute pages_collapsed_attr =
	__ATTR_RO(pages_collapsed);

static ssize_t full_scans_show(struct kobject *kobj,
			       struct kobj_attribute *attr,
			       char *buf)
{
	return sysfs_emit(buf, "%u\n", khugepaged_full_scans);
}
static struct kobj_attribute full_scans_attr =
	__ATTR_RO(full_scans);

static ssize_t defrag_show(struct kobject *kobj,
			   struct kobj_attribute *attr, char *buf)
{
	return single_hugepage_flag_show(kobj, attr, buf,
					 TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG);
}
static ssize_t defrag_store(struct kobject *kobj,
			    struct kobj_attribute *attr,
			    const char *buf, size_t count)
{
	return single_hugepage_flag_store(kobj, attr, buf, count,
				 TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG);
}
static struct kobj_attribute khugepaged_defrag_attr =
	__ATTR_RW(defrag);

/*
 * max_ptes_none controls if khugepaged should collapse hugepages over
 * any unmapped ptes in turn potentially increasing the memory
 * footprint of the vmas. When max_ptes_none is 0 khugepaged will not
 * reduce the available free memory in the system as it
 * runs. Increasing max_ptes_none will instead potentially reduce the
 * free memory in the system during the khugepaged scan.
 */
static ssize_t max_ptes_none_show(struct kobject *kobj,
				  struct kobj_attribute *attr,
				  char *buf)
{
	return sysfs_emit(buf, "%u\n", khugepaged_max_ptes_none);
}
static ssize_t max_ptes_none_store(struct kobject *kobj,
				   struct kobj_attribute *attr,
				   const char *buf, size_t count)
{
	int err;
	unsigned long max_ptes_none;

	err = kstrtoul(buf, 10, &max_ptes_none);
	if (err || max_ptes_none > KHUGEPAGED_MAX_PTES_LIMIT)
		return -EINVAL;

	khugepaged_max_ptes_none = max_ptes_none;

	return count;
}
static struct kobj_attribute khugepaged_max_ptes_none_attr =
	__ATTR_RW(max_ptes_none);

static ssize_t max_ptes_swap_show(struct kobject *kobj,
				  struct kobj_attribute *attr,
				  char *buf)
{
	return sysfs_emit(buf, "%u\n", khugepaged_max_ptes_swap);
}

static ssize_t max_ptes_swap_store(struct kobject *kobj,
				   struct kobj_attribute *attr,
				   const char *buf, size_t count)
{
	int err;
	unsigned long max_ptes_swap;

	err  = kstrtoul(buf, 10, &max_ptes_swap);
	if (err || max_ptes_swap > KHUGEPAGED_MAX_PTES_LIMIT)
		return -EINVAL;

	khugepaged_max_ptes_swap = max_ptes_swap;

	return count;
}

static struct kobj_attribute khugepaged_max_ptes_swap_attr =
	__ATTR_RW(max_ptes_swap);

static ssize_t max_ptes_shared_show(struct kobject *kobj,
				    struct kobj_attribute *attr,
				    char *buf)
{
	return sysfs_emit(buf, "%u\n", khugepaged_max_ptes_shared);
}

static ssize_t max_ptes_shared_store(struct kobject *kobj,
				     struct kobj_attribute *attr,
				     const char *buf, size_t count)
{
	int err;
	unsigned long max_ptes_shared;

	err  = kstrtoul(buf, 10, &max_ptes_shared);
	if (err || max_ptes_shared > KHUGEPAGED_MAX_PTES_LIMIT)
		return -EINVAL;

	khugepaged_max_ptes_shared = max_ptes_shared;

	return count;
}

static struct kobj_attribute khugepaged_max_ptes_shared_attr =
	__ATTR_RW(max_ptes_shared);

static struct attribute *khugepaged_attr[] = {
	&khugepaged_defrag_attr.attr,
	&khugepaged_max_ptes_none_attr.attr,
	&khugepaged_max_ptes_swap_attr.attr,
	&khugepaged_max_ptes_shared_attr.attr,
	&pages_to_scan_attr.attr,
	&pages_collapsed_attr.attr,
	&full_scans_attr.attr,
	&scan_sleep_millisecs_attr.attr,
	&alloc_sleep_millisecs_attr.attr,
	NULL,
};

struct attribute_group khugepaged_attr_group = {
	.attrs = khugepaged_attr,
	.name = "khugepaged",
};
#endif /* CONFIG_SYSFS */

static bool pte_none_or_zero(pte_t pte)
{
	if (pte_none(pte))
		return true;
	return pte_present(pte) && is_zero_pfn(pte_pfn(pte));
}

/**
 * collapse_max_ptes_none - Calculate maximum allowed empty PTEs or PTEs mapping
 * the shared zeropage for the given collapse operation.
 * @cc: The collapse control struct
 * @vma: The vma to check for userfaultfd
 * @order: The folio order being collapsed to
 *
 * Return: Maximum number of empty/shared zeropage PTEs for the collapse operation
 */
static unsigned int collapse_max_ptes_none(struct collapse_control *cc,
		struct vm_area_struct *vma, unsigned int order)
{
	const unsigned int max_ptes_none = khugepaged_max_ptes_none;

	if (vma && userfaultfd_armed(vma))
		return 0;
	/* for MADV_COLLAPSE, allow any empty/shared zeropage PTEs */
	if (!cc->is_khugepaged)
		return HPAGE_PMD_NR;
	/* for PMD collapse, respect the user defined maximum */
	if (is_pmd_order(order))
		return max_ptes_none;
	/*
	 * for mTHP collapse with the sysctl value set to KHUGEPAGED_MAX_PTES_LIMIT,
	 * scale the maximum number of PTEs to the order of the collapse.
	 */
	if (max_ptes_none == KHUGEPAGED_MAX_PTES_LIMIT)
		return (1 << order) - 1;
	/*
	 * For mTHP collapse of values other than 0 or KHUGEPAGED_MAX_PTES_LIMIT,
	 * emit a warning and return 0.
	 */
	if (max_ptes_none)
		pr_warn_once("mTHP collapse does not support max_ptes_none"
		     " values other than 0 or %u, defaulting to 0.\n",
		     KHUGEPAGED_MAX_PTES_LIMIT);
	return 0;
}

/**
 * collapse_max_ptes_shared - Calculate maximum allowed PTEs that map shared
 * anonymous pages for the given collapse operation.
 * @cc: The collapse control struct
 * @order: The folio order being collapsed to
 *
 * Return: Maximum number of PTEs that map shared anonymous pages for the
 * collapse operation
 */
static unsigned int collapse_max_ptes_shared(struct collapse_control *cc,
		unsigned int order)
{
	/*
	 * For MADV_COLLAPSE, do not restrict the number of PTEs that map shared
	 * anonymous pages.
	 */
	if (!cc->is_khugepaged)
		return HPAGE_PMD_NR;
	/*
	 * for mTHP collapse do not allow collapsing anonymous memory pages that
	 * are shared between processes.
	 */
	if (!is_pmd_order(order))
		return 0;
	/* for PMD collapse, respect the user defined maximum */
	return khugepaged_max_ptes_shared;
}

/**
 * collapse_max_ptes_swap - Calculate the maximum allowed non-present PTEs or the
 * maximum allowed non-present pagecache entries for the given collapse operation.
 * @cc: The collapse control struct
 * @order: The folio order being collapsed to
 *
 * Return: Maximum number of non-present PTEs or the maximum allowed non-present
 * pagecache entries for the collapse operation.
 */
static unsigned int collapse_max_ptes_swap(struct collapse_control *cc,
		unsigned int order)
{
	/*
	 * For MADV_COLLAPSE, do not restrict the number PTEs entries or
	 * pagecache entries that are non-present.
	 */
	if (!cc->is_khugepaged)
		return HPAGE_PMD_NR;
	/* for mTHP collapse do not allow any non-present PTEs or pagecache entries */
	if (!is_pmd_order(order))
		return 0;
	/* for PMD collapse, respect the user defined maximum */
	return khugepaged_max_ptes_swap;
}

int hugepage_madvise(struct vm_area_struct *vma,
		     vm_flags_t *vm_flags, int advice)
{
	switch (advice) {
	case MADV_HUGEPAGE:
		*vm_flags &= ~VM_NOHUGEPAGE;
		*vm_flags |= VM_HUGEPAGE;
		break;
	case MADV_NOHUGEPAGE:
		*vm_flags &= ~VM_HUGEPAGE;
		*vm_flags |= VM_NOHUGEPAGE;
		/*
		 * Setting VM_NOHUGEPAGE will prevent khugepaged from scanning
		 * this vma even if we leave the mm registered in khugepaged if
		 * it got registered before VM_NOHUGEPAGE was set.
		 */
		break;
	}

	return 0;
}

int __init khugepaged_init(void)
{
	mm_slot_cache = KMEM_CACHE(mm_slot, 0);
	if (!mm_slot_cache)
		return -ENOMEM;

	khugepaged_pages_to_scan = HPAGE_PMD_NR * 8;
	khugepaged_max_ptes_none = KHUGEPAGED_MAX_PTES_LIMIT;
	khugepaged_max_ptes_swap = HPAGE_PMD_NR / 8;
	khugepaged_max_ptes_shared = HPAGE_PMD_NR / 2;

	return 0;
}

void __init khugepaged_destroy(void)
{
	kmem_cache_destroy(mm_slot_cache);
}

static inline int collapse_test_exit(struct mm_struct *mm)
{
	return atomic_read(&mm->mm_users) == 0;
}

static inline int collapse_test_exit_or_disable(struct mm_struct *mm)
{
	return collapse_test_exit(mm) ||
		mm_flags_test(MMF_DISABLE_THP_COMPLETELY, mm);
}

static inline bool anon_hpage_enabled(void)
{
	if (READ_ONCE(huge_anon_orders_always))
		return true;
	if (READ_ONCE(huge_anon_orders_madvise))
		return true;
	if (READ_ONCE(huge_anon_orders_inherit) &&
	    hugepage_global_enabled())
		return true;
	return false;
}

static bool hugepage_enabled(void)
{
	/*
	 * We cover the anon, shmem and the file-backed case here; file-backed
	 * hugepages are determined by the global control.
	 * Anon hugepages are determined by its per-size mTHP control.
	 * Shmem pmd-sized hugepages are also determined by its pmd-size control,
	 * except when the global shmem_huge is set to SHMEM_HUGE_DENY.
	 */
	if (hugepage_global_enabled())
		return true;
	if (anon_hpage_enabled())
		return true;
	if (shmem_hpage_pmd_enabled())
		return true;
	return false;
}

void __khugepaged_enter(struct mm_struct *mm)
{
	struct mm_slot *slot;
	int wakeup;

	/* __khugepaged_exit() must not run from under us */
	VM_BUG_ON_MM(collapse_test_exit(mm), mm);

	slot = mm_slot_alloc(mm_slot_cache);
	if (!slot)
		return;

	if (unlikely(mm_flags_test_and_set(MMF_VM_HUGEPAGE, mm))) {
		mm_slot_free(mm_slot_cache, slot);
		return;
	}

	spin_lock(&khugepaged_mm_lock);
	mm_slot_insert(mm_slots_hash, mm, slot);
	/*
	 * Insert just behind the scanning cursor, to let the area settle
	 * down a little.
	 */
	wakeup = list_empty(&khugepaged_scan.mm_head);
	list_add_tail(&slot->mm_node, &khugepaged_scan.mm_head);
	spin_unlock(&khugepaged_mm_lock);

	mmgrab(mm);
	if (wakeup)
		wake_up_interruptible(&khugepaged_wait);
}

/*
 * Check what orders are possible based on the vma and collapse type.
 * This is used to determine if mTHP collapse is a viable option.
 */
static unsigned long collapse_possible_orders(struct vm_area_struct *vma,
		vm_flags_t vm_flags, enum tva_type tva_flags)
{
	unsigned long orders;

	/* If khugepaged is scanning an anonymous vma, allow mTHP collapse */
	if ((tva_flags == TVA_KHUGEPAGED) && vma_is_anonymous(vma))
		orders = THP_ORDERS_ALL_ANON;
	else
		orders = BIT(HPAGE_PMD_ORDER);

	return thp_vma_allowable_orders(vma, vm_flags, tva_flags, orders);
}

static bool collapse_possible(struct vm_area_struct *vma,
		vm_flags_t vm_flags, enum tva_type tva_flags)
{
	return collapse_possible_orders(vma, vm_flags, tva_flags);
}

void khugepaged_enter_vma(struct vm_area_struct *vma,
			  vm_flags_t vm_flags)
{
	if (!mm_flags_test(MMF_VM_HUGEPAGE, vma->vm_mm) && hugepage_enabled()
	    && collapse_possible(vma, vm_flags, TVA_KHUGEPAGED))
		__khugepaged_enter(vma->vm_mm);
}

void __khugepaged_exit(struct mm_struct *mm)
{
	struct mm_slot *slot;
	int free = 0;

	spin_lock(&khugepaged_mm_lock);
	slot = mm_slot_lookup(mm_slots_hash, mm);
	if (slot && khugepaged_scan.mm_slot != slot) {
		mm_slot_remove(slot);
		free = 1;
	}
	spin_unlock(&khugepaged_mm_lock);

	if (free) {
		mm_flags_clear(MMF_VM_HUGEPAGE, mm);
		mm_slot_free(mm_slot_cache, slot);
		mmdrop(mm);
	} else if (slot) {
		/*
		 * This is required to serialize against
		 * collapse_test_exit() (which is guaranteed to run
		 * under mmap_lock read mode). Stop here (after we return all
		 * pagetables will be destroyed) until khugepaged has finished
		 * working on the pagetables under the mmap_lock.
		 */
		mmap_write_lock(mm);
		mmap_write_unlock(mm);
	}
}

static void collapse_control_init_scan(struct collapse_control *cc)
{
	memset(cc->node_load, 0, sizeof(cc->node_load));
	nodes_clear(cc->alloc_nmask);
	bitmap_zero(cc->mthp_present_ptes, MAX_PTRS_PER_PTE);
}

static void release_pte_folio(struct folio *folio)
{
	node_stat_mod_folio(folio,
			NR_ISOLATED_ANON + folio_is_file_lru(folio),
			-folio_nr_pages(folio));
	folio_unlock(folio);
	folio_putback_lru(folio);
}

static void release_pte_pages(pte_t *pte, pte_t *_pte,
		struct list_head *compound_pagelist)
{
	struct folio *folio, *tmp;

	while (--_pte >= pte) {
		pte_t pteval = ptep_get(_pte);
		unsigned long pfn;

		if (pte_none(pteval))
			continue;
		VM_WARN_ON_ONCE(!pte_present(pteval));
		pfn = pte_pfn(pteval);
		if (is_zero_pfn(pfn))
			continue;
		folio = pfn_folio(pfn);
		if (folio_test_large(folio))
			continue;
		release_pte_folio(folio);
	}

	list_for_each_entry_safe(folio, tmp, compound_pagelist, lru) {
		list_del(&folio->lru);
		release_pte_folio(folio);
	}
}

static bool folio_pte_referenced(struct folio *folio,
		struct vm_area_struct *vma, unsigned long addr, pte_t pteval)
{
	/* The folio was referenced previously ... */
	if (folio_test_young(folio) || folio_test_referenced(folio))
		return true;
	/* ... or the PTE mapping was recently used */
	return pte_young(pteval) || mmu_notifier_test_young(vma->vm_mm, addr);
}

static void count_collapse_event(unsigned int order, enum vm_event_item vm_event,
		enum mthp_stat_item mthp_event)
{
	if (is_pmd_order(order))
		count_vm_event(vm_event);
	count_mthp_stat(order, mthp_event);
}

static enum scan_result __collapse_huge_page_isolate(struct vm_area_struct *vma,
		unsigned long start_addr, pte_t *pte, struct collapse_control *cc,
		unsigned int order, struct list_head *compound_pagelist)
{
	const unsigned int max_ptes_none = collapse_max_ptes_none(cc, vma, order);
	const unsigned int max_ptes_shared = collapse_max_ptes_shared(cc, order);
	const unsigned long nr_pages = 1UL << order;
	struct page *page = NULL;
	struct folio *folio = NULL;
	unsigned long addr = start_addr;
	pte_t *_pte;
	int none_or_zero = 0, shared = 0, referenced = 0;
	enum scan_result result = SCAN_FAIL;

	for (_pte = pte; _pte < pte + nr_pages;
	     _pte++, addr += PAGE_SIZE) {
		pte_t pteval = ptep_get(_pte);
		if (pte_none_or_zero(pteval)) {
			if (++none_or_zero > max_ptes_none) {
				result = SCAN_EXCEED_NONE_PTE;
				count_collapse_event(order, THP_SCAN_EXCEED_NONE_PTE,
						     MTHP_STAT_COLLAPSE_EXCEED_NONE);
				goto out;
			}
			continue;
		}
		if (!pte_present(pteval)) {
			result = SCAN_PTE_NON_PRESENT;
			goto out;
		}
		if (pte_uffd(pteval)) {
			result = SCAN_PTE_UFFD;
			goto out;
		}
		page = vm_normal_page(vma, addr, pteval);
		if (unlikely(!page) || unlikely(is_zone_device_page(page))) {
			result = SCAN_PAGE_NULL;
			goto out;
		}

		folio = page_folio(page);
		VM_BUG_ON_FOLIO(!folio_test_anon(folio), folio);

		/*
		 * If the vma has the VM_DROPPABLE flag, the collapse will
		 * preserve the lazyfree property without needing to skip.
		 */
		if (cc->is_khugepaged && !(vma->vm_flags & VM_DROPPABLE) &&
		    folio_test_lazyfree(folio) && !pte_dirty(pteval)) {
			result = SCAN_PAGE_LAZYFREE;
			goto out;
		}

		/* See collapse_scan_pmd(). */
		if (folio_maybe_mapped_shared(folio)) {
			/*
			 * TODO: Support shared pages without leading to further
			 * mTHP collapses. Currently bringing in new pages via
			 * shared may cause a future higher order collapse on a
			 * rescan of the same range.
			 */
			if (++shared > max_ptes_shared) {
				result = SCAN_EXCEED_SHARED_PTE;
				count_collapse_event(order, THP_SCAN_EXCEED_SHARED_PTE,
						     MTHP_STAT_COLLAPSE_EXCEED_SHARED);
				goto out;
			}
		}
		/*
		 * TODO: In some cases of partially-mapped folios, we'd actually
		 * want to collapse.
		 */
		if (!is_pmd_order(order) && folio_order(folio) >= order) {
			result = SCAN_PTE_MAPPED_HUGEPAGE;
			goto out;
		}

		if (folio_test_large(folio)) {
			struct folio *f;

			/*
			 * Check if we have dealt with the compound page
			 * already
			 */
			list_for_each_entry(f, compound_pagelist, lru) {
				if (folio == f)
					goto next;
			}
		}

		/*
		 * We can do it before folio_isolate_lru because the
		 * folio can't be freed from under us. NOTE: folio lock
		 * is needed to serialize against split_huge_page()
		 * when invoked from the VM.
		 */
		if (!folio_trylock(folio)) {
			result = SCAN_PAGE_LOCK;
			goto out;
		}

		/*
		 * Check if the page has any GUP (or other external) pins.
		 *
		 * The page table that maps the page has been already unlinked
		 * from the page table tree and this process cannot get
		 * an additional pin on the page.
		 *
		 * New pins can come later if the page is shared across fork,
		 * but not from this process. The other process cannot write to
		 * the page, only trigger CoW.
		 */
		if (folio_expected_ref_count(folio) != folio_ref_count(folio)) {
			folio_unlock(folio);
			result = SCAN_PAGE_COUNT;
			goto out;
		}

		/*
		 * Isolate the folio to avoid collapsing a hugepage
		 * currently in use by the VM.
		 */
		if (!folio_isolate_lru(folio)) {
			folio_unlock(folio);
			result = SCAN_DEL_PAGE_LRU;
			goto out;
		}
		node_stat_mod_folio(folio,
				NR_ISOLATED_ANON + folio_is_file_lru(folio),
				folio_nr_pages(folio));
		VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
		VM_BUG_ON_FOLIO(folio_test_lru(folio), folio);

		if (folio_test_large(folio))
			list_add_tail(&folio->lru, compound_pagelist);
next:
		if (cc->is_khugepaged &&
		    folio_pte_referenced(folio, vma, addr, pteval))
			referenced++;
	}

	if (unlikely(cc->is_khugepaged && !referenced)) {
		result = SCAN_LACK_REFERENCED_PAGE;
	} else {
		result = SCAN_SUCCEED;
		trace_mm_collapse_huge_page_isolate(folio, none_or_zero,
						    referenced, result, order);
		return result;
	}
out:
	release_pte_pages(pte, _pte, compound_pagelist);
	trace_mm_collapse_huge_page_isolate(folio, none_or_zero,
					    referenced, result, order);
	return result;
}

static void __collapse_huge_page_copy_succeeded(pte_t *pte,
		struct vm_area_struct *vma, unsigned long address,
		spinlock_t *ptl, unsigned int order,
		struct list_head *compound_pagelist)
{
	const unsigned long nr_pages = 1UL << order;
	unsigned long end = address + (PAGE_SIZE * nr_pages);
	struct folio *src, *tmp;
	pte_t pteval;
	pte_t *_pte;
	unsigned int nr_ptes;

	for (_pte = pte; _pte < pte + nr_pages; _pte += nr_ptes,
	     address += nr_ptes * PAGE_SIZE) {
		nr_ptes = 1;
		pteval = ptep_get(_pte);
		if (pte_none_or_zero(pteval)) {
			add_mm_counter(vma->vm_mm, MM_ANONPAGES, 1);
			if (pte_none(pteval))
				continue;
			/*
			 * ptl mostly unnecessary.
			 */
			spin_lock(ptl);
			ptep_clear(vma->vm_mm, address, _pte);
			spin_unlock(ptl);
			ksm_might_unmap_zero_page(vma->vm_mm, pteval);
		} else {
			struct page *src_page = pte_page(pteval);

			src = page_folio(src_page);

			if (folio_test_large(src)) {
				unsigned int max_nr_ptes = (end - address) >> PAGE_SHIFT;

				nr_ptes = folio_pte_batch(src, _pte, pteval, max_nr_ptes);
			} else {
				release_pte_folio(src);
			}

			/*
			 * ptl mostly unnecessary, but preempt has to
			 * be disabled to update the per-cpu stats
			 * inside folio_remove_rmap_pte().
			 */
			spin_lock(ptl);
			clear_ptes(vma->vm_mm, address, _pte, nr_ptes);
			folio_remove_rmap_ptes(src, src_page, nr_ptes, vma);
			spin_unlock(ptl);
			free_swap_cache(src);
			folio_put_refs(src, nr_ptes);
		}
	}

	list_for_each_entry_safe(src, tmp, compound_pagelist, lru) {
		list_del(&src->lru);
		node_stat_sub_folio(src, NR_ISOLATED_ANON +
				folio_is_file_lru(src));
		folio_unlock(src);
		free_swap_cache(src);
		folio_putback_lru(src);
	}
}

static void __collapse_huge_page_copy_failed(pte_t *pte,
		pmd_t *pmd, pmd_t orig_pmd, struct vm_area_struct *vma,
		unsigned int order, struct list_head *compound_pagelist)
{
	const unsigned long nr_pages = 1UL << order;
	spinlock_t *pmd_ptl;

	/*
	 * Re-establish the PMD to point to the original page table
	 * entry. Restoring PMD needs to be done prior to releasing
	 * pages. Since pages are still isolated and locked here,
	 * acquiring anon_vma_lock_write() is unnecessary.
	 */
	pmd_ptl = pmd_lock(vma->vm_mm, pmd);
	pmd_populate(vma->vm_mm, pmd, pmd_pgtable(orig_pmd));
	spin_unlock(pmd_ptl);
	/*
	 * Release both raw and compound pages isolated
	 * in __collapse_huge_page_isolate.
	 */
	release_pte_pages(pte, pte + nr_pages, compound_pagelist);
}

/*
 * __collapse_huge_page_copy - attempts to copy memory contents from raw
 * pages to a hugepage. Cleans up the raw pages if copying succeeds;
 * otherwise restores the original page table and releases isolated raw pages.
 * Returns SCAN_SUCCEED if copying succeeds, otherwise returns SCAN_COPY_MC.
 *
 * @pte: starting of the PTEs to copy from
 * @folio: the new hugepage to copy contents to
 * @pmd: pointer to the new hugepage's PMD
 * @orig_pmd: the original raw pages' PMD
 * @vma: the original raw pages' virtual memory area
 * @address: starting address to copy
 * @ptl: lock on raw pages' PTEs
 * @compound_pagelist: list that stores compound pages
 */
static enum scan_result __collapse_huge_page_copy(pte_t *pte, struct folio *folio,
		pmd_t *pmd, pmd_t orig_pmd, struct vm_area_struct *vma,
		unsigned long address, spinlock_t *ptl, unsigned int order,
		struct list_head *compound_pagelist)
{
	const unsigned long nr_pages = 1UL << order;
	unsigned int i;
	enum scan_result result = SCAN_SUCCEED;

	/*
	 * Copying pages' contents is subject to memory poison at any iteration.
	 */
	for (i = 0; i < nr_pages; i++) {
		pte_t pteval = ptep_get(pte + i);
		struct page *page = folio_page(folio, i);
		unsigned long src_addr = address + i * PAGE_SIZE;
		struct page *src_page;

		if (pte_none_or_zero(pteval)) {
			clear_user_highpage(page, src_addr);
			continue;
		}
		src_page = pte_page(pteval);
		if (copy_mc_user_highpage(page, src_page, src_addr, vma) > 0) {
			result = SCAN_COPY_MC;
			break;
		}
	}

	if (likely(result == SCAN_SUCCEED))
		__collapse_huge_page_copy_succeeded(pte, vma, address, ptl,
						    order, compound_pagelist);
	else
		__collapse_huge_page_copy_failed(pte, pmd, orig_pmd, vma,
						 order, compound_pagelist);

	return result;
}

static void khugepaged_alloc_sleep(void)
{
	DEFINE_WAIT(wait);

	add_wait_queue(&khugepaged_wait, &wait);
	__set_current_state(TASK_INTERRUPTIBLE|TASK_FREEZABLE);
	schedule_timeout(msecs_to_jiffies(khugepaged_alloc_sleep_millisecs));
	remove_wait_queue(&khugepaged_wait, &wait);
}

static struct collapse_control khugepaged_collapse_control = {
	.is_khugepaged = true,
};

static bool collapse_scan_abort(int nid, struct collapse_control *cc)
{
	int i;

	/*
	 * If node_reclaim_mode is disabled, then no extra effort is made to
	 * allocate memory locally.
	 */
	if (!node_reclaim_enabled())
		return false;

	/* If there is a count for this node already, it must be acceptable */
	if (cc->node_load[nid])
		return false;

	for (i = 0; i < MAX_NUMNODES; i++) {
		if (!cc->node_load[i])
			continue;
		if (node_distance(nid, i) > node_reclaim_distance)
			return true;
	}
	return false;
}

#define khugepaged_defrag()					\
	(transparent_hugepage_flags &				\
	 (1<<TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG))

/* Defrag for khugepaged will enter direct reclaim/compaction if necessary */
static inline gfp_t alloc_hugepage_khugepaged_gfpmask(void)
{
	return khugepaged_defrag() ? GFP_TRANSHUGE : GFP_TRANSHUGE_LIGHT;
}

#ifdef CONFIG_NUMA
static int collapse_find_target_node(struct collapse_control *cc)
{
	int nid, target_node = 0, max_value = 0;

	/* find first node with max normal pages hit */
	for (nid = 0; nid < MAX_NUMNODES; nid++)
		if (cc->node_load[nid] > max_value) {
			max_value = cc->node_load[nid];
			target_node = nid;
		}

	for_each_online_node(nid) {
		if (max_value == cc->node_load[nid])
			node_set(nid, cc->alloc_nmask);
	}

	return target_node;
}
#else
static int collapse_find_target_node(struct collapse_control *cc)
{
	return 0;
}
#endif

/*
 * If mmap_lock temporarily dropped, revalidate vma
 * after taking the mmap_lock again.
 * Returns enum scan_result value.
 */

static enum scan_result hugepage_vma_revalidate(struct mm_struct *mm, unsigned long address,
		bool expect_anon, struct vm_area_struct **vmap,
		struct collapse_control *cc, unsigned int order)
{
	struct vm_area_struct *vma;
	enum tva_type type = cc->is_khugepaged ? TVA_KHUGEPAGED :
				 TVA_FORCED_COLLAPSE;

	if (unlikely(collapse_test_exit_or_disable(mm)))
		return SCAN_ANY_PROCESS;

	*vmap = vma = find_vma(mm, address);
	if (!vma)
		return SCAN_VMA_NULL;

	/*
	 * We cannot collapse VMA regions that do not span the full PMD. This is
	 * due to the potential of the PMD being shared by another VMA leaving
	 * us vulnerable to a race condition. Always check the PMD order here to
	 * ensure its not shared by another VMA. We'd need to lock all VMAs in
	 * the PMD range to support this.
	 */
	if (!thp_vma_suitable_order(vma, address, PMD_ORDER))
		return SCAN_ADDRESS_RANGE;
	if (!thp_vma_allowable_orders(vma, vma->vm_flags, type, BIT(order)))
		return SCAN_VMA_CHECK;
	/*
	 * Anon VMA expected, the address may be unmapped then
	 * remapped to file after khugepaged reacquired the mmap_lock.
	 *
	 * thp_vma_allowable_orders() may return true for qualified file
	 * vmas.
	 */
	if (expect_anon && (!(*vmap)->anon_vma || !vma_is_anonymous(*vmap)))
		return SCAN_PAGE_ANON;
	return SCAN_SUCCEED;
}

static inline enum scan_result check_pmd_state(pmd_t *pmd)
{
	pmd_t pmde = pmdp_get_lockless(pmd);

	if (pmd_none(pmde))
		return SCAN_NO_PTE_TABLE;

	/*
	 * The folio may be under migration when khugepaged is trying to
	 * collapse it. Migration success or failure will eventually end
	 * up with a present PMD mapping a folio again.
	 */
	if (pmd_is_migration_entry(pmde))
		return SCAN_PMD_MAPPED;
	if (!pmd_present(pmde))
		return SCAN_NO_PTE_TABLE;
	if (pmd_trans_huge(pmde))
		return SCAN_PMD_MAPPED;
	if (pmd_bad(pmde))
		return SCAN_NO_PTE_TABLE;
	return SCAN_SUCCEED;
}

static enum scan_result find_pmd_or_thp_or_none(struct mm_struct *mm,
		unsigned long address, pmd_t **pmd)
{
	*pmd = mm_find_pmd(mm, address);
	if (!*pmd)
		return SCAN_NO_PTE_TABLE;

	return check_pmd_state(*pmd);
}

static enum scan_result check_pmd_still_valid(struct mm_struct *mm,
		unsigned long address, pmd_t *pmd)
{
	pmd_t *new_pmd;
	enum scan_result result = find_pmd_or_thp_or_none(mm, address, &new_pmd);

	if (result != SCAN_SUCCEED)
		return result;
	if (new_pmd != pmd)
		return SCAN_FAIL;
	return SCAN_SUCCEED;
}

/*
 * Bring missing pages in from swap, to complete THP collapse.
 * Only done if collapse_scan_pmd() believes it is worthwhile.
 *
 * For mTHP orders the function bails on the first swap entry, because
 * faulting pages back in during collapse could re-populate PTEs that
 * push a later scan over the threshold for a higher-order collapse.
 *
 * Called and returns without pte mapped or spinlocks held.
 * Returns result: if not SCAN_SUCCEED, mmap_lock has been released.
 */
static enum scan_result __collapse_huge_page_swapin(struct mm_struct *mm,
		struct vm_area_struct *vma, unsigned long start_addr,
		pmd_t *pmd, int referenced, unsigned int order)
{
	int swapped_in = 0;
	vm_fault_t ret = 0;
	unsigned long addr, end = start_addr + (PAGE_SIZE << order);
	enum scan_result result;
	pte_t *pte = NULL;
	spinlock_t *ptl;

	for (addr = start_addr; addr < end; addr += PAGE_SIZE) {
		struct vm_fault vmf = {
			.vma = vma,
			.address = addr,
			.pgoff = linear_page_index(vma, addr),
			.flags = FAULT_FLAG_ALLOW_RETRY,
			.pmd = pmd,
		};

		if (!pte++) {
			/*
			 * Here the ptl is only used to check pte_same() in
			 * do_swap_page(), so readonly version is enough.
			 */
			pte = pte_offset_map_ro_nolock(mm, pmd, addr, &ptl);
			if (!pte) {
				mmap_read_unlock(mm);
				result = SCAN_NO_PTE_TABLE;
				goto out;
			}
		}

		vmf.orig_pte = ptep_get_lockless(pte);
		if (pte_none(vmf.orig_pte) ||
		    pte_present(vmf.orig_pte))
			continue;

		/*
		 * TODO: Support swapin without leading to further mTHP
		 * collapses. Currently bringing in new pages via swapin may
		 * cause a future higher order collapse on a rescan of the same
		 * range.
		 */
		if (!is_pmd_order(order)) {
			count_mthp_stat(order, MTHP_STAT_COLLAPSE_EXCEED_SWAP);
			pte_unmap(pte);
			mmap_read_unlock(mm);
			result = SCAN_EXCEED_SWAP_PTE;
			goto out;
		}

		vmf.pte = pte;
		vmf.ptl = ptl;
		ret = do_swap_page(&vmf);
		/* Which unmaps pte (after perhaps re-checking the entry) */
		pte = NULL;

		/*
		 * do_swap_page() returns VM_FAULT_RETRY with released mmap_lock.
		 * Note we treat VM_FAULT_RETRY as VM_FAULT_ERROR here because
		 * we do not retry here and swap entry will remain in pagetable
		 * resulting in later failure.
		 */
		if (ret & VM_FAULT_RETRY) {
			/* Likely, but not guaranteed, that page lock failed */
			result = SCAN_PAGE_LOCK;
			goto out;
		}
		if (ret & VM_FAULT_ERROR) {
			mmap_read_unlock(mm);
			result = SCAN_FAIL;
			goto out;
		}
		swapped_in++;
	}

	if (pte)
		pte_unmap(pte);

	/* Drain LRU cache to remove extra pin on the swapped in pages */
	if (swapped_in)
		lru_add_drain();

	result = SCAN_SUCCEED;
out:
	trace_mm_collapse_huge_page_swapin(mm, swapped_in, referenced, result,
					   order);
	return result;
}

static enum scan_result alloc_charge_folio(struct folio **foliop, struct mm_struct *mm,
		struct collapse_control *cc, unsigned int order)
{
	gfp_t gfp = (cc->is_khugepaged ? alloc_hugepage_khugepaged_gfpmask() :
		     GFP_TRANSHUGE);
	int node = collapse_find_target_node(cc);
	struct folio *folio;

	folio = __folio_alloc(gfp, order, node, &cc->alloc_nmask);
	if (!folio) {
		*foliop = NULL;
		count_collapse_event(order, THP_COLLAPSE_ALLOC_FAILED,
				     MTHP_STAT_COLLAPSE_ALLOC_FAILED);
		return SCAN_ALLOC_HUGE_PAGE_FAIL;
	}

	count_collapse_event(order, THP_COLLAPSE_ALLOC, MTHP_STAT_COLLAPSE_ALLOC);

	if (unlikely(mem_cgroup_charge(folio, mm, gfp))) {
		folio_put(folio);
		*foliop = NULL;
		return SCAN_CGROUP_CHARGE_FAIL;
	}

	if (is_pmd_order(order))
		count_memcg_folio_events(folio, THP_COLLAPSE_ALLOC, 1);

	*foliop = folio;
	return SCAN_SUCCEED;
}

/*
 * collapse_huge_page() expects the mmap_lock to be unlocked before entering and
 * will always return with the lock unlocked, to avoid holding the mmap_lock
 * while allocating a THP, as that could trigger direct reclaim/compaction.
 * Note that the VMA must be rechecked after grabbing the mmap_lock again.
 */
static enum scan_result collapse_huge_page(struct mm_struct *mm, unsigned long start_addr,
		int referenced, int unmapped, struct collapse_control *cc,
		unsigned int order)
{
	const unsigned long pmd_addr = start_addr & HPAGE_PMD_MASK;
	const unsigned long end_addr = start_addr + (PAGE_SIZE << order);
	LIST_HEAD(compound_pagelist);
	pmd_t *pmd, _pmd;
	pte_t *pte = NULL;
	pgtable_t pgtable;
	struct folio *folio;
	spinlock_t *pmd_ptl, *pte_ptl;
	enum scan_result result = SCAN_FAIL;
	struct vm_area_struct *vma;
	struct mmu_notifier_range range;
	bool anon_vma_locked = false;

	result = alloc_charge_folio(&folio, mm, cc, order);
	if (result != SCAN_SUCCEED)
		goto out_nolock;

	if (folio_memcg_alloc_deferred(folio)) {
		result = SCAN_ALLOC_HUGE_PAGE_FAIL;
		goto out_nolock;
	}

	mmap_read_lock(mm);
	result = hugepage_vma_revalidate(mm, pmd_addr, /*expect_anon=*/ true,
					 &vma, cc, order);
	if (result != SCAN_SUCCEED) {
		mmap_read_unlock(mm);
		goto out_nolock;
	}

	result = find_pmd_or_thp_or_none(mm, pmd_addr, &pmd);
	if (result != SCAN_SUCCEED) {
		mmap_read_unlock(mm);
		goto out_nolock;
	}

	if (unmapped) {
		/*
		 * __collapse_huge_page_swapin() will return with mmap_lock
		 * released when it fails. So we jump out_nolock directly in
		 * that case.  Continuing to collapse causes inconsistency.
		 */
		result = __collapse_huge_page_swapin(mm, vma, start_addr, pmd,
						     referenced, order);
		if (result != SCAN_SUCCEED)
			goto out_nolock;
	}

	mmap_read_unlock(mm);
	/*
	 * Prevent all access to pagetables with the exception of
	 * gup_fast later handled by the pmdp_collapse_flush() and the VM
	 * handled by the anon_vma lock + folio lock.
	 *
	 * UFFDIO_MOVE is prevented to race as well thanks to the
	 * mmap_lock.
	 */
	mmap_write_lock(mm);
	result = hugepage_vma_revalidate(mm, pmd_addr, /*expect_anon=*/ true,
					 &vma, cc, order);
	if (result != SCAN_SUCCEED)
		goto out_up_write;
	/* check if the pmd is still valid */
	vma_start_write(vma);
	result = check_pmd_still_valid(mm, pmd_addr, pmd);
	if (result != SCAN_SUCCEED)
		goto out_up_write;

	anon_vma_lock_write(vma->anon_vma);
	anon_vma_locked = true;

	/*
	 * Only notify about the PTE range we will actually modify. While we
	 * temporary unmap the whole PTE table for mTHP collapse, we'll remap
	 * it later, leaving other PTEs effectively unmodified. The locks we
	 * hold prevent anybody from stumbling over such temporarily unmapped
	 * PTE tables.
	 */
	mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, mm, start_addr,
				end_addr);
	mmu_notifier_invalidate_range_start(&range);

	pmd_ptl = pmd_lock(mm, pmd); /* probably unnecessary */
	/*
	 * This removes any huge TLB entry from the CPU so we won't allow
	 * huge and small TLB entries for the same virtual address to
	 * avoid the risk of CPU bugs in that area.
	 *
	 * Parallel GUP-fast is fine since GUP-fast will back off when
	 * it detects PMD is changed.
	 */
	_pmd = pmdp_collapse_flush(vma, pmd_addr, pmd);
	spin_unlock(pmd_ptl);
	mmu_notifier_invalidate_range_end(&range);
	tlb_remove_table_sync_one();

	pte = pte_offset_map_lock(mm, &_pmd, start_addr, &pte_ptl);
	if (pte) {
		result = __collapse_huge_page_isolate(vma, start_addr, pte, cc,
						      order, &compound_pagelist);
		spin_unlock(pte_ptl);
	} else {
		result = SCAN_NO_PTE_TABLE;
	}

	if (unlikely(result != SCAN_SUCCEED)) {
		spin_lock(pmd_ptl);
		VM_WARN_ON_ONCE(!pmd_none(*pmd));
		/*
		 * We can only use set_pmd_at() when establishing
		 * hugepmds and never for establishing regular pmds that
		 * points to regular pagetables. Use pmd_populate() for that
		 */
		pmd_populate(mm, pmd, pmd_pgtable(_pmd));
		spin_unlock(pmd_ptl);
		goto out_up_write;
	}

	/*
	 * For PMD collapse all pages are isolated and locked so anon_vma
	 * rmap can't run anymore. For mTHP collapse the PMD entry has been
	 * removed and not all pages are isolated and locked, so we must hold
	 * the lock to prevent neighboring folios from attempting to access
	 * this PMD until its reinstalled.
	 */
	if (is_pmd_order(order)) {
		anon_vma_unlock_write(vma->anon_vma);
		anon_vma_locked = false;
	}

	result = __collapse_huge_page_copy(pte, folio, pmd, _pmd,
					   vma, start_addr, pte_ptl,
					   order, &compound_pagelist);
	if (unlikely(result != SCAN_SUCCEED))
		goto out_up_write;

	/*
	 * The smp_wmb() inside __folio_mark_uptodate() ensures the
	 * copy_huge_page writes become visible before the set_pmd_at()
	 * write.
	 */
	__folio_mark_uptodate(folio);
	spin_lock(pmd_ptl);
	VM_WARN_ON_ONCE(!pmd_none(*pmd));
	if (is_pmd_order(order)) {
		pgtable = pmd_pgtable(_pmd);
		pgtable_trans_huge_deposit(mm, pmd, pgtable);
		map_anon_folio_pmd_nopf(folio, pmd, vma, pmd_addr);
	} else {
		/*
		 * Some architectures (e.g. MIPS) walk the live page table in
		 * their implementation. update_mmu_cache_range() must be called
		 * with a valid page table hierarchy and the PTE lock held.
		 * Acquire it nested inside pmd_ptl when they are distinct locks.
		 */
		if (pte_ptl != pmd_ptl)
			spin_lock_nested(pte_ptl, SINGLE_DEPTH_NESTING);
		pmd_populate(mm, pmd, pmd_pgtable(_pmd));
		map_anon_folio_pte_nopf(folio, pte, vma, start_addr,
					  /*uffd_wp=*/ false);
		if (pte_ptl != pmd_ptl)
			spin_unlock(pte_ptl);
	}
	spin_unlock(pmd_ptl);

	folio = NULL;

	result = SCAN_SUCCEED;
out_up_write:
	if (pte)
		pte_unmap(pte);
	if (anon_vma_locked)
		anon_vma_unlock_write(vma->anon_vma);
	mmap_write_unlock(mm);
out_nolock:
	if (folio)
		folio_put(folio);
	trace_mm_collapse_huge_page(mm, result == SCAN_SUCCEED, result, order);
	return result;
}

/* Return the highest naturally aligned order that fits at @offset within a PMD. */
static unsigned int max_order_from_offset(unsigned int offset)
{
	if (offset == 0)
		return HPAGE_PMD_ORDER;

	return min_t(unsigned int, __ffs(offset), HPAGE_PMD_ORDER);
}

/*
 * mthp_collapse() consumes the bitmap that is generated during
 * collapse_scan_pmd() to determine what regions and mTHP orders fit best.
 *
 * Each bit in cc->mthp_present_ptes represents a single occupied (!none/zero)
 * page. We start at the PMD order and check if it is eligible for collapse;
 * if not, we check the left and right halves of the PTE page table we are
 * examining at a lower order.
 *
 * For each of these, we determine how many PTE entries are occupied in the
 * range of PTE entries we propose to collapse, then we compare this to a
 * threshold number of PTE entries which would need to be occupied for a
 * collapse to be permitted at that order (accounting for max_ptes_none).
 *
 * If a collapse is permitted, we attempt to collapse the PTE range into a
 * mTHP.
 */
static enum scan_result mthp_collapse(struct mm_struct *mm,
		unsigned long address, int referenced, int unmapped,
		struct collapse_control *cc, unsigned long enabled_orders)
{
	unsigned int nr_occupied_ptes, nr_ptes, max_ptes_none;
	enum scan_result last_result = SCAN_FAIL;
	int collapsed = 0;
	bool alloc_failed = false;
	unsigned long collapse_address;
	unsigned int offset = 0;
	unsigned int order = HPAGE_PMD_ORDER;

	while (offset < HPAGE_PMD_NR) {
		nr_ptes = 1UL << order;

		if (!test_bit(order, &enabled_orders))
			goto next_order;

		max_ptes_none = collapse_max_ptes_none(cc, NULL, order);
		nr_occupied_ptes = bitmap_weight_from(cc->mthp_present_ptes, offset,
						      offset + nr_ptes);

		/*
		 * Swap PTEs accepted during the scan are counted in @unmapped,
		 * not in the present-PTE bitmap. Account them for the PMD-order
		 * candidate.
		 */
		if (is_pmd_order(order))
			nr_occupied_ptes += unmapped;

		if (nr_occupied_ptes >= nr_ptes - max_ptes_none) {
			enum scan_result ret;

			collapse_address = address + offset * PAGE_SIZE;
			ret = collapse_huge_page(mm, collapse_address, referenced,
						 unmapped, cc, order);

			switch (ret) {
			/* Cases where we continue to next collapse candidate */
			case SCAN_SUCCEED:
				collapsed += nr_ptes;
				fallthrough;
			case SCAN_PTE_MAPPED_HUGEPAGE:
				goto next_offset;
			/* Cases where lower orders might still succeed */
			case SCAN_ALLOC_HUGE_PAGE_FAIL:
				alloc_failed = true;
				fallthrough;
			case SCAN_LACK_REFERENCED_PAGE:
			case SCAN_EXCEED_NONE_PTE:
			case SCAN_EXCEED_SWAP_PTE:
			case SCAN_EXCEED_SHARED_PTE:
			case SCAN_PAGE_LOCK:
			case SCAN_PAGE_COUNT:
			case SCAN_PAGE_NULL:
			case SCAN_DEL_PAGE_LRU:
			case SCAN_PTE_NON_PRESENT:
			case SCAN_PTE_UFFD:
			case SCAN_PAGE_LAZYFREE:
				last_result = ret;
				goto next_order;
			/* Cases where no further collapse is possible */
			case SCAN_PMD_MAPPED:
				fallthrough;
			default:
				last_result = ret;
				goto done;
			}
		}

next_order:
		/*
		 * Continue with the next smaller order if there is still
		 * any smaller order enabled. When at the smallest order
		 * we must always move to the next offset.
		 */
		if (order > KHUGEPAGED_MIN_MTHP_ORDER &&
			(enabled_orders & GENMASK(order - 1, 0))) {
			order--;
			continue;
		}
next_offset:
		/*
		 * Advance past the region we just processed and determine the
		 * highest order we can attempt next. Since huge pages must be
		 * naturally aligned, the max order we can attempt next is
		 * limited by the alignment of the new offset.
		 * E.g. if we collapsed a order-2 mTHP at offset 0, offset
		 * becomes 4 and __ffs(4) == 2, so the next attempt starts at
		 * order 2.
		 */
		offset += nr_ptes;
		order = max_order_from_offset(offset);
	}
done:
	if (collapsed)
		return SCAN_SUCCEED;
	if (alloc_failed)
		return SCAN_ALLOC_HUGE_PAGE_FAIL;
	return last_result;
}

static enum scan_result collapse_scan_pmd(struct mm_struct *mm,
		struct vm_area_struct *vma, unsigned long start_addr,
		bool *lock_dropped, struct collapse_control *cc)
{
	const unsigned int max_ptes_shared = collapse_max_ptes_shared(cc, HPAGE_PMD_ORDER);
	const unsigned int max_ptes_swap = collapse_max_ptes_swap(cc, HPAGE_PMD_ORDER);
	unsigned int max_ptes_none = collapse_max_ptes_none(cc, vma, HPAGE_PMD_ORDER);
	enum tva_type tva_flags = cc->is_khugepaged ? TVA_KHUGEPAGED : TVA_FORCED_COLLAPSE;
	pmd_t *pmd;
	pte_t *pte, *_pte, pteval;
	int i;
	int none_or_zero = 0, shared = 0, referenced = 0;
	enum scan_result result = SCAN_FAIL;
	struct page *page = NULL;
	struct folio *folio = NULL;
	unsigned long addr;
	unsigned long enabled_orders;
	spinlock_t *ptl;
	int node = NUMA_NO_NODE, unmapped = 0;

	VM_BUG_ON(start_addr & ~HPAGE_PMD_MASK);

	result = find_pmd_or_thp_or_none(mm, start_addr, &pmd);
	if (result != SCAN_SUCCEED) {
		cc->progress++;
		goto out;
	}

	collapse_control_init_scan(cc);

	enabled_orders = collapse_possible_orders(vma, vma->vm_flags, tva_flags);

	/*
	 * If PMD is the only enabled order, enforce max_ptes_none, otherwise
	 * scan all pages to populate the bitmap for mTHP collapse. The bitmap
	 * is then checked again in mthp_collapse() for each attempted order.
	 */
	if (enabled_orders != BIT(HPAGE_PMD_ORDER))
		max_ptes_none = KHUGEPAGED_MAX_PTES_LIMIT;

	pte = pte_offset_map_lock(mm, pmd, start_addr, &ptl);
	if (!pte) {
		cc->progress++;
		result = SCAN_NO_PTE_TABLE;
		goto out;
	}

	for (i = 0; i < HPAGE_PMD_NR; i++) {
		_pte = pte + i;
		addr = start_addr + i * PAGE_SIZE;
		pteval = ptep_get(_pte);

		cc->progress++;

		if (pte_none_or_zero(pteval)) {
			if (++none_or_zero > max_ptes_none) {
				result = SCAN_EXCEED_NONE_PTE;
				count_collapse_event(HPAGE_PMD_ORDER, THP_SCAN_EXCEED_NONE_PTE,
						     MTHP_STAT_COLLAPSE_EXCEED_NONE);
				goto out_unmap;
			}
			continue;
		}
		if (!pte_present(pteval)) {
			if (++unmapped > max_ptes_swap) {
				result = SCAN_EXCEED_SWAP_PTE;
				count_collapse_event(HPAGE_PMD_ORDER, THP_SCAN_EXCEED_SWAP_PTE,
						     MTHP_STAT_COLLAPSE_EXCEED_SWAP);
				goto out_unmap;
			}
			/*
			 * Always be strict with uffd-wp
			 * enabled swap entries.  Please see
			 * comment below for pte_uffd().
			 */
			if (pte_swp_uffd_any(pteval)) {
				result = SCAN_PTE_UFFD;
				goto out_unmap;
			}
			continue;
		}
		if (pte_uffd(pteval)) {
			/*
			 * Don't collapse the page if any of the small
			 * PTEs are armed with uffd write protection.
			 * Here we can also mark the new huge pmd as
			 * write protected if any of the small ones is
			 * marked but that could bring unknown
			 * userfault messages that falls outside of
			 * the registered range.  So, just be simple.
			 */
			result = SCAN_PTE_UFFD;
			goto out_unmap;
		}

		page = vm_normal_page(vma, addr, pteval);
		if (unlikely(!page) || unlikely(is_zone_device_page(page))) {
			result = SCAN_PAGE_NULL;
			goto out_unmap;
		}
		folio = page_folio(page);

		/*
		 * If the vma has the VM_DROPPABLE flag, the collapse will
		 * preserve the lazyfree property without needing to skip.
		 */
		if (cc->is_khugepaged && !(vma->vm_flags & VM_DROPPABLE) &&
		    folio_test_lazyfree(folio) && !pte_dirty(pteval)) {
			result = SCAN_PAGE_LAZYFREE;
			goto out_unmap;
		}

		if (!folio_test_anon(folio)) {
			result = SCAN_PAGE_ANON;
			goto out_unmap;
		}

		/*
		 * We treat a single page as shared if any part of the THP
		 * is shared.
		 */
		if (folio_maybe_mapped_shared(folio)) {
			if (++shared > max_ptes_shared) {
				result = SCAN_EXCEED_SHARED_PTE;
				count_collapse_event(HPAGE_PMD_ORDER, THP_SCAN_EXCEED_SHARED_PTE,
						     MTHP_STAT_COLLAPSE_EXCEED_SHARED);
				goto out_unmap;
			}
		}

		/* Set bit for occupied pages */
		__set_bit(i, cc->mthp_present_ptes);
		/*
		 * Record which node the original page is from and save this
		 * information to cc->node_load[].
		 * Khugepaged will allocate hugepage from the node has the max
		 * hit record.
		 */
		node = folio_nid(folio);
		if (collapse_scan_abort(node, cc)) {
			result = SCAN_SCAN_ABORT;
			goto out_unmap;
		}
		cc->node_load[node]++;
		if (!folio_test_lru(folio)) {
			result = SCAN_PAGE_LRU;
			goto out_unmap;
		}
		if (folio_test_locked(folio)) {
			result = SCAN_PAGE_LOCK;
			goto out_unmap;
		}

		/*
		 * Check if the page has any GUP (or other external) pins.
		 *
		 * Here the check is racy, but such cases are ephemeral and
		 * we can always retry collapse later. Anyway the same
		 * check will be done again later, so the risk seems to be low.
		 */
		if (folio_expected_ref_count(folio) != folio_ref_count(folio)) {
			result = SCAN_PAGE_COUNT;
			goto out_unmap;
		}

		if (cc->is_khugepaged &&
		    folio_pte_referenced(folio, vma, addr, pteval))
			referenced++;
	}
	if (cc->is_khugepaged &&
		   (!referenced ||
		    (unmapped && referenced < HPAGE_PMD_NR / 2))) {
		result = SCAN_LACK_REFERENCED_PAGE;
	} else {
		result = SCAN_SUCCEED;
	}
out_unmap:
	pte_unmap_unlock(pte, ptl);
	if (result == SCAN_SUCCEED) {
		/* collapse_huge_page() expects the lock to be dropped before calling */
		mmap_read_unlock(mm);
		result = mthp_collapse(mm, start_addr, referenced,
				       unmapped, cc, enabled_orders);
		/* mmap_lock was released above, set lock_dropped */
		*lock_dropped = true;
	}
out:
	trace_mm_khugepaged_scan_pmd(mm, folio, referenced,
				     none_or_zero, result, unmapped);
	return result;
}

static void collect_mm_slot(struct mm_slot *slot)
{
	struct mm_struct *mm = slot->mm;

	lockdep_assert_held(&khugepaged_mm_lock);

	if (collapse_test_exit(mm)) {
		/* free mm_slot */
		mm_slot_remove(slot);

		/*
		 * Not strictly needed because the mm exited already.
		 *
		 * mm_flags_clear(MMF_VM_HUGEPAGE, mm);
		 */

		/* khugepaged_mm_lock actually not necessary for the below */
		mm_slot_free(mm_slot_cache, slot);
		mmdrop(mm);
	}
}

/* folio must be locked, and mmap_lock must be held */
static enum scan_result set_huge_pmd(struct vm_area_struct *vma, unsigned long addr,
		pmd_t *pmdp, struct folio *folio, struct page *page)
{
	struct mm_struct *mm = vma->vm_mm;
	struct vm_fault vmf = {
		.vma = vma,
		.address = addr,
		.flags = 0,
	};
	pgd_t *pgdp;
	p4d_t *p4dp;
	pud_t *pudp;

	mmap_assert_locked(vma->vm_mm);

	if (!pmdp) {
		pgdp = pgd_offset(mm, addr);
		p4dp = p4d_alloc(mm, pgdp, addr);
		if (!p4dp)
			return SCAN_FAIL;
		pudp = pud_alloc(mm, p4dp, addr);
		if (!pudp)
			return SCAN_FAIL;
		pmdp = pmd_alloc(mm, pudp, addr);
		if (!pmdp)
			return SCAN_FAIL;
	}

	vmf.pmd = pmdp;
	if (do_set_pmd(&vmf, folio, page))
		return SCAN_FAIL;

	folio_get(folio);
	return SCAN_SUCCEED;
}

static enum scan_result try_collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
		bool install_pmd)
{
	enum scan_result result = SCAN_FAIL;
	int nr_mapped_ptes = 0;
	unsigned int nr_batch_ptes;
	struct mmu_notifier_range range;
	bool notified = false;
	unsigned long haddr = addr & HPAGE_PMD_MASK;
	unsigned long end = haddr + HPAGE_PMD_SIZE;
	struct vm_area_struct *vma = vma_lookup(mm, haddr);
	struct folio *folio;
	pte_t *start_pte, *pte;
	pmd_t *pmd, pgt_pmd;
	spinlock_t *pml = NULL, *ptl;
	int i;

	mmap_assert_locked(mm);

	/* First check VMA found, in case page tables are being torn down */
	if (!vma || !vma->vm_file ||
	    !range_in_vma(vma, haddr, haddr + HPAGE_PMD_SIZE))
		return SCAN_VMA_CHECK;

	/* Fast check before locking page if already PMD-mapped */
	result = find_pmd_or_thp_or_none(mm, haddr, &pmd);
	if (result == SCAN_PMD_MAPPED)
		return result;

	/*
	 * If we are here, we've succeeded in replacing all the native pages
	 * in the page cache with a single hugepage. If a mm were to fault-in
	 * this memory (mapped by a suitably aligned VMA), we'd get the hugepage
	 * and map it by a PMD, regardless of sysfs THP settings. As such, let's
	 * analogously elide sysfs THP settings here and force collapse.
	 */
	if (!thp_vma_allowable_order(vma, vma->vm_flags, TVA_FORCED_COLLAPSE, PMD_ORDER))
		return SCAN_VMA_CHECK;

	/*
	 * Keep pmd pgtable while the uffd bit is in use; see comment in
	 * retract_page_tables().
	 */
	if (userfaultfd_protected(vma))
		return SCAN_PTE_UFFD;

	folio = filemap_lock_folio(vma->vm_file->f_mapping,
			       linear_page_index(vma, haddr));
	if (IS_ERR(folio))
		return SCAN_PAGE_NULL;

	if (!is_pmd_order(folio_order(folio))) {
		result = SCAN_PAGE_COMPOUND;
		goto drop_folio;
	}

	result = find_pmd_or_thp_or_none(mm, haddr, &pmd);
	switch (result) {
	case SCAN_SUCCEED:
		break;
	case SCAN_NO_PTE_TABLE:
		/*
		 * All pte entries have been removed and pmd cleared.
		 * Skip all the pte checks and just update the pmd mapping.
		 */
		goto maybe_install_pmd;
	default:
		goto drop_folio;
	}

	result = SCAN_FAIL;
	start_pte = pte_offset_map_lock(mm, pmd, haddr, &ptl);
	if (!start_pte)		/* mmap_lock + page lock should prevent this */
		goto drop_folio;

	/* step 1: check all mapped PTEs are to the right huge page */
	for (i = 0, addr = haddr, pte = start_pte;
	     i < HPAGE_PMD_NR; i++, addr += PAGE_SIZE, pte++) {
		struct page *page;
		pte_t ptent = ptep_get(pte);

		/* empty pte, skip */
		if (pte_none(ptent))
			continue;

		/* page swapped out, abort */
		if (!pte_present(ptent)) {
			result = SCAN_PTE_NON_PRESENT;
			goto abort;
		}

		page = vm_normal_page(vma, addr, ptent);
		if (WARN_ON_ONCE(page && is_zone_device_page(page)))
			page = NULL;
		/*
		 * Note that uprobe, debugger, or MAP_PRIVATE may change the
		 * page table, but the new page will not be a subpage of hpage.
		 */
		if (folio_page(folio, i) != page)
			goto abort;
	}

	pte_unmap_unlock(start_pte, ptl);
	mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, mm,
				haddr, haddr + HPAGE_PMD_SIZE);
	mmu_notifier_invalidate_range_start(&range);
	notified = true;

	/*
	 * pmd_lock covers a wider range than ptl, and (if split from mm's
	 * page_table_lock) ptl nests inside pml. The less time we hold pml,
	 * the better; but userfaultfd's mfill_atomic_pte() on a private VMA
	 * inserts a valid as-if-COWed PTE without even looking up page cache.
	 * So page lock of folio does not protect from it, so we must not drop
	 * ptl before pgt_pmd is removed, so uffd private needs pml taken now.
	 */
	if (userfaultfd_armed(vma) && !(vma->vm_flags & VM_SHARED))
		pml = pmd_lock(mm, pmd);

	start_pte = pte_offset_map_rw_nolock(mm, pmd, haddr, &pgt_pmd, &ptl);
	if (!start_pte)		/* mmap_lock + page lock should prevent this */
		goto abort;
	if (!pml)
		spin_lock(ptl);
	else if (ptl != pml)
		spin_lock_nested(ptl, SINGLE_DEPTH_NESTING);

	if (unlikely(!pmd_same(pgt_pmd, pmdp_get_lockless(pmd))))
		goto abort;

	/* step 2: clear page table and adjust rmap */
	for (i = 0, addr = haddr, pte = start_pte; i < HPAGE_PMD_NR;
	     i += nr_batch_ptes, addr += nr_batch_ptes * PAGE_SIZE,
	     pte += nr_batch_ptes) {
		unsigned int max_nr_batch_ptes = (end - addr) >> PAGE_SHIFT;
		struct page *page;
		pte_t ptent = ptep_get(pte);

		nr_batch_ptes = 1;

		if (pte_none(ptent))
			continue;
		/*
		 * We dropped ptl after the first scan, to do the mmu_notifier:
		 * page lock stops more PTEs of the folio being faulted in, but
		 * does not stop write faults COWing anon copies from existing
		 * PTEs; and does not stop those being swapped out or migrated.
		 */
		if (!pte_present(ptent)) {
			result = SCAN_PTE_NON_PRESENT;
			goto abort;
		}
		page = vm_normal_page(vma, addr, ptent);

		if (folio_page(folio, i) != page)
			goto abort;

		nr_batch_ptes = folio_pte_batch(folio, pte, ptent, max_nr_batch_ptes);

		/*
		 * Must clear entry, or a racing truncate may re-remove it.
		 * TLB flush can be left until pmdp_collapse_flush() does it.
		 * PTE dirty? Shmem page is already dirty; file is read-only.
		 */
		clear_ptes(mm, addr, pte, nr_batch_ptes);
		folio_remove_rmap_ptes(folio, page, nr_batch_ptes, vma);
		nr_mapped_ptes += nr_batch_ptes;
	}

	if (!pml)
		spin_unlock(ptl);

	/* step 3: set proper refcount and mm_counters. */
	if (nr_mapped_ptes) {
		folio_ref_sub(folio, nr_mapped_ptes);
		add_mm_counter(mm, mm_counter_file(folio), -nr_mapped_ptes);
	}

	/* step 4: remove empty page table */
	if (!pml) {
		pml = pmd_lock(mm, pmd);
		if (ptl != pml) {
			spin_lock_nested(ptl, SINGLE_DEPTH_NESTING);
			if (unlikely(!pmd_same(pgt_pmd, pmdp_get_lockless(pmd)))) {
				flush_tlb_mm(mm);
				goto unlock;
			}
		}
	}
	pgt_pmd = pmdp_collapse_flush(vma, haddr, pmd);
	pmdp_get_lockless_sync();
	pte_unmap_unlock(start_pte, ptl);
	if (ptl != pml)
		spin_unlock(pml);

	mmu_notifier_invalidate_range_end(&range);

	mm_dec_nr_ptes(mm);
	page_table_check_pte_clear_range(mm, haddr, pgt_pmd);
	pte_free_defer(mm, pmd_pgtable(pgt_pmd));

maybe_install_pmd:
	/* step 5: install pmd entry */
	result = install_pmd
			? set_huge_pmd(vma, haddr, pmd, folio, &folio->page)
			: SCAN_SUCCEED;
	goto drop_folio;
abort:
	if (nr_mapped_ptes) {
		flush_tlb_mm(mm);
		folio_ref_sub(folio, nr_mapped_ptes);
		add_mm_counter(mm, mm_counter_file(folio), -nr_mapped_ptes);
	}
unlock:
	if (start_pte)
		pte_unmap_unlock(start_pte, ptl);
	if (pml && pml != ptl)
		spin_unlock(pml);
	if (notified)
		mmu_notifier_invalidate_range_end(&range);
drop_folio:
	folio_unlock(folio);
	folio_put(folio);
	return result;
}

/**
 * collapse_pte_mapped_thp - Try to collapse a pte-mapped THP for mm at
 * address haddr.
 *
 * @mm: process address space where collapse happens
 * @addr: THP collapse address
 * @install_pmd: If a huge PMD should be installed
 *
 * This function checks whether all the PTEs in the PMD are pointing to the
 * right THP. If so, retract the page table so the THP can refault in with
 * as pmd-mapped. Possibly install a huge PMD mapping the THP.
 */
void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
		bool install_pmd)
{
	try_collapse_pte_mapped_thp(mm, addr, install_pmd);
}

/* Can we retract page tables for this file-backed VMA? */
static bool file_backed_vma_is_retractable(struct vm_area_struct *vma)
{
	/*
	 * Check vma->anon_vma to exclude MAP_PRIVATE mappings that
	 * got written to. These VMAs are likely not worth removing
	 * page tables from, as PMD-mapping is likely to be split later.
	 */
	if (READ_ONCE(vma->anon_vma))
		return false;

	/*
	 * When a vma is registered with uffd-wp or RWP, we cannot recycle
	 * the page table because there may be pte markers installed.
	 * VM_UFFD_RWP ranges similarly rely on per-PTE uffd state
	 * and cannot be recycled to a shared PMD. Other vmas can still
	 * have the same file mapped hugely, but skip this one: it will
	 * always be mapped in small page size for these registrations.
	 */
	if (userfaultfd_protected(vma))
		return false;

	/*
	 * If the VMA contains guard regions then we can't collapse it.
	 *
	 * This is set atomically on guard marker installation under mmap/VMA
	 * read lock, and here we may not hold any VMA or mmap lock at all.
	 *
	 * This is therefore serialised on the PTE page table lock, which is
	 * obtained on guard region installation after the flag is set, so this
	 * check being performed under this lock excludes races.
	 */
	if (vma_test_atomic_flag(vma, VMA_MAYBE_GUARD_BIT))
		return false;

	return true;
}

static void retract_page_tables(struct address_space *mapping, pgoff_t pgoff)
{
	struct vm_area_struct *vma;

	i_mmap_lock_read(mapping);
	mapping_rmap_tree_foreach(vma, mapping, pgoff, pgoff) {
		struct mmu_notifier_range range;
		struct mm_struct *mm;
		unsigned long addr;
		pmd_t *pmd, pgt_pmd;
		spinlock_t *pml;
		spinlock_t *ptl;
		bool success = false;

		addr = vma->vm_start +
			((pgoff - vma_start_pgoff(vma)) << PAGE_SHIFT);
		if (addr & ~HPAGE_PMD_MASK ||
		    vma->vm_end < addr + HPAGE_PMD_SIZE)
			continue;

		mm = vma->vm_mm;
		if (find_pmd_or_thp_or_none(mm, addr, &pmd) != SCAN_SUCCEED)
			continue;

		if (collapse_test_exit(mm))
			continue;

		if (!file_backed_vma_is_retractable(vma))
			continue;

		/* PTEs were notified when unmapped; but now for the PMD? */
		mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, mm,
					addr, addr + HPAGE_PMD_SIZE);
		mmu_notifier_invalidate_range_start(&range);

		pml = pmd_lock(mm, pmd);
		/*
		 * The lock of new_folio is still held, we will be blocked in
		 * the page fault path, which prevents the pte entries from
		 * being set again. So even though the old empty PTE page may be
		 * concurrently freed and a new PTE page is filled into the pmd
		 * entry, it is still empty and can be removed.
		 *
		 * So here we only need to recheck if the state of pmd entry
		 * still meets our requirements, rather than checking pmd_same()
		 * like elsewhere.
		 */
		if (check_pmd_state(pmd) != SCAN_SUCCEED)
			goto drop_pml;
		ptl = pte_lockptr(mm, pmd);
		if (ptl != pml)
			spin_lock_nested(ptl, SINGLE_DEPTH_NESTING);

		/*
		 * Huge page lock is still held, so normally the page table must
		 * remain empty; and we have already skipped anon_vma and
		 * userfaultfd_wp() vmas.  But since the mmap_lock is not held,
		 * it is still possible for a racing userfaultfd_ioctl() or
		 * madvise() to have inserted ptes or markers.  Now that we hold
		 * ptlock, repeating the retractable checks protects us from
		 * races against the prior checks.
		 */
		if (likely(file_backed_vma_is_retractable(vma))) {
			pgt_pmd = pmdp_collapse_flush(vma, addr, pmd);
			pmdp_get_lockless_sync();
			success = true;
		}

		if (ptl != pml)
			spin_unlock(ptl);
drop_pml:
		spin_unlock(pml);

		mmu_notifier_invalidate_range_end(&range);

		if (success) {
			mm_dec_nr_ptes(mm);
			page_table_check_pte_clear_range(mm, addr, pgt_pmd);
			pte_free_defer(mm, pmd_pgtable(pgt_pmd));
		}
	}
	i_mmap_unlock_read(mapping);
}

/**
 * collapse_file - collapse filemap/tmpfs/shmem pages into huge one.
 *
 * @mm: process address space where collapse happens
 * @addr: virtual collapse start address
 * @file: file that collapse on
 * @start: collapse start address
 * @cc: collapse context and scratchpad
 *
 * Basic scheme is simple, details are more complex:
 *  - allocate and lock a new huge page;
 *  - scan page cache, locking old pages
 *    + swap/gup in pages if necessary;
 *  - copy data to new page
 *  - handle shmem holes
 *    + re-validate that holes weren't filled by someone else
 *    + check for userfaultfd
 *  - finalize updates to the page cache;
 *  - if replacing succeeds:
 *    + unlock huge page;
 *    + free old pages;
 *  - if replacing failed;
 *    + unlock old pages
 *    + unlock and free huge page;
 */
static enum scan_result collapse_file(struct mm_struct *mm, unsigned long addr,
		struct file *file, pgoff_t start, struct collapse_control *cc)
{
	struct address_space *mapping = file->f_mapping;
	struct page *dst;
	struct folio *folio, *tmp, *new_folio;
	pgoff_t index = 0, end = start + HPAGE_PMD_NR;
	LIST_HEAD(pagelist);
	XA_STATE_ORDER(xas, &mapping->i_pages, start, HPAGE_PMD_ORDER);
	enum scan_result result = SCAN_SUCCEED;
	int nr_none = 0;
	bool is_shmem = shmem_file(file);

	/*
	 * MADV_COLLAPSE ignores shmem huge config, so do not check shmem
	 *
	 * TODO: once shmem always calls mapping_set_large_folios() on its
	 * mapping, the shmem check can be removed.
	 */
	VM_WARN_ON_ONCE(!is_shmem && !mapping_pmd_folio_support(mapping));
	VM_WARN_ON_ONCE(start & (HPAGE_PMD_NR - 1));

	result = alloc_charge_folio(&new_folio, mm, cc, HPAGE_PMD_ORDER);
	if (result != SCAN_SUCCEED)
		goto out;

	mapping_set_update(&xas, mapping);

	__folio_set_locked(new_folio);
	if (is_shmem)
		__folio_set_swapbacked(new_folio);
	new_folio->index = start;
	new_folio->mapping = mapping;

	/*
	 * Ensure we have slots for all the pages in the range.  This is
	 * almost certainly a no-op because most of the pages must be present
	 */
	do {
		xas_lock_irq(&xas);
		xas_create_range(&xas);
		if (!xas_error(&xas))
			break;
		xas_unlock_irq(&xas);
		if (!xas_nomem(&xas, GFP_KERNEL)) {
			result = SCAN_FAIL;
			goto rollback;
		}
	} while (1);

	for (index = start; index < end;) {
		xas_set(&xas, index);
		folio = xas_load(&xas);

		VM_BUG_ON(index != xas.xa_index);
		if (is_shmem) {
			if (!folio) {
				/*
				 * Stop if extent has been truncated or
				 * hole-punched, and is now completely
				 * empty.
				 */
				if (index == start) {
					if (!xas_next_entry(&xas, end - 1)) {
						result = SCAN_TRUNCATED;
						goto xa_locked;
					}
				}
				nr_none++;
				index++;
				continue;
			}

			if (xa_is_value(folio) || !folio_test_uptodate(folio)) {
				xas_unlock_irq(&xas);
				/* swap in or instantiate fallocated page */
				if (shmem_get_folio(mapping->host, index, 0,
						&folio, SGP_NOALLOC)) {
					result = SCAN_FAIL;
					goto xa_unlocked;
				}
				/* drain lru cache to help folio_isolate_lru() */
				lru_add_drain();
			} else if (folio_trylock(folio)) {
				folio_get(folio);
				xas_unlock_irq(&xas);
			} else {
				result = SCAN_PAGE_LOCK;
				goto xa_locked;
			}
		} else {	/* !is_shmem */
			if (!folio || xa_is_value(folio)) {
				xas_unlock_irq(&xas);
				page_cache_sync_readahead(mapping, &file->f_ra,
							  file, index,
							  end - index);
				/* drain lru cache to help folio_isolate_lru() */
				lru_add_drain();
				folio = filemap_lock_folio(mapping, index);
				if (IS_ERR(folio)) {
					result = SCAN_FAIL;
					goto xa_unlocked;
				}
			} else if (folio_test_dirty(folio)) {
				/*
				 * This page is dirty because it hasn't
				 * been flushed since first write.
				 *
				 * Trigger async flush for read-only files and
				 * hope the writeback is done when khugepaged
				 * revisits this page. Writable files can have
				 * their folios dirty at any time; blindly
				 * flushing them would cause undesirable
				 * system-wide writeback.
				 *
				 * This is a one-off situation. We are not
				 * forcing writeback in loop.
				 */
				xas_unlock_irq(&xas);
				if (!inode_is_open_for_write(mapping->host))
					filemap_flush(mapping);
				result = SCAN_PAGE_DIRTY_OR_WRITEBACK;
				goto xa_unlocked;
			} else if (folio_test_writeback(folio)) {
				xas_unlock_irq(&xas);
				result = SCAN_PAGE_DIRTY_OR_WRITEBACK;
				goto xa_unlocked;
			} else if (folio_trylock(folio)) {
				folio_get(folio);
				xas_unlock_irq(&xas);
			} else {
				result = SCAN_PAGE_LOCK;
				goto xa_locked;
			}
		}

		/*
		 * The folio must be locked, so we can drop the i_pages lock
		 * without racing with truncate.
		 */
		VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);

		/* make sure the folio is up to date */
		if (unlikely(!folio_test_uptodate(folio))) {
			result = SCAN_FAIL;
			goto out_unlock;
		}

		/*
		 * If file was truncated then extended, or hole-punched, before
		 * we locked the first folio, then a THP might be there already.
		 * This will be discovered on the first iteration.
		 */
		if (is_pmd_order(folio_order(folio))) {
			result = SCAN_PTE_MAPPED_HUGEPAGE;
			goto out_unlock;
		}

		if (folio_mapping(folio) != mapping) {
			result = SCAN_TRUNCATED;
			goto out_unlock;
		}

		if (!is_shmem && (folio_test_dirty(folio) ||
				  folio_test_writeback(folio))) {
			/*
			 * khugepaged only works on clean file-backed folios,
			 * so this folio is dirty because it hasn't been flushed
			 * since first write.
			 */
			result = SCAN_PAGE_DIRTY_OR_WRITEBACK;
			goto out_unlock;
		}

		if (!folio_isolate_lru(folio)) {
			result = SCAN_DEL_PAGE_LRU;
			goto out_unlock;
		}

		if (!filemap_release_folio(folio, GFP_KERNEL)) {
			result = SCAN_PAGE_HAS_PRIVATE;
			folio_putback_lru(folio);
			goto out_unlock;
		}

		if (folio_mapped(folio))
			try_to_unmap(folio,
					TTU_IGNORE_MLOCK | TTU_BATCH_FLUSH);

		xas_lock_irq(&xas);

		VM_BUG_ON_FOLIO(folio != xa_load(xas.xa, index), folio);

		/*
		 * We control 2 + nr_pages references to the folio:
		 *  - we hold a pin on it;
		 *  - nr_pages reference from page cache;
		 *  - one from lru_isolate_folio;
		 * If those are the only references, then any new usage
		 * of the folio will have to fetch it from the page
		 * cache. That requires locking the folio to handle
		 * truncate, so any new usage will be blocked until we
		 * unlock folio after collapse/during rollback.
		 */
		if (folio_ref_count(folio) != 2 + folio_nr_pages(folio)) {
			result = SCAN_PAGE_COUNT;
			xas_unlock_irq(&xas);
			folio_putback_lru(folio);
			goto out_unlock;
		}

		/*
		 * At this point, the folio is locked and unmapped. If the PTE
		 * was dirty, try_to_unmap() has transferred the dirty bit to
		 * the folio and we must not collapse it into a clean
		 * file-backed folio.
		 *
		 * If the folio is clean here, no one can write it until we
		 * drop the folio lock. A write through a stale TLB entry came
		 * from a clean PTE and must fault because the PTE has been
		 * cleared; the fault path has to take the folio lock before
		 * installing a writable mapping. Buffered write paths also
		 * have to take the folio lock before modifying file contents
		 * without a mapping, typically via write_begin_get_folio().
		 */
		if (!is_shmem && folio_test_dirty(folio)) {
			result = SCAN_PAGE_DIRTY_OR_WRITEBACK;
			xas_unlock_irq(&xas);
			folio_putback_lru(folio);
			goto out_unlock;
		}

		/*
		 * Accumulate the folios that are being collapsed.
		 */
		list_add_tail(&folio->lru, &pagelist);
		index += folio_nr_pages(folio);
		continue;
out_unlock:
		folio_unlock(folio);
		folio_put(folio);
		goto xa_unlocked;
	}

xa_locked:
	xas_unlock_irq(&xas);
xa_unlocked:

	/*
	 * If collapse is successful, flush must be done now before copying.
	 * If collapse is unsuccessful, does flush actually need to be done?
	 * Do it anyway, to clear the state.
	 */
	try_to_unmap_flush();

	if (result == SCAN_SUCCEED && nr_none &&
	    !shmem_charge(mapping->host, nr_none))
		result = SCAN_FAIL;
	if (result != SCAN_SUCCEED) {
		nr_none = 0;
		goto rollback;
	}

	/*
	 * The old folios are locked, so they won't change anymore.
	 */
	index = start;
	dst = folio_page(new_folio, 0);
	list_for_each_entry(folio, &pagelist, lru) {
		int i, nr_pages = folio_nr_pages(folio);

		while (index < folio->index) {
			clear_highpage(dst);
			index++;
			dst++;
		}

		for (i = 0; i < nr_pages; i++) {
			if (copy_mc_highpage(dst, folio_page(folio, i)) > 0) {
				result = SCAN_COPY_MC;
				goto rollback;
			}
			index++;
			dst++;
		}
	}
	while (index < end) {
		clear_highpage(dst);
		index++;
		dst++;
	}

	if (nr_none) {
		struct vm_area_struct *vma;
		int nr_none_check = 0;

		i_mmap_lock_read(mapping);
		xas_lock_irq(&xas);

		xas_set(&xas, start);
		for (index = start; index < end; index++) {
			if (!xas_next(&xas)) {
				xas_store(&xas, XA_RETRY_ENTRY);
				if (xas_error(&xas)) {
					result = SCAN_STORE_FAILED;
					goto immap_locked;
				}
				nr_none_check++;
			}
		}

		if (nr_none != nr_none_check) {
			result = SCAN_PAGE_FILLED;
			goto immap_locked;
		}

		/*
		 * If userspace observed a missing page in a VMA with
		 * a MODE_MISSING userfaultfd, then it might expect a
		 * UFFD_EVENT_PAGEFAULT for that page. If so, we need to
		 * roll back to avoid suppressing such an event. Since
		 * wp/minor userfaultfds don't give userspace any
		 * guarantees that the kernel doesn't fill a missing
		 * page with a zero page, so they don't matter here.
		 *
		 * Any userfaultfds registered after this point will
		 * not be able to observe any missing pages due to the
		 * previously inserted retry entries.
		 */
		mapping_rmap_tree_foreach(vma, mapping, start, end) {
			if (userfaultfd_missing(vma)) {
				result = SCAN_EXCEED_NONE_PTE;
				goto immap_locked;
			}
		}

immap_locked:
		i_mmap_unlock_read(mapping);
		if (result != SCAN_SUCCEED) {
			xas_set(&xas, start);
			for (index = start; index < end; index++) {
				if (xas_next(&xas) == XA_RETRY_ENTRY)
					xas_store(&xas, NULL);
			}

			xas_unlock_irq(&xas);
			goto rollback;
		}
	} else {
		xas_lock_irq(&xas);
	}

	if (is_shmem) {
		lruvec_stat_mod_folio(new_folio, NR_SHMEM, HPAGE_PMD_NR);
		lruvec_stat_mod_folio(new_folio, NR_SHMEM_THPS, HPAGE_PMD_NR);
	} else {
		lruvec_stat_mod_folio(new_folio, NR_FILE_THPS, HPAGE_PMD_NR);
	}
	lruvec_stat_mod_folio(new_folio, NR_FILE_PAGES, HPAGE_PMD_NR);

	/*
	 * Mark new_folio as uptodate before inserting it into the
	 * page cache so that it isn't mistaken for an fallocated but
	 * unwritten page.
	 */
	folio_mark_uptodate(new_folio);
	folio_ref_add(new_folio, HPAGE_PMD_NR - 1);

	if (is_shmem)
		folio_mark_dirty(new_folio);
	folio_add_lru(new_folio);

	/* Join all the small entries into a single multi-index entry. */
	xas_set_order(&xas, start, HPAGE_PMD_ORDER);
	xas_store(&xas, new_folio);
	WARN_ON_ONCE(xas_error(&xas));
	xas_unlock_irq(&xas);

	/*
	 * Remove pte page tables, so we can re-fault the page as huge.
	 * If MADV_COLLAPSE, adjust result to call try_collapse_pte_mapped_thp().
	 */
	retract_page_tables(mapping, start);
	if (cc && !cc->is_khugepaged)
		result = SCAN_PTE_MAPPED_HUGEPAGE;
	folio_unlock(new_folio);

	/*
	 * The collapse has succeeded, so free the old folios.
	 */
	list_for_each_entry_safe(folio, tmp, &pagelist, lru) {
		list_del(&folio->lru);
		lruvec_stat_mod_folio(folio, NR_FILE_PAGES,
				      -folio_nr_pages(folio));
		if (is_shmem)
			lruvec_stat_mod_folio(folio, NR_SHMEM,
					      -folio_nr_pages(folio));
		folio->mapping = NULL;
		folio_clear_active(folio);
		folio_clear_unevictable(folio);
		folio_unlock(folio);
		folio_put_refs(folio, 2 + folio_nr_pages(folio));
	}

	goto out;

rollback:
	/* Something went wrong: roll back page cache changes */
	if (nr_none) {
		xas_lock_irq(&xas);
		mapping->nrpages -= nr_none;
		xas_unlock_irq(&xas);
		shmem_uncharge(mapping->host, nr_none);
	}

	list_for_each_entry_safe(folio, tmp, &pagelist, lru) {
		list_del(&folio->lru);
		folio_unlock(folio);
		folio_putback_lru(folio);
		folio_put(folio);
	}

	new_folio->mapping = NULL;

	folio_unlock(new_folio);
	folio_put(new_folio);
out:
	VM_BUG_ON(!list_empty(&pagelist));
	trace_mm_khugepaged_collapse_file(mm, new_folio, index, addr, is_shmem, file, HPAGE_PMD_NR, result);
	return result;
}

static enum scan_result collapse_scan_file(struct mm_struct *mm,
		unsigned long addr, struct file *file, pgoff_t start,
		struct collapse_control *cc)
{
	const unsigned int max_ptes_none = collapse_max_ptes_none(cc, NULL, HPAGE_PMD_ORDER);
	const unsigned int max_ptes_swap = collapse_max_ptes_swap(cc, HPAGE_PMD_ORDER);
	struct folio *folio = NULL;
	struct address_space *mapping = file->f_mapping;
	XA_STATE(xas, &mapping->i_pages, start);
	int present, swap;
	int node = NUMA_NO_NODE;
	enum scan_result result = SCAN_SUCCEED;

	present = 0;
	swap = 0;
	collapse_control_init_scan(cc);
	rcu_read_lock();
	xas_for_each(&xas, folio, start + HPAGE_PMD_NR - 1) {
		if (xas_retry(&xas, folio))
			continue;

		if (xa_is_value(folio)) {
			swap += 1 << xas_get_order(&xas);
			if (swap > max_ptes_swap) {
				result = SCAN_EXCEED_SWAP_PTE;
				count_vm_event(THP_SCAN_EXCEED_SWAP_PTE);
				break;
			}
			continue;
		}

		if (!folio_try_get(folio)) {
			xas_reset(&xas);
			continue;
		}

		if (unlikely(folio != xas_reload(&xas))) {
			folio_put(folio);
			xas_reset(&xas);
			continue;
		}

		if (is_pmd_order(folio_order(folio))) {
			result = SCAN_PTE_MAPPED_HUGEPAGE;
			/*
			 * PMD-sized THP implies that we can only try
			 * retracting the PTE table.
			 */
			folio_put(folio);
			break;
		}

		node = folio_nid(folio);
		if (collapse_scan_abort(node, cc)) {
			result = SCAN_SCAN_ABORT;
			folio_put(folio);
			break;
		}
		cc->node_load[node]++;

		if (!folio_test_lru(folio)) {
			result = SCAN_PAGE_LRU;
			folio_put(folio);
			break;
		}

		if (folio_expected_ref_count(folio) + 1 != folio_ref_count(folio)) {
			result = SCAN_PAGE_COUNT;
			folio_put(folio);
			break;
		}

		/*
		 * We probably should check if the folio is referenced
		 * here, but nobody would transfer pte_young() to
		 * folio_test_referenced() for us.  And rmap walk here
		 * is just too costly...
		 */

		present += folio_nr_pages(folio);
		folio_put(folio);

		if (need_resched()) {
			xas_pause(&xas);
			cond_resched_rcu();
		}
	}
	rcu_read_unlock();
	if (result == SCAN_PTE_MAPPED_HUGEPAGE)
		cc->progress++;
	else
		cc->progress += HPAGE_PMD_NR;

	if (result == SCAN_SUCCEED) {
		if (present < HPAGE_PMD_NR - max_ptes_none) {
			result = SCAN_EXCEED_NONE_PTE;
			count_vm_event(THP_SCAN_EXCEED_NONE_PTE);
		} else {
			result = collapse_file(mm, addr, file, start, cc);
		}
	}

	trace_mm_khugepaged_scan_file(mm, folio, file, present, swap, result);
	return result;
}

/*
 * Try to collapse a single PMD starting at a PMD aligned addr, and return
 * the results.
 */
static enum scan_result collapse_single_pmd(unsigned long addr,
		struct vm_area_struct *vma, bool *lock_dropped,
		struct collapse_control *cc)
{
	struct mm_struct *mm = vma->vm_mm;
	bool triggered_wb = false;
	enum scan_result result;
	struct file *file;
	pgoff_t pgoff;

	mmap_assert_locked(mm);

	if (vma_is_anonymous(vma)) {
		result = collapse_scan_pmd(mm, vma, addr, lock_dropped, cc);
		goto end;
	}

	file = get_file(vma->vm_file);
	pgoff = linear_page_index(vma, addr);

	mmap_read_unlock(mm);
	*lock_dropped = true;
retry:
	result = collapse_scan_file(mm, addr, file, pgoff, cc);

	/*
	 * For MADV_COLLAPSE, when encountering dirty pages, try to writeback,
	 * then retry the collapse one time.
	 */
	if (!cc->is_khugepaged && result == SCAN_PAGE_DIRTY_OR_WRITEBACK &&
	    !triggered_wb && mapping_can_writeback(file->f_mapping)) {
		const loff_t lstart = (loff_t)pgoff << PAGE_SHIFT;
		const loff_t lend = lstart + HPAGE_PMD_SIZE - 1;

		filemap_write_and_wait_range(file->f_mapping, lstart, lend);
		triggered_wb = true;
		goto retry;
	}
	fput(file);

	if (result == SCAN_PTE_MAPPED_HUGEPAGE) {
		mmap_read_lock(mm);
		if (collapse_test_exit_or_disable(mm))
			result = SCAN_ANY_PROCESS;
		else
			result = try_collapse_pte_mapped_thp(mm, addr,
							     !cc->is_khugepaged);
		if (result == SCAN_PMD_MAPPED)
			result = SCAN_SUCCEED;
		mmap_read_unlock(mm);
	}
end:
	if (cc->is_khugepaged && result == SCAN_SUCCEED)
		++khugepaged_pages_collapsed;
	return result;
}

static void collapse_scan_mm_slot(unsigned int progress_max,
		enum scan_result *result, struct collapse_control *cc)
	__releases(&khugepaged_mm_lock)
	__acquires(&khugepaged_mm_lock)
{
	struct vma_iterator vmi;
	struct mm_slot *slot;
	struct mm_struct *mm;
	struct vm_area_struct *vma;
	unsigned int progress_prev = cc->progress;

	lockdep_assert_held(&khugepaged_mm_lock);
	*result = SCAN_FAIL;

	if (khugepaged_scan.mm_slot) {
		slot = khugepaged_scan.mm_slot;
	} else {
		slot = list_first_entry(&khugepaged_scan.mm_head,
				     struct mm_slot, mm_node);
		khugepaged_scan.address = 0;
		khugepaged_scan.mm_slot = slot;
	}
	spin_unlock(&khugepaged_mm_lock);

	mm = slot->mm;
	/*
	 * Don't wait for semaphore (to avoid long wait times).  Just move to
	 * the next mm on the list.
	 */
	vma = NULL;
	if (unlikely(!mmap_read_trylock(mm)))
		goto breakouterloop_mmap_lock;

	cc->progress++;
	if (unlikely(collapse_test_exit_or_disable(mm)))
		goto breakouterloop;

	vma_iter_init(&vmi, mm, khugepaged_scan.address);
	for_each_vma(vmi, vma) {
		unsigned long hstart, hend;

		cond_resched();
		if (unlikely(collapse_test_exit_or_disable(mm))) {
			cc->progress++;
			break;
		}
		if (!collapse_possible(vma, vma->vm_flags, TVA_KHUGEPAGED)) {
			cc->progress++;
			continue;
		}
		hstart = ALIGN(vma->vm_start, HPAGE_PMD_SIZE);
		hend = ALIGN_DOWN(vma->vm_end, HPAGE_PMD_SIZE);
		if (khugepaged_scan.address > hend) {
			cc->progress++;
			continue;
		}
		if (khugepaged_scan.address < hstart)
			khugepaged_scan.address = hstart;
		VM_BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK);

		while (khugepaged_scan.address < hend) {
			bool lock_dropped = false;

			cond_resched();
			if (unlikely(collapse_test_exit_or_disable(mm)))
				goto breakouterloop;

			VM_WARN_ON_ONCE(khugepaged_scan.address < hstart ||
				  khugepaged_scan.address + HPAGE_PMD_SIZE >
				  hend);

			*result = collapse_single_pmd(khugepaged_scan.address,
						      vma, &lock_dropped, cc);
			/* move to next address */
			khugepaged_scan.address += HPAGE_PMD_SIZE;
			if (lock_dropped)
				/*
				 * We released mmap_lock so break loop.  Note
				 * that we drop mmap_lock before all hugepage
				 * allocations, so if allocation fails, we are
				 * guaranteed to break here and report the
				 * correct result back to caller.
				 */
				goto breakouterloop_mmap_lock;
			if (cc->progress >= progress_max)
				goto breakouterloop;
		}
	}
breakouterloop:
	mmap_read_unlock(mm); /* exit_mmap will destroy ptes after this */
breakouterloop_mmap_lock:

	spin_lock(&khugepaged_mm_lock);
	VM_BUG_ON(khugepaged_scan.mm_slot != slot);
	/*
	 * Release the current mm_slot if this mm is about to die, or
	 * if we scanned all vmas of this mm, or THP got disabled.
	 */
	if (collapse_test_exit_or_disable(mm) || !vma) {
		/*
		 * Make sure that if mm_users is reaching zero while
		 * khugepaged runs here, khugepaged_exit will find
		 * mm_slot not pointing to the exiting mm.
		 */
		if (!list_is_last(&slot->mm_node, &khugepaged_scan.mm_head)) {
			khugepaged_scan.mm_slot = list_next_entry(slot, mm_node);
			khugepaged_scan.address = 0;
		} else {
			khugepaged_scan.mm_slot = NULL;
			khugepaged_full_scans++;
		}

		collect_mm_slot(slot);
	}

	trace_mm_khugepaged_scan(mm, cc->progress - progress_prev,
				 khugepaged_scan.mm_slot == NULL);
}

static int khugepaged_has_work(void)
{
	return !list_empty(&khugepaged_scan.mm_head) && hugepage_enabled();
}

static int khugepaged_wait_event(void)
{
	return !list_empty(&khugepaged_scan.mm_head) ||
		kthread_should_stop();
}

static void khugepaged_do_scan(struct collapse_control *cc)
{
	const unsigned int progress_max = READ_ONCE(khugepaged_pages_to_scan);
	unsigned int pass_through_head = 0;
	bool wait = true;
	enum scan_result result = SCAN_SUCCEED;

	lru_add_drain_all();

	cc->progress = 0;
	while (true) {
		cond_resched();

		if (unlikely(kthread_should_stop()))
			break;

		spin_lock(&khugepaged_mm_lock);
		if (!khugepaged_scan.mm_slot)
			pass_through_head++;
		if (khugepaged_has_work() &&
		    pass_through_head < 2)
			collapse_scan_mm_slot(progress_max, &result, cc);
		else
			cc->progress = progress_max;
		spin_unlock(&khugepaged_mm_lock);

		if (cc->progress >= progress_max)
			break;

		if (result == SCAN_ALLOC_HUGE_PAGE_FAIL) {
			/*
			 * If fail to allocate the first time, try to sleep for
			 * a while.  When hit again, cancel the scan.
			 */
			if (!wait)
				break;
			wait = false;
			khugepaged_alloc_sleep();
		}
	}
}

static bool khugepaged_should_wakeup(void)
{
	return kthread_should_stop() ||
	       time_after_eq(jiffies, khugepaged_sleep_expire);
}

static void khugepaged_wait_work(void)
{
	if (khugepaged_has_work()) {
		const unsigned long scan_sleep_jiffies =
			msecs_to_jiffies(khugepaged_scan_sleep_millisecs);

		if (!scan_sleep_jiffies)
			return;

		khugepaged_sleep_expire = jiffies + scan_sleep_jiffies;
		wait_event_freezable_timeout(khugepaged_wait,
					     khugepaged_should_wakeup(),
					     scan_sleep_jiffies);
		return;
	}

	if (hugepage_enabled())
		wait_event_freezable(khugepaged_wait, khugepaged_wait_event());
}

static int khugepaged(void *none)
{
	struct mm_slot *slot;

	set_freezable();
	set_user_nice(current, MAX_NICE);

	while (!kthread_should_stop()) {
		khugepaged_do_scan(&khugepaged_collapse_control);
		khugepaged_wait_work();
	}

	spin_lock(&khugepaged_mm_lock);
	slot = khugepaged_scan.mm_slot;
	khugepaged_scan.mm_slot = NULL;
	if (slot)
		collect_mm_slot(slot);
	spin_unlock(&khugepaged_mm_lock);
	return 0;
}

void set_recommended_min_free_kbytes(void)
{
	struct zone *zone;
	int nr_zones = 0;
	unsigned long recommended_min;

	if (!hugepage_enabled()) {
		calculate_min_free_kbytes();
		goto update_wmarks;
	}

	for_each_populated_zone(zone) {
		/*
		 * We don't need to worry about fragmentation of
		 * ZONE_MOVABLE since it only has movable pages.
		 */
		if (zone_idx(zone) > gfp_zone(GFP_USER))
			continue;

		nr_zones++;
	}

	/* Ensure 2 pageblocks are free to assist fragmentation avoidance */
	recommended_min = pageblock_nr_pages * nr_zones * 2;

	/*
	 * Make sure that on average at least two pageblocks are almost free
	 * of another type, one for a migratetype to fall back to and a
	 * second to avoid subsequent fallbacks of other types There are 3
	 * MIGRATE_TYPES we care about.
	 */
	recommended_min += pageblock_nr_pages * nr_zones *
			   MIGRATE_PCPTYPES * MIGRATE_PCPTYPES;

	/* don't ever allow to reserve more than 5% of the lowmem */
	recommended_min = min(recommended_min,
			      (unsigned long) nr_free_buffer_pages() / 20);
	recommended_min <<= (PAGE_SHIFT-10);

	if (recommended_min > min_free_kbytes) {
		if (user_min_free_kbytes >= 0)
			pr_info_ratelimited("raising min_free_kbytes from %d to %lu to help transparent hugepage allocations\n",
					    min_free_kbytes, recommended_min);

		min_free_kbytes = recommended_min;
	}

update_wmarks:
	setup_per_zone_wmarks();
}

int start_stop_khugepaged(void)
{
	guard(mutex)(&khugepaged_mutex);
	if (hugepage_enabled()) {
		if (!khugepaged_thread) {
			struct task_struct *new_thread = kthread_run(khugepaged,
								     NULL,
								     "khugepaged");

			if (IS_ERR(new_thread)) {
				pr_err("khugepaged: kthread_run(khugepaged) failed\n");
				return PTR_ERR(new_thread);
			}

			khugepaged_thread = new_thread;
		}

		if (!list_empty(&khugepaged_scan.mm_head))
			wake_up_interruptible(&khugepaged_wait);
	} else if (khugepaged_thread) {
		kthread_stop(khugepaged_thread);
		khugepaged_thread = NULL;
	}
	set_recommended_min_free_kbytes();
	return 0;
}

void khugepaged_min_free_kbytes_update(void)
{
	guard(mutex)(&khugepaged_mutex);
	if (hugepage_enabled() && khugepaged_thread)
		set_recommended_min_free_kbytes();
}

bool current_is_khugepaged(void)
{
	return kthread_func(current) == khugepaged;
}

static int madvise_collapse_errno(enum scan_result r)
{
	/*
	 * MADV_COLLAPSE breaks from existing madvise(2) conventions to provide
	 * actionable feedback to caller, so they may take an appropriate
	 * fallback measure depending on the nature of the failure.
	 */
	switch (r) {
	case SCAN_ALLOC_HUGE_PAGE_FAIL:
		return -ENOMEM;
	case SCAN_CGROUP_CHARGE_FAIL:
	case SCAN_EXCEED_NONE_PTE:
		return -EBUSY;
	/* Resource temporary unavailable - trying again might succeed */
	case SCAN_PAGE_COUNT:
	case SCAN_PAGE_LOCK:
	case SCAN_PAGE_LRU:
	case SCAN_DEL_PAGE_LRU:
	case SCAN_PAGE_FILLED:
	case SCAN_PAGE_HAS_PRIVATE:
	case SCAN_PAGE_DIRTY_OR_WRITEBACK:
		return -EAGAIN;
	/*
	 * Other: Trying again likely not to succeed / error intrinsic to
	 * specified memory range. khugepaged likely won't be able to collapse
	 * either.
	 */
	default:
		return -EINVAL;
	}
}

int madvise_collapse(struct vm_area_struct *vma, unsigned long start,
		     unsigned long end, bool *lock_dropped)
{
	struct collapse_control *cc;
	struct mm_struct *mm = vma->vm_mm;
	unsigned long hstart, hend, addr;
	enum scan_result last_fail = SCAN_FAIL;
	int thps = 0;
	bool mmap_unlocked = false;

	BUG_ON(vma->vm_start > start);
	BUG_ON(vma->vm_end < end);

	if (!collapse_possible(vma, vma->vm_flags, TVA_FORCED_COLLAPSE))
		return -EINVAL;

	hstart = ALIGN(start, HPAGE_PMD_SIZE);
	hend = ALIGN_DOWN(end, HPAGE_PMD_SIZE);

	if (hstart >= hend)
		return 0;

	cc = kmalloc_obj(*cc);
	if (!cc)
		return -ENOMEM;
	cc->is_khugepaged = false;
	cc->progress = 0;

	mmgrab(mm);
	lru_add_drain_all();

	for (addr = hstart; addr < hend; addr += HPAGE_PMD_SIZE) {
		enum scan_result result = SCAN_FAIL;

		if (mmap_unlocked) {
			cond_resched();
			mmap_read_lock(mm);
			mmap_unlocked = false;
			*lock_dropped = true;
			result = hugepage_vma_revalidate(mm, addr, false, &vma,
							 cc, HPAGE_PMD_ORDER);
			if (result != SCAN_SUCCEED) {
				last_fail = result;
				goto out_nolock;
			}

			hend = min(hend, vma->vm_end & HPAGE_PMD_MASK);
		}

		result = collapse_single_pmd(addr, vma, &mmap_unlocked, cc);

		switch (result) {
		case SCAN_SUCCEED:
		case SCAN_PMD_MAPPED:
			++thps;
			break;
		/* Whitelisted set of results where continuing OK */
		case SCAN_NO_PTE_TABLE:
		case SCAN_PTE_NON_PRESENT:
		case SCAN_PTE_UFFD:
		case SCAN_LACK_REFERENCED_PAGE:
		case SCAN_PAGE_NULL:
		case SCAN_PAGE_COUNT:
		case SCAN_PAGE_LOCK:
		case SCAN_PAGE_COMPOUND:
		case SCAN_PAGE_LRU:
		case SCAN_DEL_PAGE_LRU:
			last_fail = result;
			break;
		default:
			last_fail = result;
			/* Other error, exit */
			goto out_maybelock;
		}
	}

out_maybelock:
	/* Caller expects us to hold mmap_lock on return */
	if (mmap_unlocked) {
		*lock_dropped = true;
		mmap_read_lock(mm);
	}
out_nolock:
	mmap_assert_locked(mm);
	mmdrop(mm);
	kfree(cc);

	return thps == ((hend - hstart) >> HPAGE_PMD_SHIFT) ? 0
			: madvise_collapse_errno(last_fail);
}
