// SPDX-License-Identifier: GPL-2.0
/*
 * linux/mm/compaction.c
 *
 * Memory compaction for the reduction of external fragmentation. Note that
 * this heavily depends upon page migration to do all the real heavy
 * lifting
 *
 * Copyright IBM Corp. 2007-2010 Mel Gorman <mel@csn.ul.ie>
 */
#include <linux/cpu.h>
#include <linux/swap.h>
#include <linux/migrate.h>
#include <linux/compaction.h>
#include <linux/mm_inline.h>
#include <linux/sched/signal.h>
#include <linux/backing-dev.h>
#include <linux/sysctl.h>
#include <linux/sysfs.h>
#include <linux/page-isolation.h>
#include <linux/kasan.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/page_owner.h>
#include <linux/psi.h>
#include <linux/cpuset.h>
#include "internal.h"

#ifdef CONFIG_COMPACTION
/*
 * Fragmentation score check interval for proactive compaction purposes.
 */
#define HPAGE_FRAG_CHECK_INTERVAL_MSEC	(500)

static inline void count_compact_event(enum vm_event_item item)
{
	count_vm_event(item);
}

static inline void count_compact_events(enum vm_event_item item, long delta)
{
	count_vm_events(item, delta);
}

/*
 * order == -1 is expected when compacting proactively via
 * 1. /proc/sys/vm/compact_memory
 * 2. /sys/devices/system/node/nodex/compact
 * 3. /proc/sys/vm/compaction_proactiveness
 */
static inline bool is_via_compact_memory(int order)
{
	return order == -1;
}

#else
#define count_compact_event(item) do { } while (0)
#define count_compact_events(item, delta) do { } while (0)
static inline bool is_via_compact_memory(int order) { return false; }
#endif

#if defined CONFIG_COMPACTION || defined CONFIG_CMA

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

#define block_start_pfn(pfn, order)	round_down(pfn, 1UL << (order))
#define block_end_pfn(pfn, order)	ALIGN((pfn) + 1, 1UL << (order))

/*
 * Page order with-respect-to which proactive compaction
 * calculates external fragmentation, which is used as
 * the "fragmentation score" of a node/zone.
 */
#if defined CONFIG_TRANSPARENT_HUGEPAGE
#define COMPACTION_HPAGE_ORDER	HPAGE_PMD_ORDER
#elif defined CONFIG_HUGETLBFS
#define COMPACTION_HPAGE_ORDER	HUGETLB_PAGE_ORDER
#else
#define COMPACTION_HPAGE_ORDER	(PMD_SHIFT - PAGE_SHIFT)
#endif

static struct page *mark_allocated_noprof(struct page *page, unsigned int order, gfp_t gfp_flags)
{
	post_alloc_hook(page, order, __GFP_MOVABLE);
	set_page_refcounted(page);
	return page;
}
#define mark_allocated(...)	alloc_hooks(mark_allocated_noprof(__VA_ARGS__))

static unsigned long release_free_list(struct list_head *freepages)
{
	int order;
	unsigned long high_pfn = 0;

	for (order = 0; order < NR_PAGE_ORDERS; order++) {
		struct page *page, *next;

		list_for_each_entry_safe(page, next, &freepages[order], lru) {
			unsigned long pfn = page_to_pfn(page);

			list_del(&page->lru);
			/*
			 * Convert free pages into post allocation pages, so
			 * that we can free them via __free_page.
			 */
			mark_allocated(page, order, __GFP_MOVABLE);
			__free_pages(page, order);
			if (pfn > high_pfn)
				high_pfn = pfn;
		}
	}
	return high_pfn;
}

#ifdef CONFIG_COMPACTION
bool PageMovable(struct page *page)
{
	const struct movable_operations *mops;

	VM_BUG_ON_PAGE(!PageLocked(page), page);
	if (!__PageMovable(page))
		return false;

	mops = page_movable_ops(page);
	if (mops)
		return true;

	return false;
}

void __SetPageMovable(struct page *page, const struct movable_operations *mops)
{
	VM_BUG_ON_PAGE(!PageLocked(page), page);
	VM_BUG_ON_PAGE((unsigned long)mops & PAGE_MAPPING_MOVABLE, page);
	page->mapping = (void *)((unsigned long)mops | PAGE_MAPPING_MOVABLE);
}
EXPORT_SYMBOL(__SetPageMovable);

void __ClearPageMovable(struct page *page)
{
	VM_BUG_ON_PAGE(!PageMovable(page), page);
	/*
	 * This page still has the type of a movable page, but it's
	 * actually not movable any more.
	 */
	page->mapping = (void *)PAGE_MAPPING_MOVABLE;
}
EXPORT_SYMBOL(__ClearPageMovable);

/* Do not skip compaction more than 64 times */
#define COMPACT_MAX_DEFER_SHIFT 6

/*
 * Compaction is deferred when compaction fails to result in a page
 * allocation success. 1 << compact_defer_shift, compactions are skipped up
 * to a limit of 1 << COMPACT_MAX_DEFER_SHIFT
 */
static void defer_compaction(struct zone *zone, int order)
{
	zone->compact_considered = 0;
	zone->compact_defer_shift++;

	if (order < zone->compact_order_failed)
		zone->compact_order_failed = order;

	if (zone->compact_defer_shift > COMPACT_MAX_DEFER_SHIFT)
		zone->compact_defer_shift = COMPACT_MAX_DEFER_SHIFT;

	trace_mm_compaction_defer_compaction(zone, order);
}

/* Returns true if compaction should be skipped this time */
static bool compaction_deferred(struct zone *zone, int order)
{
	unsigned long defer_limit = 1UL << zone->compact_defer_shift;

	if (order < zone->compact_order_failed)
		return false;

	/* Avoid possible overflow */
	if (++zone->compact_considered >= defer_limit) {
		zone->compact_considered = defer_limit;
		return false;
	}

	trace_mm_compaction_deferred(zone, order);

	return true;
}

/*
 * Update defer tracking counters after successful compaction of given order,
 * which means an allocation either succeeded (alloc_success == true) or is
 * expected to succeed.
 */
void compaction_defer_reset(struct zone *zone, int order,
		bool alloc_success)
{
	if (alloc_success) {
		zone->compact_considered = 0;
		zone->compact_defer_shift = 0;
	}
	if (order >= zone->compact_order_failed)
		zone->compact_order_failed = order + 1;

	trace_mm_compaction_defer_reset(zone, order);
}

/* Returns true if restarting compaction after many failures */
static bool compaction_restarting(struct zone *zone, int order)
{
	if (order < zone->compact_order_failed)
		return false;

	return zone->compact_defer_shift == COMPACT_MAX_DEFER_SHIFT &&
		zone->compact_considered >= 1UL << zone->compact_defer_shift;
}

/* Returns true if the pageblock should be scanned for pages to isolate. */
static inline bool isolation_suitable(struct compact_control *cc,
					struct page *page)
{
	if (cc->ignore_skip_hint)
		return true;

	return !get_pageblock_skip(page);
}

static void reset_cached_positions(struct zone *zone)
{
	zone->compact_cached_migrate_pfn[0] = zone->zone_start_pfn;
	zone->compact_cached_migrate_pfn[1] = zone->zone_start_pfn;
	zone->compact_cached_free_pfn =
				pageblock_start_pfn(zone_end_pfn(zone) - 1);
}

#ifdef CONFIG_SPARSEMEM
/*
 * If the PFN falls into an offline section, return the start PFN of the
 * next online section. If the PFN falls into an online section or if
 * there is no next online section, return 0.
 */
static unsigned long skip_offline_sections(unsigned long start_pfn)
{
	unsigned long start_nr = pfn_to_section_nr(start_pfn);

	if (online_section_nr(start_nr))
		return 0;

	while (++start_nr <= __highest_present_section_nr) {
		if (online_section_nr(start_nr))
			return section_nr_to_pfn(start_nr);
	}

	return 0;
}

/*
 * If the PFN falls into an offline section, return the end PFN of the
 * next online section in reverse. If the PFN falls into an online section
 * or if there is no next online section in reverse, return 0.
 */
static unsigned long skip_offline_sections_reverse(unsigned long start_pfn)
{
	unsigned long start_nr = pfn_to_section_nr(start_pfn);

	if (!start_nr || online_section_nr(start_nr))
		return 0;

	while (start_nr-- > 0) {
		if (online_section_nr(start_nr))
			return section_nr_to_pfn(start_nr) + PAGES_PER_SECTION;
	}

	return 0;
}
#else
static unsigned long skip_offline_sections(unsigned long start_pfn)
{
	return 0;
}

static unsigned long skip_offline_sections_reverse(unsigned long start_pfn)
{
	return 0;
}
#endif

/*
 * Compound pages of >= pageblock_order should consistently be skipped until
 * released. It is always pointless to compact pages of such order (if they are
 * migratable), and the pageblocks they occupy cannot contain any free pages.
 */
static bool pageblock_skip_persistent(struct page *page)
{
	if (!PageCompound(page))
		return false;

	page = compound_head(page);

	if (compound_order(page) >= pageblock_order)
		return true;

	return false;
}

static bool
__reset_isolation_pfn(struct zone *zone, unsigned long pfn, bool check_source,
							bool check_target)
{
	struct page *page = pfn_to_online_page(pfn);
	struct page *block_page;
	struct page *end_page;
	unsigned long block_pfn;

	if (!page)
		return false;
	if (zone != page_zone(page))
		return false;
	if (pageblock_skip_persistent(page))
		return false;

	/*
	 * If skip is already cleared do no further checking once the
	 * restart points have been set.
	 */
	if (check_source && check_target && !get_pageblock_skip(page))
		return true;

	/*
	 * If clearing skip for the target scanner, do not select a
	 * non-movable pageblock as the starting point.
	 */
	if (!check_source && check_target &&
	    get_pageblock_migratetype(page) != MIGRATE_MOVABLE)
		return false;

	/* Ensure the start of the pageblock or zone is online and valid */
	block_pfn = pageblock_start_pfn(pfn);
	block_pfn = max(block_pfn, zone->zone_start_pfn);
	block_page = pfn_to_online_page(block_pfn);
	if (block_page) {
		page = block_page;
		pfn = block_pfn;
	}

	/* Ensure the end of the pageblock or zone is online and valid */
	block_pfn = pageblock_end_pfn(pfn) - 1;
	block_pfn = min(block_pfn, zone_end_pfn(zone) - 1);
	end_page = pfn_to_online_page(block_pfn);
	if (!end_page)
		return false;

	/*
	 * Only clear the hint if a sample indicates there is either a
	 * free page or an LRU page in the block. One or other condition
	 * is necessary for the block to be a migration source/target.
	 */
	do {
		if (check_source && PageLRU(page)) {
			clear_pageblock_skip(page);
			return true;
		}

		if (check_target && PageBuddy(page)) {
			clear_pageblock_skip(page);
			return true;
		}

		page += (1 << PAGE_ALLOC_COSTLY_ORDER);
	} while (page <= end_page);

	return false;
}

/*
 * This function is called to clear all cached information on pageblocks that
 * should be skipped for page isolation when the migrate and free page scanner
 * meet.
 */
static void __reset_isolation_suitable(struct zone *zone)
{
	unsigned long migrate_pfn = zone->zone_start_pfn;
	unsigned long free_pfn = zone_end_pfn(zone) - 1;
	unsigned long reset_migrate = free_pfn;
	unsigned long reset_free = migrate_pfn;
	bool source_set = false;
	bool free_set = false;

	/* Only flush if a full compaction finished recently */
	if (!zone->compact_blockskip_flush)
		return;

	zone->compact_blockskip_flush = false;

	/*
	 * Walk the zone and update pageblock skip information. Source looks
	 * for PageLRU while target looks for PageBuddy. When the scanner
	 * is found, both PageBuddy and PageLRU are checked as the pageblock
	 * is suitable as both source and target.
	 */
	for (; migrate_pfn < free_pfn; migrate_pfn += pageblock_nr_pages,
					free_pfn -= pageblock_nr_pages) {
		cond_resched();

		/* Update the migrate PFN */
		if (__reset_isolation_pfn(zone, migrate_pfn, true, source_set) &&
		    migrate_pfn < reset_migrate) {
			source_set = true;
			reset_migrate = migrate_pfn;
			zone->compact_init_migrate_pfn = reset_migrate;
			zone->compact_cached_migrate_pfn[0] = reset_migrate;
			zone->compact_cached_migrate_pfn[1] = reset_migrate;
		}

		/* Update the free PFN */
		if (__reset_isolation_pfn(zone, free_pfn, free_set, true) &&
		    free_pfn > reset_free) {
			free_set = true;
			reset_free = free_pfn;
			zone->compact_init_free_pfn = reset_free;
			zone->compact_cached_free_pfn = reset_free;
		}
	}

	/* Leave no distance if no suitable block was reset */
	if (reset_migrate >= reset_free) {
		zone->compact_cached_migrate_pfn[0] = migrate_pfn;
		zone->compact_cached_migrate_pfn[1] = migrate_pfn;
		zone->compact_cached_free_pfn = free_pfn;
	}
}

void reset_isolation_suitable(pg_data_t *pgdat)
{
	int zoneid;

	for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) {
		struct zone *zone = &pgdat->node_zones[zoneid];
		if (!populated_zone(zone))
			continue;

		__reset_isolation_suitable(zone);
	}
}

