Unverified Commit 7cdbedac authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!9286 mm, vmscan: prevent infinite loop for costly GFP_NOIO | __GFP_RETRY_MAYFAIL allocations

parents e823cbe2 942a759c
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -622,6 +622,15 @@ static inline bool pm_suspended_storage(void)
}
#endif /* CONFIG_PM_SLEEP */

/*
 * Check if the gfp flags allow compaction - GFP_NOIO is a really
 * tricky context because the migration might require IO.
 */
static inline bool gfp_compaction_allowed(gfp_t gfp_mask)
{
	return IS_ENABLED(CONFIG_COMPACTION) && (gfp_mask & __GFP_IO);
}

#if (defined(CONFIG_MEMORY_ISOLATION) && defined(CONFIG_COMPACTION)) || defined(CONFIG_CMA)
/* The below functions must be run on a range from a single zone. */
extern int alloc_contig_range(unsigned long start, unsigned long end,
+1 −6
Original line number Diff line number Diff line
@@ -1758,16 +1758,11 @@ 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)
{
	int may_perform_io = gfp_mask & __GFP_IO;
	struct zoneref *z;
	struct zone *zone;
	enum compact_result rc = COMPACT_SKIPPED;

	/*
	 * Check if the GFP flags allow compaction - GFP_NOIO is really
	 * tricky context because the migration might require IO
	 */
	if (!may_perform_io)
	if (!gfp_compaction_allowed(gfp_mask))
		return COMPACT_SKIPPED;

	trace_mm_compaction_try_to_compact_pages(order, gfp_mask, prio);
+6 −4
Original line number Diff line number Diff line
@@ -4366,6 +4366,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
						struct alloc_context *ac)
{
	bool can_direct_reclaim = gfp_mask & __GFP_DIRECT_RECLAIM;
	bool can_compact = gfp_compaction_allowed(gfp_mask);
	const bool costly_order = order > PAGE_ALLOC_COSTLY_ORDER;
	struct page *page = NULL;
	unsigned int alloc_flags;
@@ -4435,7 +4436,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
	 * Don't try this for allocations that are allowed to ignore
	 * watermarks, as the ALLOC_NO_WATERMARKS attempt didn't yet happen.
	 */
	if (can_direct_reclaim &&
	if (can_direct_reclaim && can_compact &&
			(costly_order ||
			   (order > 0 && ac->migratetype != MIGRATE_MOVABLE))
			&& !gfp_pfmemalloc_allowed(gfp_mask)) {
@@ -4522,9 +4523,10 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,

	/*
	 * Do not retry costly high order allocations unless they are
	 * __GFP_RETRY_MAYFAIL
	 * __GFP_RETRY_MAYFAIL and we can compact
	 */
	if (costly_order && !(gfp_mask & __GFP_RETRY_MAYFAIL))
	if (costly_order && (!can_compact ||
			     !(gfp_mask & __GFP_RETRY_MAYFAIL)))
		goto nopage;

	if (should_reclaim_retry(gfp_mask, order, ac, alloc_flags,
@@ -4537,7 +4539,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
	 * implementation of the compaction depends on the sufficient amount
	 * of free memory (see __compaction_suitable)
	 */
	if (did_some_progress > 0 &&
	if (did_some_progress > 0 && can_compact &&
			should_compact_retry(ac, order, alloc_flags,
				compact_result, &compact_priority,
				&compaction_retries))
+4 −1
Original line number Diff line number Diff line
@@ -2651,7 +2651,7 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc
/* Use reclaim/compaction for costly allocs or under memory pressure */
static bool in_reclaim_compaction(struct scan_control *sc)
{
	if (IS_ENABLED(CONFIG_COMPACTION) && sc->order &&
	if (gfp_compaction_allowed(sc->gfp_mask) && sc->order &&
			(sc->order > PAGE_ALLOC_COSTLY_ORDER ||
			 sc->priority < DEF_PRIORITY - 2))
		return true;
@@ -2913,6 +2913,9 @@ static inline bool compaction_ready(struct zone *zone, struct scan_control *sc)
	unsigned long watermark;
	enum compact_result suitable;

	if (!gfp_compaction_allowed(sc->gfp_mask))
		return false;

	suitable = compaction_suitable(zone, sc->order, 0, sc->reclaim_idx);
	if (suitable == COMPACT_SUCCESS)
		/* Allocation should succeed already. Don't reclaim. */