mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
mm: avoid livelock on !__GFP_FS allocations
Under the following conditions, __alloc_pages_slowpath can loop forever: gfp_mask & __GFP_WAIT is true gfp_mask & __GFP_FS is false reclaim and compaction make no progress order <= PAGE_ALLOC_COSTLY_ORDER The gfp conditions are normally invalid, because !__GFP_FS disables most of the reclaim methods that __GFP_WAIT would wait for. However, these conditions happen very often during suspend and resume, when pm_restrict_gfp_mask() effectively converts all GFP_KERNEL allocations into __GFP_WAIT. The oom killer is not run because gfp_mask & __GFP_FS is false, but should_alloc_retry will always return true when order is less than PAGE_ALLOC_COSTLY_ORDER. __alloc_pages_slowpath will loop forever between the rebalance label and should_alloc_retry, unless another thread happens to release enough pages to satisfy the allocation. Add a check to detect when PM has disabled __GFP_FS, and do not retry if reclaim is not making any progress. [taken from patch on lkml by Mel Gorman, commit message by ccross] Change-Id: I864a24e9d9fd98bd0e3d6e9c1e85b6c1b766850e Signed-off-by: Colin Cross <ccross@android.com>
This commit is contained in:
@@ -127,6 +127,20 @@ void pm_restrict_gfp_mask(void)
|
||||
saved_gfp_mask = gfp_allowed_mask;
|
||||
gfp_allowed_mask &= ~GFP_IOFS;
|
||||
}
|
||||
|
||||
static bool pm_suspending(void)
|
||||
{
|
||||
if ((gfp_allowed_mask & GFP_IOFS) == GFP_IOFS)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static bool pm_suspending(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
|
||||
@@ -2194,6 +2208,14 @@ rebalance:
|
||||
|
||||
goto restart;
|
||||
}
|
||||
|
||||
/*
|
||||
* Suspend converts GFP_KERNEL to __GFP_WAIT which can
|
||||
* prevent reclaim making forward progress without
|
||||
* invoking OOM. Bail if we are suspending
|
||||
*/
|
||||
if (pm_suspending())
|
||||
goto nopage;
|
||||
}
|
||||
|
||||
/* Check if we should retry the allocation */
|
||||
|
||||
Reference in New Issue
Block a user