/*
 * Sets the pageblock skip bit if it was clear. Note that this is a hint as
 * locks are not required for read/writers. Returns true if it was already set.
 */
static bool test_and_set_skip(struct compact_control *cc, struct page *page)
{
	bool skip;

	/* Do not update if skip hint is being ignored */
	if (cc->ignore_skip_hint)
		return false;

	skip = get_pageblock_skip(page);
	if (!skip && !cc->no_set_skip_hint)
		set_pageblock_skip(page);

	return skip;
}

static void update_cached_migrate(struct compact_control *cc, unsigned long pfn)
{
	struct zone *zone = cc->zone;

	/* Set for isolation rather than compaction */
	if (cc->no_set_skip_hint)
		return;

	pfn = pageblock_end_pfn(pfn);

	/* Update where async and sync compaction should restart */
	if (pfn > zone->compact_cached_migrate_pfn[0])
		zone->compact_cached_migrate_pfn[0] = pfn;
	if (cc->mode != MIGRATE_ASYNC &&
	    pfn > zone->compact_cached_migrate_pfn[1])
		zone->compact_cached_migrate_pfn[1] = pfn;
}

/*
 * If no pages were isolated then mark this pageblock to be skipped in the
 * future. The information is later cleared by __reset_isolation_suitable().
 */
static void update_pageblock_skip(struct compact_control *cc,
			struct page *page, unsigned long pfn)
{
	struct zone *zone = cc->zone;

	if (cc->no_set_skip_hint)
		return;

	set_pageblock_skip(page);

	if (pfn < zone->compact_cached_free_pfn)
		zone->compact_cached_free_pfn = pfn;
}
#else
static inline bool isolation_suitable(struct compact_control *cc,
					struct page *page)
{
	return true;
}

static inline bool pageblock_skip_persistent(struct page *page)
{
	return false;
}

static inline void update_pageblock_skip(struct compact_control *cc,
			struct page *page, unsigned long pfn)
{
}

static void update_cached_migrate(struct compact_control *cc, unsigned long pfn)
{
}

static bool test_and_set_skip(struct compact_control *cc, struct page *page)
{
	return false;
}
#endif /* CONFIG_COMPACTION */

/*
 * Compaction requires the taking of some coarse locks that are potentially
 * very heavily contended. For async compaction, trylock and record if the
 * lock is contended. The lock will still be acquired but compaction will
 * abort when the current block is finished regardless of success rate.
 * Sync compaction acquires the lock.
 *
 * Always returns true which makes it easier to track lock state in callers.
 */
static bool compact_lock_irqsave(spinlock_t *lock, unsigned long *flags,
						struct compact_control *cc)
	__acquires(lock)
{
	/* Track if the lock is contended in async mode */
	if (cc->mode == MIGRATE_ASYNC && !cc->contended) {
		if (spin_trylock_irqsave(lock, *flags))
			return true;

		cc->contended = true;
	}

	spin_lock_irqsave(lock, *flags);
	return true;
}

/*
 * Compaction requires the taking of some coarse locks that are potentially
 * very heavily contended. The lock should be periodically unlocked to avoid
 * having disabled IRQs for a long time, even when there is nobody waiting on
 * the lock. It might also be that allowing the IRQs will result in
 * need_resched() becoming true. If scheduling is needed, compaction schedules.
 * Either compaction type will also abort if a fatal signal is pending.
 * In either case if the lock was locked, it is dropped and not regained.
 *
 * Returns true if compaction should abort due to fatal signal pending.
 * Returns false when compaction can continue.
 */
static bool compact_unlock_should_abort(spinlock_t *lock,
		unsigned long flags, bool *locked, struct compact_control *cc)
{
	if (*locked) {
		spin_unlock_irqrestore(lock, flags);
		*locked = false;
	}

	if (fatal_signal_pending(current)) {
		cc->contended = true;
		return true;
	}

	cond_resched();

	return false;
}

/*
 * Isolate free pages onto a private freelist. If @strict is true, will abort
 * returning 0 on any invalid PFNs or non-free pages inside of the pageblock
 * (even though it may still end up isolating some pages).
 */
static unsigned long isolate_freepages_block(struct compact_control *cc,
				unsigned long *start_pfn,
				unsigned long end_pfn,
				struct list_head *freelist,
				unsigned int stride,
				bool strict)
{
	int nr_scanned = 0, total_isolated = 0;
	struct page *page;
	unsigned long flags = 0;
	bool locked = false;
	unsigned long blockpfn = *start_pfn;
	unsigned int order;

	/* Strict mode is for isolation, speed is secondary */
	if (strict)
		stride = 1;

	page = pfn_to_page(blockpfn);

	/* Isolate free pages. */
	for (; blockpfn < end_pfn; blockpfn += stride, page += stride) {
		int isolated;

		/*
		 * Periodically drop the lock (if held) regardless of its
		 * contention, to give chance to IRQs. Abort if fatal signal
		 * pending.
		 */
		if (!(blockpfn % COMPACT_CLUSTER_MAX)
		    && compact_unlock_should_abort(&cc->zone->lock, flags,
								&locked, cc))
			break;

		nr_scanned++;

		/*
		 * For compound pages such as THP and hugetlbfs, we can save
		 * potentially a lot of iterations if we skip them at once.
		 * The check is racy, but we can consider only valid values
		 * and the only danger is skipping too much.
		 */
		if (PageCompound(page)) {
			const unsigned int order = compound_order(page);

			if ((order <= MAX_PAGE_ORDER) &&
			    (blockpfn + (1UL << order) <= end_pfn)) {
				blockpfn += (1UL << order) - 1;
				page += (1UL << order) - 1;
				nr_scanned += (1UL << order) - 1;
			}

			goto isolate_fail;
		}

		if (!PageBuddy(page))
			goto isolate_fail;

		/* If we already hold the lock, we can skip some rechecking. */
		if (!locked) {
			locked = compact_lock_irqsave(&cc->zone->lock,
								&flags, cc);

			/* Recheck this is a buddy page under lock */
			if (!PageBuddy(page))
				goto isolate_fail;
		}

		/* Found a free page, will break it into order-0 pages */
		order = buddy_order(page);
		isolated = __isolate_free_page(page, order);
		if (!isolated)
			break;
		set_page_private(page, order);

		nr_scanned += isolated - 1;
		total_isolated += isolated;
		cc->nr_freepages += isolated;
		list_add_tail(&page->lru, &freelist[order]);

		if (!strict && cc->nr_migratepages <= cc->nr_freepages) {
			blockpfn += isolated;
			break;
		}
		/* Advance to the end of split page */
		blockpfn += isolated - 1;
		page += isolated - 1;
		continue;

isolate_fail:
		if (strict)
			break;

	}

	if (locked)
		spin_unlock_irqrestore(&cc->zone->lock, flags);

	/*
	 * Be careful to not go outside of the pageblock.
	 */
	if (unlikely(blockpfn > end_pfn))
		blockpfn = end_pfn;

	trace_mm_compaction_isolate_freepages(*start_pfn, blockpfn,
					nr_scanned, total_isolated);

	/* Record how far we have got within the block */
	*start_pfn = blockpfn;

	/*
	 * If strict isolation is requested by CMA then check that all the
	 * pages requested were isolated. If there were any failures, 0 is
	 * returned and CMA will fail.
	 */
	if (strict && blockpfn < end_pfn)
		total_isolated = 0;

	cc->total_free_scanned += nr_scanned;
	if (total_isolated)
		count_compact_events(COMPACTISOLATED, total_isolated);
	return total_isolated;
}

/**
 * isolate_freepages_range() - isolate free pages.
 * @cc:        Compaction control structure.
 * @start_pfn: The first PFN to start isolating.
 * @end_pfn:   The one-past-last PFN.
 *
 * Non-free pages, invalid PFNs, or zone boundaries within the
 * [start_pfn, end_pfn) range are considered errors, cause function to
 * undo its actions and return zero. cc->freepages[] are empty.
 *
 * Otherwise, function returns one-past-the-last PFN of isolated page
 * (which may be greater then end_pfn if end fell in a middle of
 * a free page). cc->freepages[] contain free pages isolated.
 */
unsigned long
isolate_freepages_range(struct compact_control *cc,
			unsigned long start_pfn, unsigned long end_pfn)
{
	unsigned long isolated, pfn, block_start_pfn, block_end_pfn;
	int order;

	for (order = 0; order < NR_PAGE_ORDERS; order++)
		INIT_LIST_HEAD(&cc->freepages[order]);

	pfn = start_pfn;
	block_start_pfn = pageblock_start_pfn(pfn);
	if (block_start_pfn < cc->zone->zone_start_pfn)
		block_start_pfn = cc->zone->zone_start_pfn;
	block_end_pfn = pageblock_end_pfn(pfn);

	for (; pfn < end_pfn; pfn += isolated,
				block_start_pfn = block_end_pfn,
				block_end_pfn += pageblock_nr_pages) {
		/* Protect pfn from changing by isolate_freepages_block */
		unsigned long isolate_start_pfn = pfn;

		/*
		 * pfn could pass the block_end_pfn if isolated freepage
		 * is more than pageblock order. In this case, we adjust
		 * scanning range to right one.
		 */
		if (pfn >= block_end_pfn) {
			block_start_pfn = pageblock_start_pfn(pfn);
			block_end_pfn = pageblock_end_pfn(pfn);
		}

		block_end_pfn = min(block_end_pfn, end_pfn);

		if (!pageblock_pfn_to_page(block_start_pfn,
					block_end_pfn, cc->zone))
			break;

		isolated = isolate_freepages_block(cc, &isolate_start_pfn,
					block_end_pfn, cc->freepages, 0, true);

		/*
		 * In strict mode, isolate_freepages_block() returns 0 if
		 * there are any holes in the block (ie. invalid PFNs or
		 * non-free pages).
		 */
		if (!isolated)
			break;

		/*
		 * If we managed to isolate pages, it is always (1 << n) *
		 * pageblock_nr_pages for some non-negative n.  (Max order
		 * page may span two pageblocks).
		 */
	}

	if (pfn < end_pfn) {
		/* Loop terminated early, cleanup. */
		release_free_list(cc->freepages);
		return 0;
	}

	/* We don't use freelists for anything. */
	return pfn;
}

/* Similar to reclaim, but different enough that they don't share logic */
static bool too_many_isolated(struct compact_control *cc)
{
	pg_data_t *pgdat = cc->zone->zone_pgdat;
	bool too_many;

	unsigned long active, inactive, isolated;

	inactive = node_page_state(pgdat, NR_INACTIVE_FILE) +
			node_page_state(pgdat, NR_INACTIVE_ANON);
	active = node_page_state(pgdat, NR_ACTIVE_FILE) +
			node_page_state(pgdat, NR_ACTIVE_ANON);
	isolated = node_page_state(pgdat, NR_ISOLATED_FILE) +
			node_page_state(pgdat, NR_ISOLATED_ANON);

	/*
	 * Allow GFP_NOFS to isolate past the limit set for regular
	 * compaction runs. This prevents an ABBA deadlock when other
	 * compactors have already isolated to the limit, but are
	 * blocked on filesystem locks held by the GFP_NOFS thread.
	 */
	if (cc->gfp_mask & __GFP_FS) {
		inactive >>= 3;
		active >>= 3;
	}

	too_many = isolated > (inactive + active) / 2;
	if (!too_many)
		wake_throttle_isolated(pgdat);

	return too_many;
}

/**
 * skip_isolation_on_order() - determine when to skip folio isolation based on
 *			       folio order and compaction target order
 * @order:		to-be-isolated folio order
 * @target_order:	compaction target order
 *
 * This avoids unnecessary folio isolations during compaction.
 */
static bool skip_isolation_on_order(int order, int target_order)
{
	/*
	 * Unless we are performing global compaction (i.e.,
	 * is_via_compact_memory), skip any folios that are larger than the
	 * target order: we wouldn't be here if we'd have a free folio with
	 * the desired target_order, so migrating this folio would likely fail
	 * later.
	 */
	if (!is_via_compact_memory(target_order) && order >= target_order)
		return true;
	/*
	 * We limit memory compaction to pageblocks and won't try
	 * creating free blocks of memory that are larger than that.
	 */
	return order >= pageblock_order;
}

/**
 * isolate_migratepages_block() - isolate all migrate-able pages within
 *				  a single pageblock
 * @cc:		Compaction control structure.
 * @low_pfn:	The first PFN to isolate
 * @end_pfn:	The one-past-the-last PFN to isolate, within same pageblock
 * @mode:	Isolation mode to be used.
 *
 * Isolate all pages that can be migrated from the range specified by
 * [low_pfn, end_pfn). The range is expected to be within same pageblock.
 * Returns errno, like -EAGAIN or -EINTR in case e.g signal pending or congestion,
 * -ENOMEM in case we could not allocate a page, or 0.
 * cc->migrate_pfn will contain the next pfn to scan.
 *
 * The pages are isolated on cc->migratepages list (not required to be empty),
 * and cc->nr_migratepages is updated accordingly.
 */
static int
isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
			unsigned long end_pfn, isolate_mode_t mode)
{
	pg_data_t *pgdat = cc->zone->zone_pgdat;
	unsigned long nr_scanned = 0, nr_isolated = 0;
	struct lruvec *lruvec;
	unsigned long flags = 0;
	struct lruvec *locked = NULL;
	struct folio *folio = NULL;
	struct page *page = NULL, *valid_page = NULL;
	struct address_space *mapping;
	unsigned long start_pfn = low_pfn;
	bool skip_on_failure = false;
	unsigned long next_skip_pfn = 0;
	bool skip_updated = false;
	int ret = 0;

	cc->migrate_pfn = low_pfn;

	/*
	 * Ensure that there are not too many pages isolated from the LRU
	 * list by either parallel reclaimers or compaction. If there are,
	 * delay for some time until fewer pages are isolated
	 */
	while (unlikely(too_many_isolated(cc))) {
		/* stop isolation if there are still pages not migrated */
		if (cc->nr_migratepages)
			return -EAGAIN;

		/* async migration should just abort */
		if (cc->mode == MIGRATE_ASYNC)
			return -EAGAIN;

		reclaim_throttle(pgdat, VMSCAN_THROTTLE_ISOLATED);

		if (fatal_signal_pending(current))
			return -EINTR;
	}

	cond_resched();

	if (cc->direct_compaction && (cc->mode == MIGRATE_ASYNC)) {
		skip_on_failure = true;
		next_skip_pfn = block_end_pfn(low_pfn, cc->order);
	}

	/* Time to isolate some pages for migration */
	for (; low_pfn < end_pfn; low_pfn++) {
		bool is_dirty, is_unevictable;

		if (skip_on_failure && low_pfn >= next_skip_pfn) {
			/*
			 * We have isolated all migration candidates in the
			 * previous order-aligned block, and did not skip it due
			 * to failure. We should migrate the pages now and
			 * hopefully succeed compaction.
			 */
			if (nr_isolated)
				break;

			/*
			 * We failed to isolate in the previous order-aligned
			 * block. Set the new boundary to the end of the
			 * current block. Note we can't simply increase
			 * next_skip_pfn by 1 << order, as low_pfn might have
			 * been incremented by a higher number due to skipping
			 * a compound or a high-order buddy page in the
			 * previous loop iteration.
			 */
			next_skip_pfn = block_end_pfn(low_pfn, cc->order);
		}

		/*
		 * Periodically drop the lock (if held) regardless of its
		 * contention, to give chance to IRQs. Abort completely if
		 * a fatal signal is pending.
		 */
		if (!(low_pfn % COMPACT_CLUSTER_MAX)) {
			if (locked) {
				unlock_page_lruvec_irqrestore(locked, flags);
				locked = NULL;
			}

			if (fatal_signal_pending(current)) {
				cc->contended = true;
				ret = -EINTR;

				goto fatal_pending;
			}

			cond_resched();
		}

		nr_scanned++;

		page = pfn_to_page(low_pfn);

		/*
		 * Check if the pageblock has already been marked skipped.
		 * Only the first PFN is checked as the caller isolates
		 * COMPACT_CLUSTER_MAX at a time so the second call must
		 * not falsely conclude that the block should be skipped.
		 */
		if (!valid_page && (pageblock_aligned(low_pfn) ||
				    low_pfn == cc->zone->zone_start_pfn)) {
			if (!isolation_suitable(cc, page)) {
				low_pfn = end_pfn;
				folio = NULL;
				goto isolate_abort;
			}
			valid_page = page;
		}

		if (PageHuge(page)) {
			const unsigned int order = compound_order(page);
			/*
			 * skip hugetlbfs if we are not compacting for pages
			 * bigger than its order. THPs and other compound pages
			 * are handled below.
			 */
			if (!cc->alloc_contig) {

				if (order <= MAX_PAGE_ORDER) {
					low_pfn += (1UL << order) - 1;
					nr_scanned += (1UL << order) - 1;
				}
				goto isolate_fail;
			}
			/* for alloc_contig case */
			if (locked) {
				unlock_page_lruvec_irqrestore(locked, flags);
				locked = NULL;
			}

			ret = isolate_or_dissolve_huge_page(page, &cc->migratepages);

			/*
			 * Fail isolation in case isolate_or_dissolve_huge_page()
			 * reports an error. In case of -ENOMEM, abort right away.
			 */
			if (ret < 0) {
				 /* Do not report -EBUSY down the chain */
				if (ret == -EBUSY)
					ret = 0;
				low_pfn += (1UL << order) - 1;
				nr_scanned += (1UL << order) - 1;
				goto isolate_fail;
			}

			if (PageHuge(page)) {
				/*
				 * Hugepage was successfully isolated and placed
				 * on the cc->migratepages list.
				 */
				folio = page_folio(page);
				low_pfn += folio_nr_pages(folio) - 1;
				goto isolate_success_no_list;
			}

			/*
			 * Ok, the hugepage was dissolved. Now these pages are
			 * Buddy and cannot be re-allocated because they are
			 * isolated. Fall-through as the check below handles
			 * Buddy pages.
			 */
		}

		/*
		 * Skip if free. We read page order here without zone lock
		 * which is generally unsafe, but the race window is small and
		 * the worst thing that can happen is that we skip some
		 * potential isolation targets.
		 */
		if (PageBuddy(page)) {
			unsigned long freepage_order = buddy_order_unsafe(page);

			/*
			 * Without lock, we cannot be sure that what we got is
			 * a valid page order. Consider only values in the
			 * valid order range to prevent low_pfn overflow.
			 */
			if (freepage_order > 0 && freepage_order <= MAX_PAGE_ORDER) {
				low_pfn += (1UL << freepage_order) - 1;
				nr_scanned += (1UL << freepage_order) - 1;
			}
			continue;
		}

		/*
		 * Regardless of being on LRU, compound pages such as THP
		 * (hugetlbfs is handled above) are not to be compacted unless
		 * we are attempting an allocation larger than the compound
		 * page size. We can potentially save a lot of iterations if we
		 * skip them at once. The check is racy, but we can consider
		 * only valid values and the only danger is skipping too much.
		 */
		if (PageCompound(page) && !cc->alloc_contig) {
			const unsigned int order = compound_order(page);

			/* Skip based on page order and compaction target order. */
			if (skip_isolation_on_order(order, cc->order)) {
				if (order <= MAX_PAGE_ORDER) {
					low_pfn += (1UL << order) - 1;
					nr_scanned += (1UL << order) - 1;
				}
				goto isolate_fail;
			}
		}

		/*
		 * Check may be lockless but that's ok as we recheck later.
		 * It's possible to migrate LRU and non-lru movable pages.
		 * Skip any other type of page
		 */
		if (!PageLRU(page)) {
			/*
			 * __PageMovable can return false positive so we need
			 * to verify it under page_lock.
			 */
			if (unlikely(__PageMovable(page)) &&
					!PageIsolated(page)) {
				if (locked) {
					unlock_page_lruvec_irqrestore(locked, flags);
					locked = NULL;
				}

				if (isolate_movable_page(page, mode)) {
					folio = page_folio(page);
					goto isolate_success;
				}
			}

			goto isolate_fail;
		}

		/*
		 * Be careful not to clear PageLRU until after we're
		 * sure the page is not being freed elsewhere -- the
		 * page release code relies on it.
		 */
		folio = folio_get_nontail_page(page);
		if (unlikely(!folio))
			goto isolate_fail;

		/*
		 * Migration will fail if an anonymous page is pinned in memory,
		 * so avoid taking lru_lock and isolating it unnecessarily in an
		 * admittedly racy check.
		 */
		mapping = folio_mapping(folio);
		if (!mapping && (folio_ref_count(folio) - 1) > folio_mapcount(folio))
			goto isolate_fail_put;

		/*
		 * Only allow to migrate anonymous pages in GFP_NOFS context
		 * because those do not depend on fs locks.
		 */
		if (!(cc->gfp_mask & __GFP_FS) && mapping)
			goto isolate_fail_put;

		/* Only take pages on LRU: a check now makes later tests safe */
		if (!folio_test_lru(folio))
			goto isolate_fail_put;

		is_unevictable = folio_test_unevictable(folio);

		/* Compaction might skip unevictable pages but CMA takes them */
		if (!(mode & ISOLATE_UNEVICTABLE) && is_unevictable)
			goto isolate_fail_put;

		/*
		 * To minimise LRU disruption, the caller can indicate with
		 * ISOLATE_ASYNC_MIGRATE that it only wants to isolate pages
		 * it will be able to migrate without blocking - clean pages
		 * for the most part.  PageWriteback would require blocking.
		 */
		if ((mode & ISOLATE_ASYNC_MIGRATE) && folio_test_writeback(folio))
			goto isolate_fail_put;

		is_dirty = folio_test_dirty(folio);

		if (((mode & ISOLATE_ASYNC_MIGRATE) && is_dirty) ||
		    (mapping && is_unevictable)) {
			bool migrate_dirty = true;
			bool is_inaccessible;

			/*
			 * Only folios without mappings or that have
			 * a ->migrate_folio callback are possible to migrate
			 * without blocking.
			 *
			 * Folios from inaccessible mappings are not migratable.
			 *
			 * However, we can be racing with truncation, which can
			 * free the mapping that we need to check. Truncation
			 * holds the folio lock until after the folio is removed
			 * from the page so holding it ourselves is sufficient.
			 *
			 * To avoid locking the folio just to check inaccessible,
			 * assume every inaccessible folio is also unevictable,
			 * which is a cheaper test.  If our assumption goes
			 * wrong, it's not a correctness bug, just potentially
			 * wasted cycles.
			 */
			if (!folio_trylock(folio))
				goto isolate_fail_put;

			mapping = folio_mapping(folio);
			if ((mode & ISOLATE_ASYNC_MIGRATE) && is_dirty) {
				migrate_dirty = !mapping ||
						mapping->a_ops->migrate_folio;
			}
			is_inaccessible = mapping && mapping_inaccessible(mapping);
			folio_unlock(folio);
			if (!migrate_dirty || is_inaccessible)
				goto isolate_fail_put;
		}

		/* Try isolate the folio */
		if (!folio_test_clear_lru(folio))
			goto isolate_fail_put;

		lruvec = folio_lruvec(folio);

		/* If we already hold the lock, we can skip some rechecking */
		if (lruvec != locked) {
			if (locked)
				unlock_page_lruvec_irqrestore(locked, flags);

			compact_lock_irqsave(&lruvec->lru_lock, &flags, cc);
			locked = lruvec;

			lruvec_memcg_debug(lruvec, folio);

			/*
			 * Try get exclusive access under lock. If marked for
			 * skip, the scan is aborted unless the current context
			 * is a rescan to reach the end of the pageblock.
			 */
			if (!skip_updated && valid_page) {
				skip_updated = true;
				if (test_and_set_skip(cc, valid_page) &&
				    !cc->finish_pageblock) {
					low_pfn = end_pfn;
					goto isolate_abort;
				}
			}

			/*
			 * Check LRU folio order under the lock
			 */
			if (unlikely(skip_isolation_on_order(folio_order(folio),
							     cc->order) &&
				     !cc->alloc_contig)) {
				low_pfn += folio_nr_pages(folio) - 1;
				nr_scanned += folio_nr_pages(folio) - 1;
				folio_set_lru(folio);
				goto isolate_fail_put;
			}
		}

		/* The folio is taken off the LRU */
		if (folio_test_large(folio))
			low_pfn += folio_nr_pages(folio) - 1;

		/* Successfully isolated */
		lruvec_del_folio(lruvec, folio);
		node_stat_mod_folio(folio,
				NR_ISOLATED_ANON + folio_is_file_lru(folio),
				folio_nr_pages(folio));

isolate_success:
		list_add(&folio->lru, &cc->migratepages);
isolate_success_no_list:
		cc->nr_migratepages += folio_nr_pages(folio);
		nr_isolated += folio_nr_pages(folio);
		nr_scanned += folio_nr_pages(folio) - 1;

		/*
		 * Avoid isolating too much unless this block is being
		 * fully scanned (e.g. dirty/writeback pages, parallel allocation)
		 * or a lock is contended. For contention, isolate quickly to
		 * potentially remove one source of contention.
		 */
		if (cc->nr_migratepages >= COMPACT_CLUSTER_MAX &&
		    !cc->finish_pageblock && !cc->contended) {
			++low_pfn;
			break;
		}

		continue;

isolate_fail_put:
		/* Avoid potential deadlock in freeing page under lru_lock */
		if (locked) {
			unlock_page_lruvec_irqrestore(locked, flags);
			locked = NULL;
		}
		folio_put(folio);

isolate_fail:
		if (!skip_on_failure && ret != -ENOMEM)
			continue;

		/*
		 * We have isolated some pages, but then failed. Release them
		 * instead of migrating, as we cannot form the cc->order buddy
		 * page anyway.
		 */
		if (nr_isolated) {
			if (locked) {
				unlock_page_lruvec_irqrestore(locked, flags);
				locked = NULL;
			}
			putback_movable_pages(&cc->migratepages);
			cc->nr_migratepages = 0;
			nr_isolated = 0;
		}

		if (low_pfn < next_skip_pfn) {
			low_pfn = next_skip_pfn - 1;
			/*
			 * The check near the loop beginning would have updated
			 * next_skip_pfn too, but this is a bit simpler.
			 */
			next_skip_pfn += 1UL << cc->order;
		}

		if (ret == -ENOMEM)
			break;
	}

	/*
	 * The PageBuddy() check could have potentially brought us outside
	 * the range to be scanned.
	 */
	if (unlikely(low_pfn > end_pfn))
		low_pfn = end_pfn;

	folio = NULL;

isolate_abort:
	if (locked)
		unlock_page_lruvec_irqrestore(locked, flags);
	if (folio) {
		folio_set_lru(folio);
		folio_put(folio);
	}

	/*
	 * Update the cached scanner pfn once the pageblock has been scanned.
	 * Pages will either be migrated in which case there is no point
	 * scanning in the near future or migration failed in which case the
	 * failure reason may persist. The block is marked for skipping if
	 * there were no pages isolated in the block or if the block is
	 * rescanned twice in a row.
	 */
	if (low_pfn == end_pfn && (!nr_isolated || cc->finish_pageblock)) {
		if (!cc->no_set_skip_hint && valid_page && !skip_updated)
			set_pageblock_skip(valid_page);
		update_cached_migrate(cc, low_pfn);
	}

	trace_mm_compaction_isolate_migratepages(start_pfn, low_pfn,
						nr_scanned, nr_isolated);

fatal_pending:
	cc->total_migrate_scanned += nr_scanned;
	if (nr_isolated)
		count_compact_events(COMPACTISOLATED, nr_isolated);

	cc->migrate_pfn = low_pfn;

	return ret;
}

/**
 * isolate_migratepages_range() - isolate migrate-able pages in a PFN range
 * @cc:        Compaction control structure.
 * @start_pfn: The first PFN to start isolating.
 * @end_pfn:   The one-past-last PFN.
 *
 * Returns -EAGAIN when contented, -EINTR in case of a signal pending, -ENOMEM
 * in case we could not allocate a page, or 0.
 */
int
isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn,
							unsigned long end_pfn)
{
	unsigned long pfn, block_start_pfn, block_end_pfn;
	int ret = 0;

	/* Scan block by block. First and last block may be incomplete */
	pfn = start_pfn;
	block_start_pfn = pageblock_start_pfn(pfn);
	if (block_start_pfn < cc->zone->zone_start_pfn)
		block_start_pfn = cc->zone->zone_start_pfn;
	block_end_pfn = pageblock_end_pfn(pfn);

	for (; pfn < end_pfn; pfn = block_end_pfn,
				block_start_pfn = block_end_pfn,
				block_end_pfn += pageblock_nr_pages) {

		block_end_pfn = min(block_end_pfn, end_pfn);

		if (!pageblock_pfn_to_page(block_start_pfn,
					block_end_pfn, cc->zone))
			continue;

		ret = isolate_migratepages_block(cc, pfn, block_end_pfn,
						 ISOLATE_UNEVICTABLE);

		if (ret)
			break;

		if (cc->nr_migratepages >= COMPACT_CLUSTER_MAX)
			break;
	}

	return ret;
}

#endif /* CONFIG_COMPACTION || CONFIG_CMA */
#ifdef CONFIG_COMPACTION

static bool suitable_migration_source(struct compact_control *cc,
							struct page *page)
{
	int block_mt;

	if (pageblock_skip_persistent(page))
		return false;

	if ((cc->mode != MIGRATE_ASYNC) || !cc->direct_compaction)
		return true;

	block_mt = get_pageblock_migratetype(page);

	if (cc->migratetype == MIGRATE_MOVABLE)
		return is_migrate_movable(block_mt);
	else
		return block_mt == cc->migratetype;
}

/* Returns true if the page is within a block suitable for migration to */
static bool suitable_migration_target(struct compact_control *cc,
							struct page *page)
{
	/* If the page is a large free page, then disallow migration */
	if (PageBuddy(page)) {
		int order = cc->order > 0 ? cc->order : pageblock_order;

		/*
		 * We are checking page_order without zone->lock taken. But
		 * the only small danger is that we skip a potentially suitable
		 * pageblock, so it's not worth to check order for valid range.
		 */
		if (buddy_order_unsafe(page) >= order)
			return false;
	}

	if (cc->ignore_block_suitable)
		return true;

	/* If the block is MIGRATE_MOVABLE or MIGRATE_CMA, allow migration */
	if (is_migrate_movable(get_pageblock_migratetype(page)))
		return true;

	/* Otherwise skip the block */
	return false;
}

static inline unsigned int
freelist_scan_limit(struct compact_control *cc)
{
	unsigned short shift = BITS_PER_LONG - 1;

	return (COMPACT_CLUSTER_MAX >> min(shift, cc->fast_search_fail)) + 1;
}

/*
 * Test whether the free scanner has reached the same or lower pageblock than
 * the migration scanner, and compaction should thus terminate.
 */
static inline bool compact_scanners_met(struct compact_control *cc)
{
	return (cc->free_pfn >> pageblock_order)
		<= (cc->migrate_pfn >> pageblock_order);
}

/*
 * Used when scanning for a suitable migration target which scans freelists
 * in reverse. Reorders the list such as the unscanned pages are scanned
 * first on the next iteration of the free scanner
 */
static void
move_freelist_head(struct list_head *freelist, struct page *freepage)
{
	LIST_HEAD(sublist);

	if (!list_is_first(&freepage->buddy_list, freelist)) {
		list_cut_before(&sublist, freelist, &freepage->buddy_list);
		list_splice_tail(&sublist, freelist);
	}
}

/*
 * Similar to move_freelist_head except used by the migration scanner
 * when scanning forward. It's possible for these list operations to
 * move against each other if they search the free list exactly in
 * lockstep.
 */
static void
move_freelist_tail(struct list_head *freelist, struct page *freepage)
{
	LIST_HEAD(sublist);

	if (!list_is_last(&freepage->buddy_list, freelist)) {
		list_cut_position(&sublist, freelist, &freepage->buddy_list);
		list_splice_tail(&sublist, freelist);
	}
}

static void
fast_isolate_around(struct compact_control *cc, unsigned long pfn)
{
	unsigned long start_pfn, end_pfn;
	struct page *page;

	/* Do not search around if there are enough pages already */
	if (cc->nr_freepages >= cc->nr_migratepages)
		return;

	/* Minimise scanning during async compaction */
	if (cc->direct_compaction && cc->mode == MIGRATE_ASYNC)
		return;

	/* Pageblock boundaries */
	start_pfn = max(pageblock_start_pfn(pfn), cc->zone->zone_start_pfn);
	end_pfn = min(pageblock_end_pfn(pfn), zone_end_pfn(cc->zone));

	page = pageblock_pfn_to_page(start_pfn, end_pfn, cc->zone);
	if (!page)
		return;

	isolate_freepages_block(cc, &start_pfn, end_pfn, cc->freepages, 1, false);

	/* Skip this pageblock in the future as it's full or nearly full */
	if (start_pfn == end_pfn && !cc->no_set_skip_hint)
		set_pageblock_skip(page);
}

/* Search orders in round-robin fashion */
static int next_search_order(struct compact_control *cc, int order)
{
	order--;
	if (order < 0)
		order = cc->order - 1;

	/* Search wrapped around? */
	if (order == cc->search_order) {
		cc->search_order--;
		if (cc->search_order < 0)
			cc->search_order = cc->order - 1;
		return -1;
	}

	return order;
}

static void fast_isolate_freepages(struct compact_control *cc)
{
	unsigned int limit = max(1U, freelist_scan_limit(cc) >> 1);
	unsigned int nr_scanned = 0, total_isolated = 0;
	unsigned long low_pfn, min_pfn, highest = 0;
	unsigned long nr_isolated = 0;
	unsigned long distance;
	struct page *page = NULL;
	bool scan_start = false;
	int order;

	/* Full compaction passes in a negative order */
	if (cc->order <= 0)
		return;

	/*
	 * If starting the scan, use a deeper search and use the highest
	 * PFN found if a suitable one is not found.
	 */
	if (cc->free_pfn >= cc->zone->compact_init_free_pfn) {
		limit = pageblock_nr_pages >> 1;
		scan_start = true;
	}

	/*
	 * Preferred point is in the top quarter of the scan space but take
	 * a pfn from the top half if the search is problematic.
	 */
	distance = (cc->free_pfn - cc->migrate_pfn);
	low_pfn = pageblock_start_pfn(cc->free_pfn - (distance >> 2));
	min_pfn = pageblock_start_pfn(cc->free_pfn - (distance >> 1));

	if (WARN_ON_ONCE(min_pfn > low_pfn))
		low_pfn = min_pfn;

	/*
	 * Search starts from the last successful isolation order or the next
	 * order to search after a previous failure
	 */
	cc->search_order = min_t(unsigned int, cc->order - 1, cc->search_order);

	for (order = cc->search_order;
	     !page && order >= 0;
	     order = next_search_order(cc, order)) {
		struct free_area *area = &cc->zone->free_area[order];
		struct list_head *freelist;
		struct page *freepage;
		unsigned long flags;
		unsigned int order_scanned = 0;
		unsigned long high_pfn = 0;

		if (!area->nr_free)
			continue;

		spin_lock_irqsave(&cc->zone->lock, flags);
		freelist = &area->free_list[MIGRATE_MOVABLE];
		list_for_each_entry_reverse(freepage, freelist, buddy_list) {
			unsigned long pfn;

			order_scanned++;
			nr_scanned++;
			pfn = page_to_pfn(freepage);

			if (pfn >= highest)
				highest = max(pageblock_start_pfn(pfn),
					      cc->zone->zone_start_pfn);

			if (pfn >= low_pfn) {
				cc->fast_search_fail = 0;
				cc->search_order = order;
				page = freepage;
				break;
			}

			if (pfn >= min_pfn && pfn > high_pfn) {
				high_pfn = pfn;

				/* Shorten the scan if a candidate is found */
				limit >>= 1;
			}

			if (order_scanned >= limit)
				break;
		}

		/* Use a maximum candidate pfn if a preferred one was not found */
		if (!page && high_pfn) {
			page = pfn_to_page(high_pfn);

			/* Update freepage for the list reorder below */
			freepage = page;
		}

		/* Reorder to so a future search skips recent pages */
		move_freelist_head(freelist, freepage);

		/* Isolate the page if available */
		if (page) {
			if (__isolate_free_page(page, order)) {
				set_page_private(page, order);
				nr_isolated = 1 << order;
				nr_scanned += nr_isolated - 1;
				total_isolated += nr_isolated;
				cc->nr_freepages += nr_isolated;
				list_add_tail(&page->lru, &cc->freepages[order]);
				count_compact_events(COMPACTISOLATED, nr_isolated);
			} else {
				/* If isolation fails, abort the search */
				order = cc->search_order + 1;
				page = NULL;
			}
		}

		spin_unlock_irqrestore(&cc->zone->lock, flags);

		/* Skip fast search if enough freepages isolated */
		if (cc->nr_freepages >= cc->nr_migratepages)
			break;

		/*
		 * Smaller scan on next order so the total scan is related
		 * to freelist_scan_limit.
		 */
		if (order_scanned >= limit)
			limit = max(1U, limit >> 1);
	}

	trace_mm_compaction_fast_isolate_freepages(min_pfn, cc->free_pfn,
						   nr_scanned, total_isolated);

	if (!page) {
		cc->fast_search_fail++;
		if (scan_start) {
			/*
			 * Use the highest PFN found above min. If one was
			 * not found, be pessimistic for direct compaction
			 * and use the min mark.
			 */
			if (highest >= min_pfn) {
				page = pfn_to_page(highest);
				cc->free_pfn = highest;
			} else {
				if (cc->direct_compaction && pfn_valid(min_pfn)) {
					page = pageblock_pfn_to_page(min_pfn,
						min(pageblock_end_pfn(min_pfn),
						    zone_end_pfn(cc->zone)),
						cc->zone);
					if (page && !suitable_migration_target(cc, page))
						page = NULL;

					cc->free_pfn = min_pfn;
				}
			}
		}
	}

	if (highest && highest >= cc->zone->compact_cached_free_pfn) {
		highest -= pageblock_nr_pages;
		cc->zone->compact_cached_free_pfn = highest;
	}

	cc->total_free_scanned += nr_scanned;
	if (!page)
		return;

	low_pfn = page_to_pfn(page);
	fast_isolate_around(cc, low_pfn);
}

/*
 * Based on information in the current compact_control, find blocks
 * suitable for isolating free pages from and then isolate them.
 */
static void isolate_freepages(struct compact_control *cc)
{
	struct zone *zone = cc->zone;
	struct page *page;
	unsigned long block_start_pfn;	/* start of current pageblock */
	unsigned long isolate_start_pfn; /* exact pfn we start at */
	unsigned long block_end_pfn;	/* end of current pageblock */
	unsigned long low_pfn;	     /* lowest pfn scanner is able to scan */
	unsigned int stride;

	/* Try a small search of the free lists for a candidate */
	fast_isolate_freepages(cc);
	if (cc->nr_freepages)
		return;

	/*
	 * Initialise the free scanner. The starting point is where we last
	 * successfully isolated from, zone-cached value, or the end of the
	 * zone when isolating for the first time. For looping we also need
	 * this pfn aligned down to the pageblock boundary, because we do
	 * block_start_pfn -= pageblock_nr_pages in the for loop.
	 * For ending point, take care when isolating in last pageblock of a
	 * zone which ends in the middle of a pageblock.
	 * The low boundary is the end of the pageblock the migration scanner
	 * is using.
	 */
	isolate_start_pfn = cc->free_pfn;
	block_start_pfn = pageblock_start_pfn(isolate_start_pfn);
	block_end_pfn = min(block_start_pfn + pageblock_nr_pages,
						zone_end_pfn(zone));
	low_pfn = pageblock_end_pfn(cc->migrate_pfn);
	stride = cc->mode == MIGRATE_ASYNC ? COMPACT_CLUSTER_MAX : 1;

	/*
	 * Isolate free pages until enough are available to migrate the
	 * pages on cc->migratepages. We stop searching if the migrate
	 * and free page scanners meet or enough free pages are isolated.
	 */
	for (; block_start_pfn >= low_pfn;
				block_end_pfn = block_start_pfn,
				block_start_pfn -= pageblock_nr_pages,
				isolate_start_pfn = block_start_pfn) {
		unsigned long nr_isolated;

		/*
		 * This can iterate a massively long zone without finding any
		 * suitable migration targets, so periodically check resched.
		 */
		if (!(block_start_pfn % (COMPACT_CLUSTER_MAX * pageblock_nr_pages)))
			cond_resched();

		page = pageblock_pfn_to_page(block_start_pfn, block_end_pfn,
									zone);
		if (!page) {
			unsigned long next_pfn;

			next_pfn = skip_offline_sections_reverse(block_start_pfn);
			if (next_pfn)
				block_start_pfn = max(next_pfn, low_pfn);

			continue;
		}

		/* Check the block is suitable for migration */
		if (!suitable_migration_target(cc, page))
			continue;

		/* If isolation recently failed, do not retry */
		if (!isolation_suitable(cc, page))
			continue;

		/* Found a block suitable for isolating free pages from. */
		nr_isolated = isolate_freepages_block(cc, &isolate_start_pfn,
					block_end_pfn, cc->freepages, stride, false);

		/* Update the skip hint if the full pageblock was scanned */
		if (isolate_start_pfn == block_end_pfn)
			update_pageblock_skip(cc, page, block_start_pfn -
					      pageblock_nr_pages);

		/* Are enough freepages isolated? */
		if (cc->nr_freepages >= cc->nr_migratepages) {
			if (isolate_start_pfn >= block_end_pfn) {
				/*
				 * Restart at previous pageblock if more
				 * freepages can be isolated next time.
				 */
				isolate_start_pfn =
					block_start_pfn - pageblock_nr_pages;
			}
			break;
		} else if (isolate_start_pfn < block_end_pfn) {
			/*
			 * If isolation failed early, do not continue
			 * needlessly.
			 */
			break;
		}

		/* Adjust stride depending on isolation */
		if (nr_isolated) {
			stride = 1;
			continue;
		}
		stride = min_t(unsigned int, COMPACT_CLUSTER_MAX, stride << 1);
	}

	/*
	 * Record where the free scanner will restart next time. Either we
	 * broke from the loop and set isolate_start_pfn based on the last
	 * call to isolate_freepages_block(), or we met the migration scanner
	 * and the loop terminated due to isolate_start_pfn < low_pfn
	 */
	cc->free_pfn = isolate_start_pfn;
}

/*
 * This is a migrate-callback that "allocates" freepages by taking pages
 * from the isolated freelists in the block we are migrating to.
 */
static struct folio *compaction_alloc_noprof(struct folio *src, unsigned long data)
{
	struct compact_control *cc = (struct compact_control *)data;
	struct folio *dst;
	int order = folio_order(src);
	bool has_isolated_pages = false;
	int start_order;
	struct page *freepage;
	unsigned long size;

again:
	for (start_order = order; start_order < NR_PAGE_ORDERS; start_order++)
		if (!list_empty(&cc->freepages[start_order]))
			break;

	/* no free pages in the list */
	if (start_order == NR_PAGE_ORDERS) {
		if (has_isolated_pages)
			return NULL;
		isolate_freepages(cc);
		has_isolated_pages = true;
		goto again;
	}

	freepage = list_first_entry(&cc->freepages[start_order], struct page,
				lru);
	size = 1 << start_order;

	list_del(&freepage->lru);

	while (start_order > order) {
		start_order--;
		size >>= 1;

		list_add(&freepage[size].lru, &cc->freepages[start_order]);
		set_page_private(&freepage[size], start_order);
	}
	dst = (struct folio *)freepage;

	post_alloc_hook(&dst->page, order, __GFP_MOVABLE);
	set_page_refcounted(&dst->page);
	if (order)
		prep_compound_page(&dst->page, order);
	cc->nr_freepages -= 1 << order;
	cc->nr_migratepages -= 1 << order;
	return page_rmappable_folio(&dst->page);
}

static struct folio *compaction_alloc(struct folio *src, unsigned long data)
{
	return alloc_hooks(compaction_alloc_noprof(src, data));
}

/*
 * This is a migrate-callback that "frees" freepages back to the isolated
 * freelist.  All pages on the freelist are from the same zone, so there is no
 * special handling needed for NUMA.
 */
static void compaction_free(struct folio *dst, unsigned long data)
{
	struct compact_control *cc = (struct compact_control *)data;
	int order = folio_order(dst);
	struct page *page = &dst->page;

	if (folio_put_testzero(dst)) {
		free_pages_prepare(page, order);
		list_add(&dst->lru, &cc->freepages[order]);
		cc->nr_freepages += 1 << order;
	}
	cc->nr_migratepages += 1 << order;
	/*
	 * someone else has referenced the page, we cannot take it back to our
	 * free list.
	 */
}

/* possible outcome of isolate_migratepages */
typedef enum {
	ISOLATE_ABORT,		/* Abort compaction now */
	ISOLATE_NONE,		/* No pages isolated, continue scanning */
	ISOLATE_SUCCESS,	/* Pages isolated, migrate */
} isolate_migrate_t;

/*
 * Allow userspace to control policy on scanning the unevictable LRU for
 * compactable pages.
 */
static int sysctl_compact_unevictable_allowed __read_mostly = CONFIG_COMPACT_UNEVICTABLE_DEFAULT;
/*
 * Tunable for proactive compaction. It determines how
 * aggressively the kernel should compact memory in the
 * background. It takes values in the range [0, 100].
 */
static unsigned int __read_mostly sysctl_compaction_proactiveness = 20;
static int sysctl_extfrag_threshold = 500;
static int __read_mostly sysctl_compact_memory;

static inline void
update_fast_start_pfn(struct compact_control *cc, unsigned long pfn)
{
	if (cc->fast_start_pfn == ULONG_MAX)
		return;

	if (!cc->fast_start_pfn)
		cc->fast_start_pfn = pfn;

	cc->fast_start_pfn = min(cc->fast_start_pfn, pfn);
}

static inline unsigned long
reinit_migrate_pfn(struct compact_control *cc)
{
	if (!cc->fast_start_pfn || cc->fast_start_pfn == ULONG_MAX)
		return cc->migrate_pfn;

	cc->migrate_pfn = cc->fast_start_pfn;
	cc->fast_start_pfn = ULONG_MAX;

	return cc->migrate_pfn;
}

/*
 * Briefly search the free lists for a migration source that already has
 * some free pages to reduce the number of pages that need migration
 * before a pageblock is free.
 */
static unsigned long fast_find_migrateblock(struct compact_control *cc)
{
	unsigned int limit = freelist_scan_limit(cc);
	unsigned int nr_scanned = 0;
	unsigned long distance;
	unsigned long pfn = cc->migrate_pfn;
	unsigned long high_pfn;
	int order;
	bool found_block = false;

	/* Skip hints are relied on to avoid repeats on the fast search */
	if (cc->ignore_skip_hint)
		return pfn;

	/*
	 * If the pageblock should be finished then do not select a different
	 * pageblock.
	 */
	if (cc->finish_pageblock)
		return pfn;

	/*
	 * If the migrate_pfn is not at the start of a zone or the start
	 * of a pageblock then assume this is a continuation of a previous
	 * scan restarted due to COMPACT_CLUSTER_MAX.
	 */
	if (pfn != cc->zone->zone_start_pfn && pfn != pageblock_start_pfn(pfn))
		return pfn;

	/*
	 * For smaller orders, just linearly scan as the number of pages
	 * to migrate should be relatively small and does not necessarily
	 * justify freeing up a large block for a small allocation.
	 */
	if (cc->order <= PAGE_ALLOC_COSTLY_ORDER)
		return pfn;

	/*
	 * Only allow kcompactd and direct requests for movable pages to
	 * quickly clear out a MOVABLE pageblock for allocation. This
	 * reduces the risk that a large movable pageblock is freed for
	 * an unmovable/reclaimable small allocation.
	 */
	if (cc->direct_compaction && cc->migratetype != MIGRATE_MOVABLE)
		return pfn;

	/*
	 * When starting the migration scanner, pick any pageblock within the
	 * first half of the search space. Otherwise try and pick a pageblock
	 * within the first eighth to reduce the chances that a migration
	 * target later becomes a source.
	 */
	distance = (cc->free_pfn - cc->migrate_pfn) >> 1;
	if (cc->migrate_pfn != cc->zone->zone_start_pfn)
		distance >>= 2;
	high_pfn = pageblock_start_pfn(cc->migrate_pfn + distance);

	for (order = cc->order - 1;
	     order >= PAGE_ALLOC_COSTLY_ORDER && !found_block && nr_scanned < limit;
	     order--) {
		struct free_area *area = &cc->zone->free_area[order];
		struct list_head *freelist;
		unsigned long flags;
		struct page *freepage;

		if (!area->nr_free)
			continue;

		spin_lock_irqsave(&cc->zone->lock, flags);
		freelist = &area->free_list[MIGRATE_MOVABLE];
		list_for_each_entry(freepage, freelist, buddy_list) {
			unsigned long free_pfn;

			if (nr_scanned++ >= limit) {
				move_freelist_tail(freelist, freepage);
				break;
			}

			free_pfn = page_to_pfn(freepage);
			if (free_pfn < high_pfn) {
				/*
				 * Avoid if skipped recently. Ideally it would
				 * move to the tail but even safe iteration of
				 * the list assumes an entry is deleted, not
				 * reordered.
				 */
				if (get_pageblock_skip(freepage))
					continue;

				/* Reorder to so a future search skips recent pages */
				move_freelist_tail(freelist, freepage);

				update_fast_start_pfn(cc, free_pfn);
				pfn = pageblock_start_pfn(free_pfn);
				if (pfn < cc->zone->zone_start_pfn)
					pfn = cc->zone->zone_start_pfn;
				cc->fast_search_fail = 0;
				found_block = true;
				break;
			}
		}
		spin_unlock_irqrestore(&cc->zone->lock, flags);
	}

	cc->total_migrate_scanned += nr_scanned;

	/*
	 * If fast scanning failed then use a cached entry for a page block
	 * that had free pages as the basis for starting a linear scan.
	 */
	if (!found_block) {
		cc->fast_search_fail++;
		pfn = reinit_migrate_pfn(cc);
	}
	return pfn;
}

/*
 * Isolate all pages that can be migrated from the first suitable block,
 * starting at the block pointed to by the migrate scanner pfn within
 * compact_control.
 */
static isolate_migrate_t isolate_migratepages(struct compact_control *cc)
{
	unsigned long block_start_pfn;
	unsigned long block_end_pfn;
	unsigned long low_pfn;
	struct page *page;
	const isolate_mode_t isolate_mode =
		(sysctl_compact_unevictable_allowed ? ISOLATE_UNEVICTABLE : 0) |
		(cc->mode != MIGRATE_SYNC ? ISOLATE_ASYNC_MIGRATE : 0);
	bool fast_find_block;

	/*
	 * Start at where we last stopped, or beginning of the zone as
	 * initialized by compact_zone(). The first failure will use
	 * the lowest PFN as the starting point for linear scanning.
	 */
	low_pfn = fast_find_migrateblock(cc);
	block_start_pfn = pageblock_start_pfn(low_pfn);
	if (block_start_pfn < cc->zone->zone_start_pfn)
		block_start_pfn = cc->zone->zone_start_pfn;

	/*
	 * fast_find_migrateblock() has already ensured the pageblock is not
	 * set with a skipped flag, so to avoid the isolation_suitable check
	 * below again, check whether the fast search was successful.
	 */
	fast_find_block = low_pfn != cc->migrate_pfn && !cc->fast_search_fail;

	/* Only scan within a pageblock boundary */
	block_end_pfn = pageblock_end_pfn(low_pfn);

	/*
	 * Iterate over whole pageblocks until we find the first suitable.
	 * Do not cross the free scanner.
	 */
	for (; block_end_pfn <= cc->free_pfn;
			fast_find_block = false,
			cc->migrate_pfn = low_pfn = block_end_pfn,
			block_start_pfn = block_end_pfn,
			block_end_pfn += pageblock_nr_pages) {

		/*
		 * This can potentially iterate a massively long zone with
		 * many pageblocks unsuitable, so periodically check if we
		 * need to schedule.
		 */
		if (!(low_pfn % (COMPACT_CLUSTER_MAX * pageblock_nr_pages)))
			cond_resched();

		page = pageblock_pfn_to_page(block_start_pfn,
						block_end_pfn, cc->zone);
		if (!page) {
			unsigned long next_pfn;

			next_pfn = skip_offline_sections(block_start_pfn);
			if (next_pfn)
				block_end_pfn = min(next_pfn, cc->free_pfn);
			continue;
		}

		/*
		 * If isolation recently failed, do not retry. Only check the
		 * pageblock once. COMPACT_CLUSTER_MAX causes a pageblock
		 * to be visited multiple times. Assume skip was checked
		 * before making it "skip" so other compaction instances do
		 * not scan the same block.
		 */
		if ((pageblock_aligned(low_pfn) ||
		     low_pfn == cc->zone->zone_start_pfn) &&
		    !fast_find_block && !isolation_suitable(cc, page))
			continue;

		/*
		 * For async direct compaction, only scan the pageblocks of the
		 * same migratetype without huge pages. Async direct compaction
		 * is optimistic to see if the minimum amount of work satisfies
		 * the allocation. The cached PFN is updated as it's possible
		 * that all remaining blocks between source and target are
		 * unsuitable and the compaction scanners fail to meet.
		 */
		if (!suitable_migration_source(cc, page)) {
			update_cached_migrate(cc, block_end_pfn);
			continue;
		}

		/* Perform the isolation */
		if (isolate_migratepages_block(cc, low_pfn, block_end_pfn,
						isolate_mode))
			return ISOLATE_ABORT;

		/*
		 * Either we isolated something and proceed with migration. Or
		 * we failed and compact_zone should decide if we should
		 * continue or not.
		 */
		break;
	}

	return cc->nr_migratepages ? ISOLATE_SUCCESS : ISOLATE_NONE;
}

/*
 * Determine whether kswapd is (or recently was!) running on this node.
 *
 * pgdat_kswapd_lock() pins pgdat->kswapd, so a concurrent kswapd_stop() can't
 * zero it.
 */
static bool kswapd_is_running(pg_data_t *pgdat)
{
	bool running;

	pgdat_kswapd_lock(pgdat);
	running = pgdat->kswapd && task_is_running(pgdat->kswapd);
	pgdat_kswapd_unlock(pgdat);

	return running;
}

/*
 * A zone's fragmentation score is the external fragmentation wrt to the
 * COMPACTION_HPAGE_ORDER. It returns a value in the range [0, 100].
 */
static unsigned int fragmentation_score_zone(struct zone *zone)
{
	return extfrag_for_order(zone, COMPACTION_HPAGE_ORDER);
}

/*
 * A weighted zone's fragmentation score is the external fragmentation
 * wrt to the COMPACTION_HPAGE_ORDER scaled by the zone's size. It
 * returns a value in the range [0, 100].
 *
 * The scaling factor ensures that proactive compaction focuses on larger
 * zones like ZONE_NORMAL, rather than smaller, specialized zones like
 * ZONE_DMA32. For smaller zones, the score value remains close to zero,
 * and thus never exceeds the high threshold for proactive compaction.
 */
static unsigned int fragmentation_score_zone_weighted(struct zone *zone)
{
	unsigned long score;

	score = zone->present_pages * fragmentation_score_zone(zone);
	return div64_ul(score, zone->zone_pgdat->node_present_pages + 1);
}

/*
 * The per-node proactive (background) compaction process is started by its
 * corresponding kcompactd thread when the node's fragmentation score
 * exceeds the high threshold. The compaction process remains active till
 * the node's score falls below the low threshold, or one of the back-off
 * conditions is met.
 */
static unsigned int fragmentation_score_node(pg_data_t *pgdat)
{
	unsigned int score = 0;
	int zoneid;

	for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) {
		struct zone *zone;

		zone = &pgdat->node_zones[zoneid];
		if (!populated_zone(zone))
			continue;
		score += fragmentation_score_zone_weighted(zone);
	}

	return score;
}

static unsigned int fragmentation_score_wmark(bool low)
{
	unsigned int wmark_low;

	/*
	 * Cap the low watermark to avoid excessive compaction
	 * activity in case a user sets the proactiveness tunable
	 * close to 100 (maximum).
	 */
	wmark_low = max(100U - sysctl_compaction_proactiveness, 5U);
	return low ? wmark_low : min(wmark_low + 10, 100U);
}

static bool should_proactive_compact_node(pg_data_t *pgdat)
{
	int wmark_high;

	if (!sysctl_compaction_proactiveness || kswapd_is_running(pgdat))
		return false;

	wmark_high = fragmentation_score_wmark(false);
	return fragmentation_score_node(pgdat) > wmark_high;
}

static enum compact_result __compact_finished(struct compact_control *cc)
{
	unsigned int order;
	const int migratetype = cc->migratetype;
	int ret;

	/* Compaction run completes if the migrate and free scanner meet */
	if (compact_scanners_met(cc)) {
		/* Let the next compaction start anew. */
		reset_cached_positions(cc->zone);

		/*
		 * Mark that the PG_migrate_skip information should be cleared
		 * by kswapd when it goes to sleep. kcompactd does not set the
		 * flag itself as the decision to be clear should be directly
		 * based on an allocation request.
		 */
		if (cc->direct_compaction)
			cc->zone->compact_blockskip_flush = true;

		if (cc->whole_zone)
			return COMPACT_COMPLETE;
		else
			return COMPACT_PARTIAL_SKIPPED;
	}

	if (cc->proactive_compaction) {
		int score, wmark_low;
		pg_data_t *pgdat;

		pgdat = cc->zone->zone_pgdat;
		if (kswapd_is_running(pgdat))
			return COMPACT_PARTIAL_SKIPPED;

		score = fragmentation_score_zone(cc->zone);
		wmark_low = fragmentation_score_wmark(true);

		if (score > wmark_low)
			ret = COMPACT_CONTINUE;
		else
			ret = COMPACT_SUCCESS;

		goto out;
	}

	if (is_via_compact_memory(cc->order))
		return COMPACT_CONTINUE;

	/*
	 * Always finish scanning a pageblock to reduce the possibility of
	 * fallbacks in the future. This is particularly important when
	 * migration source is unmovable/reclaimable but it's not worth
	 * special casing.
	 */
	if (!pageblock_aligned(cc->migrate_pfn))
		return COMPACT_CONTINUE;

	/*
	 * When defrag_mode is enabled, make kcompactd target
	 * watermarks in whole pageblocks. Because they can be stolen
	 * without polluting, no further fallback checks are needed.
	 */
	if (defrag_mode && !cc->direct_compaction) {
		if (__zone_watermark_ok(cc->zone, cc->order,
					high_wmark_pages(cc->zone),
					cc->highest_zoneidx, cc->alloc_flags,
					zone_page_state(cc->zone,
							NR_FREE_PAGES_BLOCKS)))
			return COMPACT_SUCCESS;

		return COMPACT_CONTINUE;
	}

	/* Direct compactor: Is a suitable page free? */
	ret = COMPACT_NO_SUITABLE_PAGE;
	for (order = cc->order; order < NR_PAGE_ORDERS; order++) {
		struct free_area *area = &cc->zone->free_area[order];
		bool claim_block;

		/* Job done if page is free of the right migratetype */
		if (!free_area_empty(area, migratetype))
			return COMPACT_SUCCESS;

#ifdef CONFIG_CMA
		/* MIGRATE_MOVABLE can fallback on MIGRATE_CMA */
		if (migratetype == MIGRATE_MOVABLE &&
			!free_area_empty(area, MIGRATE_CMA))
			return COMPACT_SUCCESS;
#endif
		/*
		 * Job done if allocation would steal freepages from
		 * other migratetype buddy lists.
		 */
		if (find_suitable_fallback(area, order, migratetype,
						true, &claim_block) != -1)
			/*
			 * Movable pages are OK in any pageblock. If we are
			 * stealing for a non-movable allocation, make sure
			 * we finish compacting the current pageblock first
			 * (which is assured by the above migrate_pfn align
			 * check) so it is as free as possible and we won't
			 * have to steal another one soon.
			 */
			return COMPACT_SUCCESS;
	}

out:
	if (cc->contended || fatal_signal_pending(current))
		ret = COMPACT_CONTENDED;

	return ret;
}

static enum compact_result compact_finished(struct compact_control *cc)
{
	int ret;

	ret = __compact_finished(cc);
	trace_mm_compaction_finished(cc->zone, cc->order, ret);
	if (ret == COMPACT_NO_SUITABLE_PAGE)
		ret = COMPACT_CONTINUE;

	return ret;
}

static bool __compaction_suitable(struct zone *zone, int order,
				  unsigned long watermark, int highest_zoneidx,
				  unsigned long free_pages)
{
	/*
	 * Watermarks for order-0 must be met for compaction to be able to
	 * isolate free pages for migration targets. This means that the
	 * watermark have to match, or be more pessimistic than the check in
	 * __isolate_free_page().
	 *
	 * For costly orders, we require a higher watermark for compaction to
	 * proceed to increase its chances.
	 *
	 * We use the direct compactor's highest_zoneidx to skip over zones
	 * where lowmem reserves would prevent allocation even if compaction
	 * succeeds.
	 *
	 * ALLOC_CMA is used, as pages in CMA pageblocks are considered
	 * suitable migration targets.
	 */
	watermark += compact_gap(order);
	if (order > PAGE_ALLOC_COSTLY_ORDER)
		watermark += low_wmark_pages(zone) - min_wmark_pages(zone);
	return __zone_watermark_ok(zone, 0, watermark, highest_zoneidx,
				   ALLOC_CMA, free_pages);
}

/*
 * compaction_suitable: Is this suitable to run compaction on this zone now?
 */
bool compaction_suitable(struct zone *zone, int order, unsigned long watermark,
			 int highest_zoneidx)
{
	enum compact_result compact_result;
	bool suitable;

	suitable = __compaction_suitable(zone, order, watermark, highest_zoneidx,
					 zone_page_state(zone, NR_FREE_PAGES));
	/*
	 * fragmentation index determines if allocation failures are due to
	 * low memory or external fragmentation
	 *
	 * index of -1000 would imply allocations might succeed depending on
	 * watermarks, but we already failed the high-order watermark check
	 * index towards 0 implies failure is due to lack of memory
	 * index towards 1000 implies failure is due to fragmentation
	 *
	 * Only compact if a failure would be due to fragmentation. Also
	 * ignore fragindex for non-costly orders where the alternative to
	 * a successful reclaim/compaction is OOM. Fragindex and the
	 * vm.extfrag_threshold sysctl is meant as a heuristic to prevent
	 * excessive compaction for costly orders, but it should not be at the
	 * expense of system stability.
	 */
	if (suitable) {
		compact_result = COMPACT_CONTINUE;
		if (order > PAGE_ALLOC_COSTLY_ORDER) {
			int fragindex = fragmentation_index(zone, order);

			if (fragindex >= 0 &&
			    fragindex <= sysctl_extfrag_threshold) {
				suitable = false;
				compact_result = COMPACT_NOT_SUITABLE_ZONE;
			}
		}
	} else {
		compact_result = COMPACT_SKIPPED;
	}

	trace_mm_compaction_suitable(zone, order, compact_result);

	return suitable;
}

/* Used by direct reclaimers */
bool compaction_zonelist_suitable(struct alloc_context *ac, int order,
		int alloc_flags)
{
	struct zone *zone;
	struct zoneref *z;

	/*
	 * Make sure at least one zone would pass __compaction_suitable if we continue
	 * retrying the reclaim.
	 */
	for_each_zone_zonelist_nodemask(zone, z, ac->zonelist,
				ac->highest_zoneidx, ac->nodemask) {
		unsigned long available;

		/*
		 * Do not consider all the reclaimable memory because we do not
		 * want to trash just for a single high order allocation which
		 * is even not guaranteed to appear even if __compaction_suitable
		 * is happy about the watermark check.
		 */
		available = zone_reclaimable_pages(zone) / order;
		available += zone_page_state_snapshot(zone, NR_FREE_PAGES);
		if (__compaction_suitable(zone, order, min_wmark_pages(zone),
					  ac->highest_zoneidx, available))
			return true;
	}

	return false;
}

/*
 * Should we do compaction for target allocation order.
 * Return COMPACT_SUCCESS if allocation for target order can be already
 * satisfied
 * Return COMPACT_SKIPPED if compaction for target order is likely to fail
 * Return COMPACT_CONTINUE if compaction for target order should be ran
 */
static enum compact_result
compaction_suit_allocation_order(struct zone *zone, unsigned int order,
				 int highest_zoneidx, unsigned int alloc_flags,
				 bool async, bool kcompactd)
{
	unsigned long free_pages;
	unsigned long watermark;

	if (kcompactd && defrag_mode)
		free_pages = zone_page_state(zone, NR_FREE_PAGES_BLOCKS);
	else
		free_pages = zone_page_state(zone, NR_FREE_PAGES);

	watermark = wmark_pages(zone, alloc_flags & ALLOC_WMARK_MASK);
	if (__zone_watermark_ok(zone, order, watermark, highest_zoneidx,
				alloc_flags, free_pages))
		return COMPACT_SUCCESS;

	/*
	 * For unmovable allocations (without ALLOC_CMA), check if there is enough
	 * free memory in the non-CMA pageblocks. Otherwise compaction could form
	 * the high-order page in CMA pageblocks, which would not help the
	 * allocation to succeed. However, limit the check to costly order async
	 * compaction (such as opportunistic THP attempts) because there is the
	 * possibility that compaction would migrate pages from non-CMA to CMA
	 * pageblock.
	 */
	if (order > PAGE_ALLOC_COSTLY_ORDER && async &&
	    !(alloc_flags & ALLOC_CMA)) {
		if (!__zone_watermark_ok(zone, 0, watermark + compact_gap(order),
					 highest_zoneidx, 0,
					 zone_page_state(zone, NR_FREE_PAGES)))
			return COMPACT_SKIPPED;
	}

	if (!compaction_suitable(zone, order, watermark, highest_zoneidx))
		return COMPACT_SKIPPED;

	return COMPACT_CONTINUE;
}

static enum compact_result
compact_zone(struct compact_control *cc, struct capture_control *capc)
{
	enum compact_result ret;
	unsigned long start_pfn = cc->zone->zone_start_pfn;
	unsigned long end_pfn = zone_end_pfn(cc->zone);
	unsigned long last_migrated_pfn;
	const bool sync = cc->mode != MIGRATE_ASYNC;
	bool update_cached;
	unsigned int nr_succeeded = 0, nr_migratepages;
	int order;

	/*
	 * These counters track activities during zone compaction.  Initialize
	 * them before compacting a new zone.
	 */
	cc->total_migrate_scanned = 0;
	cc->total_free_scanned = 0;
	cc->nr_migratepages = 0;
	cc->nr_freepages = 0;
	for (order = 0; order < NR_PAGE_ORDERS; order++)
		INIT_LIST_HEAD(&cc->freepages[order]);
	INIT_LIST_HEAD(&cc->migratepages);

	cc->migratetype = gfp_migratetype(cc->gfp_mask);

	if (!is_via_compact_memory(cc->order)) {
		ret = compaction_suit_allocation_order(cc->zone, cc->order,
						       cc->highest_zoneidx,
						       cc->alloc_flags,
						       cc->mode == MIGRATE_ASYNC,
						       !cc->direct_compaction);
		if (ret != COMPACT_CONTINUE)
			return ret;
	}

	/*
	 * Clear pageblock skip if there were failures recently and compaction
	 * is about to be retried after being deferred.
	 */
	if (compaction_restarting(cc->zone, cc->order))
		__reset_isolation_suitable(cc->zone);

	/*
	 * Setup to move all movable pages to the end of the zone. Used cached
	 * information on where the scanners should start (unless we explicitly
	 * want to compact the whole zone), but check that it is initialised
	 * by ensuring the values are within zone boundaries.
	 */
	cc->fast_start_pfn = 0;
	if (cc->whole_zone) {
		cc->migrate_pfn = start_pfn;
		cc->free_pfn = pageblock_start_pfn(end_pfn - 1);
	} else {
		cc->migrate_pfn = cc->zone->compact_cached_migrate_pfn[sync];
		cc->free_pfn = cc->zone->compact_cached_free_pfn;
		if (cc->free_pfn < start_pfn || cc->free_pfn >= end_pfn) {
			cc->free_pfn = pageblock_start_pfn(end_pfn - 1);
			cc->zone->compact_cached_free_pfn = cc->free_pfn;
		}
		if (cc->migrate_pfn < start_pfn || cc->migrate_pfn >= end_pfn) {
			cc->migrate_pfn = start_pfn;
			cc->zone->compact_cached_migrate_pfn[0] = cc->migrate_pfn;
			cc->zone->compact_cached_migrate_pfn[1] = cc->migrate_pfn;
		}

		if (cc->migrate_pfn <= cc->zone->compact_init_migrate_pfn)
			cc->whole_zone = true;
	}

	last_migrated_pfn = 0;

	/*
	 * Migrate has separate cached PFNs for ASYNC and SYNC* migration on
	 * the basis that some migrations will fail in ASYNC mode. However,
	 * if the cached PFNs match and pageblocks are skipped due to having
	 * no isolation candidates, then the sync state does not matter.
	 * Until a pageblock with isolation candidates is found, keep the
	 * cached PFNs in sync to avoid revisiting the same blocks.
	 */
	update_cached = !sync &&
		cc->zone->compact_cached_migrate_pfn[0] == cc->zone->compact_cached_migrate_pfn[1];

	trace_mm_compaction_begin(cc, start_pfn, end_pfn, sync);

	/* lru_add_drain_all could be expensive with involving other CPUs */
	lru_add_drain();

	while ((ret = compact_finished(cc)) == COMPACT_CONTINUE) {
		int err;
		unsigned long iteration_start_pfn = cc->migrate_pfn;

		/*
		 * Avoid multiple rescans of the same pageblock which can
		 * happen if a page cannot be isolated (dirty/writeback in
		 * async mode) or if the migrated pages are being allocated
		 * before the pageblock is cleared.  The first rescan will
		 * capture the entire pageblock for migration. If it fails,
		 * it'll be marked skip and scanning will proceed as normal.
		 */
		cc->finish_pageblock = false;
		if (pageblock_start_pfn(last_migrated_pfn) ==
		    pageblock_start_pfn(iteration_start_pfn)) {
			cc->finish_pageblock = true;
		}

rescan:
		switch (isolate_migratepages(cc)) {
		case ISOLATE_ABORT:
			ret = COMPACT_CONTENDED;
			putback_movable_pages(&cc->migratepages);
			cc->nr_migratepages = 0;
			goto out;
		case ISOLATE_NONE:
			if (update_cached) {
				cc->zone->compact_cached_migrate_pfn[1] =
					cc->zone->compact_cached_migrate_pfn[0];
			}

			/*
			 * We haven't isolated and migrated anything, but
			 * there might still be unflushed migrations from
			 * previous cc->order aligned block.
			 */
			goto check_drain;
		case ISOLATE_SUCCESS:
			update_cached = false;
			last_migrated_pfn = max(cc->zone->zone_start_pfn,
				pageblock_start_pfn(cc->migrate_pfn - 1));
		}

		/*
		 * Record the number of pages to migrate since the
		 * compaction_alloc/free() will update cc->nr_migratepages
		 * properly.
		 */
		nr_migratepages = cc->nr_migratepages;
		err = migrate_pages(&cc->migratepages, compaction_alloc,
				compaction_free, (unsigned long)cc, cc->mode,
				MR_COMPACTION, &nr_succeeded);

		trace_mm_compaction_migratepages(nr_migratepages, nr_succeeded);

		/* All pages were either migrated or will be released */
		cc->nr_migratepages = 0;
		if (err) {
			putback_movable_pages(&cc->migratepages);
			/*
			 * migrate_pages() may return -ENOMEM when scanners meet
			 * and we want compact_finished() to detect it
			 */
			if (err == -ENOMEM && !compact_scanners_met(cc)) {
				ret = COMPACT_CONTENDED;
				goto out;
			}
			/*
			 * If an ASYNC or SYNC_LIGHT fails to migrate a page
			 * within the pageblock_order-aligned block and
			 * fast_find_migrateblock may be used then scan the
			 * remainder of the pageblock. This will mark the
			 * pageblock "skip" to avoid rescanning in the near
			 * future. This will isolate more pages than necessary
			 * for the request but avoid loops due to
			 * fast_find_migrateblock revisiting blocks that were
			 * recently partially scanned.
			 */
			if (!pageblock_aligned(cc->migrate_pfn) &&
			    !cc->ignore_skip_hint && !cc->finish_pageblock &&
			    (cc->mode < MIGRATE_SYNC)) {
				cc->finish_pageblock = true;

				/*
				 * Draining pcplists does not help THP if
				 * any page failed to migrate. Even after
				 * drain, the pageblock will not be free.
				 */
				if (cc->order == COMPACTION_HPAGE_ORDER)
					last_migrated_pfn = 0;

				goto rescan;
			}
		}

		/* Stop if a page has been captured */
		if (capc && capc->page) {
			ret = COMPACT_SUCCESS;
			break;
		}

check_drain:
		/*
		 * Has the migration scanner moved away from the previous
		 * cc->order aligned block where we migrated from? If yes,
		 * flush the pages that were freed, so that they can merge and
		 * compact_finished() can detect immediately if allocation
		 * would succeed.
		 */
		if (cc->order > 0 && last_migrated_pfn) {
			unsigned long current_block_start =
				block_start_pfn(cc->migrate_pfn, cc->order);

			if (last_migrated_pfn < current_block_start) {
				lru_add_drain_cpu_zone(cc->zone);
				/* No more flushing until we migrate again */
				last_migrated_pfn = 0;
			}
		}
	}

out:
	/*
	 * Release free pages and update where the free scanner should restart,
	 * so we don't leave any returned pages behind in the next attempt.
	 */
	if (cc->nr_freepages > 0) {
		unsigned long free_pfn = release_free_list(cc->freepages);

		cc->nr_freepages = 0;
		VM_BUG_ON(free_pfn == 0);
		/* The cached pfn is always the first in a pageblock */
		free_pfn = pageblock_start_pfn(free_pfn);
		/*
		 * Only go back, not forward. The cached pfn might have been
		 * already reset to zone end in compact_finished()
		 */
		if (free_pfn > cc->zone->compact_cached_free_pfn)
			cc->zone->compact_cached_free_pfn = free_pfn;
	}

	count_compact_events(COMPACTMIGRATE_SCANNED, cc->total_migrate_scanned);
	count_compact_events(COMPACTFREE_SCANNED, cc->total_free_scanned);

	trace_mm_compaction_end(cc, start_pfn, end_pfn, sync, ret);

	VM_BUG_ON(!list_empty(&cc->migratepages));

	return ret;
}

static enum compact_result compact_zone_order(struct zone *zone, int order,
		gfp_t gfp_mask, enum compact_priority prio,
		unsigned int alloc_flags, int highest_zoneidx,
		struct page **capture)
{
	enum compact_result ret;
	struct compact_control cc = {
		.order = order,
		.search_order = order,
		.gfp_mask = gfp_mask,
		.zone = zone,
		.mode = (prio == COMPACT_PRIO_ASYNC) ?
					MIGRATE_ASYNC :	MIGRATE_SYNC_LIGHT,
		.alloc_flags = alloc_flags,
		.highest_zoneidx = highest_zoneidx,
		.direct_compaction = true,
		.whole_zone = (prio == MIN_COMPACT_PRIORITY),
		.ignore_skip_hint = (prio == MIN_COMPACT_PRIORITY),
		.ignore_block_suitable = (prio == MIN_COMPACT_PRIORITY)
	};
	struct capture_control capc = {
		.cc = &cc,
		.page = NULL,
	};

	/*
	 * Make sure the structs are really initialized before we expose the
	 * capture control, in case we are interrupted and the interrupt handler
	 * frees a page.
	 */
	barrier();
	WRITE_ONCE(current->capture_control, &capc);

	ret = compact_zone(&cc, &capc);

	/*
	 * Make sure we hide capture control first before we read the captured
	 * page pointer, otherwise an interrupt could free and capture a page
	 * and we would leak it.
	 */
	WRITE_ONCE(current->capture_control, NULL);
	*capture = READ_ONCE(capc.page);
	/*
	 * Technically, it is also possible that compaction is skipped but
	 * the page is still captured out of luck(IRQ came and freed the page).
	 * Returning COMPACT_SUCCESS in such cases helps in properly accounting
	 * the COMPACT[STALL|FAIL] when compaction is skipped.
	 */
	if (*capture)
		ret = COMPACT_SUCCESS;

	return ret;
}

/**
 * try_to_compact_pages - Direct compact to satisfy a high-order allocation
 * @gfp_mask: The GFP mask of the current allocation
 * @order: The order of the current allocation
 * @alloc_flags: The allocation flags of the current allocation
 * @ac: The context of current allocation
 * @prio: Determines how hard direct compaction should try to succeed
 * @capture: Pointer to free page created by compaction will be stored here
 *
 * This is the main entry point for direct page compaction.
 */
enum compact_result try_to_compact_pages(gfp_t gfp_mask, unsigned int order,
		unsigned int alloc_flags, const struct alloc_context *ac,
		enum compact_priority prio, struct page **capture)
{
	struct zoneref *z;
	struct zone *zone;
	enum compact_result rc = COMPACT_SKIPPED;

	if (!gfp_compaction_allowed(gfp_mask))
		return COMPACT_SKIPPED;

	trace_mm_compaction_try_to_compact_pages(order, gfp_mask, prio);

	/* Compact each zone in the list */
	for_each_zone_zonelist_nodemask(zone, z, ac->zonelist,
					ac->highest_zoneidx, ac->nodemask) {
		enum compact_result status;

		if (cpusets_enabled() &&
			(alloc_flags & ALLOC_CPUSET) &&
			!__cpuset_zone_allowed(zone, gfp_mask))
				continue;

		if (prio > MIN_COMPACT_PRIORITY
					&& compaction_deferred(zone, order)) {
			rc = max_t(enum compact_result, COMPACT_DEFERRED, rc);
			continue;
		}

		status = compact_zone_order(zone, order, gfp_mask, prio,
				alloc_flags, ac->highest_zoneidx, capture);
		rc = max(status, rc);

		/* The allocation should succeed, stop compacting */
		if (status == COMPACT_SUCCESS) {
			/*
			 * We think the allocation will succeed in this zone,
			 * but it is not certain, hence the false. The caller
			 * will repeat this with true if allocation indeed
			 * succeeds in this zone.
			 */
			compaction_defer_reset(zone, order, false);

			break;
		}

		if (prio != COMPACT_PRIO_ASYNC && (status == COMPACT_COMPLETE ||
					status == COMPACT_PARTIAL_SKIPPED))
			/*
			 * We think that allocation won't succeed in this zone
			 * so we defer compaction there. If it ends up
			 * succeeding after all, it will be reset.
			 */
			defer_compaction(zone, order);

		/*
		 * We might have stopped compacting due to need_resched() in
		 * async compaction, or due to a fatal signal detected. In that
		 * case do not try further zones
		 */
		if ((prio == COMPACT_PRIO_ASYNC && need_resched())
					|| fatal_signal_pending(current))
			break;
	}

	return rc;
}

/*
 * compact_node() - compact all zones within a node
 * @pgdat: The node page data
 * @proactive: Whether the compaction is proactive
 *
 * For proactive compaction, compact till each zone's fragmentation score
 * reaches within proactive compaction thresholds (as determined by the
 * proactiveness tunable), it is possible that the function returns before
 * reaching score targets due to various back-off conditions, such as,
 * contention on per-node or per-zone locks.
 */
static int compact_node(pg_data_t *pgdat, bool proactive)
{
	int zoneid;
	struct zone *zone;
	struct compact_control cc = {
		.order = -1,
		.mode = proactive ? MIGRATE_SYNC_LIGHT : MIGRATE_SYNC,
		.ignore_skip_hint = true,
		.whole_zone = true,
		.gfp_mask = GFP_KERNEL,
		.proactive_compaction = proactive,
	};

	for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) {
		zone = &pgdat->node_zones[zoneid];
		if (!populated_zone(zone))
			continue;

		if (fatal_signal_pending(current))
			return -EINTR;

		cc.zone = zone;

		compact_zone(&cc, NULL);

		if (proactive) {
			count_compact_events(KCOMPACTD_MIGRATE_SCANNED,
					     cc.total_migrate_scanned);
			count_compact_events(KCOMPACTD_FREE_SCANNED,
					     cc.total_free_scanned);
		}
	}

	return 0;
}

/* Compact all zones of all nodes in the system */
static int compact_nodes(void)
{
	int ret, nid;

	/* Flush pending updates to the LRU lists */
	lru_add_drain_all();

	for_each_online_node(nid) {
		ret = compact_node(NODE_DATA(nid), false);
		if (ret)
			return ret;
	}

	return 0;
}

static int compaction_proactiveness_sysctl_handler(const struct ctl_table *table, int write,
		void *buffer, size_t *length, loff_t *ppos)
{
	int rc, nid;

	rc = proc_dointvec_minmax(table, write, buffer, length, ppos);
	if (rc)
		return rc;

	if (write && sysctl_compaction_proactiveness) {
		for_each_online_node(nid) {
			pg_data_t *pgdat = NODE_DATA(nid);

			if (pgdat->proactive_compact_trigger)
				continue;

			pgdat->proactive_compact_trigger = true;
			trace_mm_compaction_wakeup_kcompactd(pgdat->node_id, -1,
							     pgdat->nr_zones - 1);
			wake_up_interruptible(&pgdat->kcompactd_wait);
		}
	}

	return 0;
}

/*
 * This is the entry point for compacting all nodes via
 * /proc/sys/vm/compact_memory
 */
static int sysctl_compaction_handler(const struct ctl_table *table, int write,
			void *buffer, size_t *length, loff_t *ppos)
{
	int ret;

	ret = proc_dointvec(table, write, buffer, length, ppos);
	if (ret)
		return ret;

	if (sysctl_compact_memory != 1)
		return -EINVAL;

	if (write)
		ret = compact_nodes();

	return ret;
}

#if defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
static ssize_t compact_store(struct device *dev,
			     struct device_attribute *attr,
			     const char *buf, size_t count)
{
	int nid = dev->id;

	if (nid >= 0 && nid < nr_node_ids && node_online(nid)) {
		/* Flush pending updates to the LRU lists */
		lru_add_drain_all();

		compact_node(NODE_DATA(nid), false);
	}

	return count;
}
static DEVICE_ATTR_WO(compact);

int compaction_register_node(struct node *node)
{
	return device_create_file(&node->dev, &dev_attr_compact);
}

void compaction_unregister_node(struct node *node)
{
	device_remove_file(&node->dev, &dev_attr_compact);
}
#endif /* CONFIG_SYSFS && CONFIG_NUMA */

static inline bool kcompactd_work_requested(pg_data_t *pgdat)
{
	return pgdat->kcompactd_max_order > 0 || kthread_should_stop() ||
		pgdat->proactive_compact_trigger;
}

static bool kcompactd_node_suitable(pg_data_t *pgdat)
{
	int zoneid;
	struct zone *zone;
	enum zone_type highest_zoneidx = pgdat->kcompactd_highest_zoneidx;
	enum compact_result ret;
	unsigned int alloc_flags = defrag_mode ?
		ALLOC_WMARK_HIGH : ALLOC_WMARK_MIN;

	for (zoneid = 0; zoneid <= highest_zoneidx; zoneid++) {
		zone = &pgdat->node_zones[zoneid];

		if (!populated_zone(zone))
			continue;

		ret = compaction_suit_allocation_order(zone,
				pgdat->kcompactd_max_order,
				highest_zoneidx, alloc_flags,
				false, true);
		if (ret == COMPACT_CONTINUE)
			return true;
	}

	return false;
}

static void kcompactd_do_work(pg_data_t *pgdat)
{
	/*
	 * With no special task, compact all zones so that a page of requested
	 * order is allocatable.
	 */
	int zoneid;
	struct zone *zone;
	struct compact_control cc = {
		.order = pgdat->kcompactd_max_order,
		.search_order = pgdat->kcompactd_max_order,
		.highest_zoneidx = pgdat->kcompactd_highest_zoneidx,
		.mode = MIGRATE_SYNC_LIGHT,
		.ignore_skip_hint = false,
		.gfp_mask = GFP_KERNEL,
		.alloc_flags = defrag_mode ? ALLOC_WMARK_HIGH : ALLOC_WMARK_MIN,
	};
	enum compact_result ret;

	trace_mm_compaction_kcompactd_wake(pgdat->node_id, cc.order,
							cc.highest_zoneidx);
	count_compact_event(KCOMPACTD_WAKE);

	for (zoneid = 0; zoneid <= cc.highest_zoneidx; zoneid++) {
		int status;

		zone = &pgdat->node_zones[zoneid];
		if (!populated_zone(zone))
			continue;

		if (compaction_deferred(zone, cc.order))
			continue;

		ret = compaction_suit_allocation_order(zone,
				cc.order, zoneid, cc.alloc_flags,
				false, true);
		if (ret != COMPACT_CONTINUE)
			continue;

		if (kthread_should_stop())
			return;

		cc.zone = zone;
		status = compact_zone(&cc, NULL);

		if (status == COMPACT_SUCCESS) {
			compaction_defer_reset(zone, cc.order, false);
		} else if (status == COMPACT_PARTIAL_SKIPPED || status == COMPACT_COMPLETE) {
			/*
			 * Buddy pages may become stranded on pcps that could
			 * otherwise coalesce on the zone's free area for
			 * order >= cc.order.  This is ratelimited by the
			 * upcoming deferral.
			 */
			drain_all_pages(zone);

			/*
			 * We use sync migration mode here, so we defer like
			 * sync direct compaction does.
			 */
			defer_compaction(zone, cc.order);
		}

		count_compact_events(KCOMPACTD_MIGRATE_SCANNED,
				     cc.total_migrate_scanned);
		count_compact_events(KCOMPACTD_FREE_SCANNED,
				     cc.total_free_scanned);
	}

	/*
	 * Regardless of success, we are done until woken up next. But remember
	 * the requested order/highest_zoneidx in case it was higher/tighter
	 * than our current ones
	 */
	if (pgdat->kcompactd_max_order <= cc.order)
		pgdat->kcompactd_max_order = 0;
	if (pgdat->kcompactd_highest_zoneidx >= cc.highest_zoneidx)
		pgdat->kcompactd_highest_zoneidx = pgdat->nr_zones - 1;
}

void wakeup_kcompactd(pg_data_t *pgdat, int order, int highest_zoneidx)
{
	if (!order)
		return;

	if (pgdat->kcompactd_max_order < order)
		pgdat->kcompactd_max_order = order;

	if (pgdat->kcompactd_highest_zoneidx > highest_zoneidx)
		pgdat->kcompactd_highest_zoneidx = highest_zoneidx;

	/*
	 * Pairs with implicit barrier in wait_event_freezable()
	 * such that wakeups are not missed.
	 */
	if (!wq_has_sleeper(&pgdat->kcompactd_wait))
		return;

	if (!kcompactd_node_suitable(pgdat))
		return;

	trace_mm_compaction_wakeup_kcompactd(pgdat->node_id, order,
							highest_zoneidx);
	wake_up_interruptible(&pgdat->kcompactd_wait);
}

/*
 * The background compaction daemon, started as a kernel thread
 * from the init process.
 */
static int kcompactd(void *p)
{
	pg_data_t *pgdat = (pg_data_t *)p;
	long default_timeout = msecs_to_jiffies(HPAGE_FRAG_CHECK_INTERVAL_MSEC);
	long timeout = default_timeout;

	current->flags |= PF_KCOMPACTD;
	set_freezable();

	pgdat->kcompactd_max_order = 0;
	pgdat->kcompactd_highest_zoneidx = pgdat->nr_zones - 1;

	while (!kthread_should_stop()) {
		unsigned long pflags;

		/*
		 * Avoid the unnecessary wakeup for proactive compaction
		 * when it is disabled.
		 */
		if (!sysctl_compaction_proactiveness)
			timeout = MAX_SCHEDULE_TIMEOUT;
		trace_mm_compaction_kcompactd_sleep(pgdat->node_id);
		if (wait_event_freezable_timeout(pgdat->kcompactd_wait,
			kcompactd_work_requested(pgdat), timeout) &&
			!pgdat->proactive_compact_trigger) {

			psi_memstall_enter(&pflags);
			kcompactd_do_work(pgdat);
			psi_memstall_leave(&pflags);
			/*
			 * Reset the timeout value. The defer timeout from
			 * proactive compaction is lost here but that is fine
			 * as the condition of the zone changing substantionally
			 * then carrying on with the previous defer interval is
			 * not useful.
			 */
			timeout = default_timeout;
			continue;
		}

		/*
		 * Start the proactive work with default timeout. Based
		 * on the fragmentation score, this timeout is updated.
		 */
		timeout = default_timeout;
		if (should_proactive_compact_node(pgdat)) {
			unsigned int prev_score, score;

			prev_score = fragmentation_score_node(pgdat);
			compact_node(pgdat, true);
			score = fragmentation_score_node(pgdat);
			/*
			 * Defer proactive compaction if the fragmentation
			 * score did not go down i.e. no progress made.
			 */
			if (unlikely(score >= prev_score))
				timeout =
				   default_timeout << COMPACT_MAX_DEFER_SHIFT;
		}
		if (unlikely(pgdat->proactive_compact_trigger))
			pgdat->proactive_compact_trigger = false;
	}

	current->flags &= ~PF_KCOMPACTD;

	return 0;
}

/*
 * This kcompactd start function will be called by init and node-hot-add.
 * On node-hot-add, kcompactd will moved to proper cpus if cpus are hot-added.
 */
void __meminit kcompactd_run(int nid)
{
	pg_data_t *pgdat = NODE_DATA(nid);

	if (pgdat->kcompactd)
		return;

	pgdat->kcompactd = kthread_create_on_node(kcompactd, pgdat, nid, "kcompactd%d", nid);
	if (IS_ERR(pgdat->kcompactd)) {
		pr_err("Failed to start kcompactd on node %d\n", nid);
		pgdat->kcompactd = NULL;
	} else {
		wake_up_process(pgdat->kcompactd);
	}
}

/*
 * Called by memory hotplug when all memory in a node is offlined. Caller must
 * be holding mem_hotplug_begin/done().
 */
void __meminit kcompactd_stop(int nid)
{
	struct task_struct *kcompactd = NODE_DATA(nid)->kcompactd;

	if (kcompactd) {
		kthread_stop(kcompactd);
		NODE_DATA(nid)->kcompactd = NULL;
	}
}

static int proc_dointvec_minmax_warn_RT_change(const struct ctl_table *table,
		int write, void *buffer, size_t *lenp, loff_t *ppos)
{
	int ret, old;

	if (!IS_ENABLED(CONFIG_PREEMPT_RT) || !write)
		return proc_dointvec_minmax(table, write, buffer, lenp, ppos);

	old = *(int *)table->data;
	ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
	if (ret)
		return ret;
	if (old != *(int *)table->data)
		pr_warn_once("sysctl attribute %s changed by %s[%d]\n",
			     table->procname, current->comm,
			     task_pid_nr(current));
	return ret;
}

static const struct ctl_table vm_compaction[] = {
	{
		.procname	= "compact_memory",
		.data		= &sysctl_compact_memory,
		.maxlen		= sizeof(int),
		.mode		= 0200,
		.proc_handler	= sysctl_compaction_handler,
	},
	{
		.procname	= "compaction_proactiveness",
		.data		= &sysctl_compaction_proactiveness,
		.maxlen		= sizeof(sysctl_compaction_proactiveness),
		.mode		= 0644,
		.proc_handler	= compaction_proactiveness_sysctl_handler,
		.extra1		= SYSCTL_ZERO,
		.extra2		= SYSCTL_ONE_HUNDRED,
	},
	{
		.procname	= "extfrag_threshold",
		.data		= &sysctl_extfrag_threshold,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_minmax,
		.extra1		= SYSCTL_ZERO,
		.extra2		= SYSCTL_ONE_THOUSAND,
	},
	{
		.procname	= "compact_unevictable_allowed",
		.data		= &sysctl_compact_unevictable_allowed,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_minmax_warn_RT_change,
		.extra1		= SYSCTL_ZERO,
		.extra2		= SYSCTL_ONE,
	},
};

static int __init kcompactd_init(void)
{
	int nid;

	for_each_node_state(nid, N_MEMORY)
		kcompactd_run(nid);
	register_sysctl_init("vm", vm_compaction);
	return 0;
}
subsys_initcall(kcompactd_init)

#endif /* CONFIG_COMPACTION */
