Skip to content

Commit 3eb2771

Browse files
tehcastertorvalds
authored andcommitted
mm, page_alloc: make THP-specific decisions more generic
Since THP allocations during page faults can be costly, extra decisions are employed for them to avoid excessive reclaim and compaction, if the initial compaction doesn't look promising. The detection has never been perfect as there is no gfp flag specific to THP allocations. At this moment it checks the whole combination of flags that makes up GFP_TRANSHUGE, and hopes that no other users of such combination exist, or would mind being treated the same way. Extra care is also taken to separate allocations from khugepaged, where latency doesn't matter that much. It is however possible to distinguish these allocations in a simpler and more reliable way. The key observation is that after the initial compaction followed by the first iteration of "standard" reclaim/compaction, both __GFP_NORETRY allocations and costly allocations without __GFP_REPEAT are declared as failures: /* Do not loop if specifically requested */ if (gfp_mask & __GFP_NORETRY) goto nopage; /* * Do not retry costly high order allocations unless they are * __GFP_REPEAT */ if (order > PAGE_ALLOC_COSTLY_ORDER && !(gfp_mask & __GFP_REPEAT)) goto nopage; This means we can further distinguish allocations that are costly order *and* additionally include the __GFP_NORETRY flag. As it happens, GFP_TRANSHUGE allocations do already fall into this category. This will also allow other costly allocations with similar high-order benefit vs latency considerations to use this semantic. Furthermore, we can distinguish THP allocations that should try a bit harder (such as from khugepageed) by removing __GFP_NORETRY, as will be done in the next patch. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Vlastimil Babka <[email protected]> Acked-by: Michal Hocko <[email protected]> Acked-by: Mel Gorman <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent a8161d1 commit 3eb2771

File tree

1 file changed

+9
-13
lines changed

1 file changed

+9
-13
lines changed

mm/page_alloc.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3085,7 +3085,6 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
30853085
return page;
30863086
}
30873087

3088-
30893088
/*
30903089
* Maximum number of compaction retries wit a progress before OOM
30913090
* killer is consider as the only way to move forward.
@@ -3373,11 +3372,6 @@ bool gfp_pfmemalloc_allowed(gfp_t gfp_mask)
33733372
return false;
33743373
}
33753374

3376-
static inline bool is_thp_gfp_mask(gfp_t gfp_mask)
3377-
{
3378-
return (gfp_mask & (GFP_TRANSHUGE | __GFP_KSWAPD_RECLAIM)) == GFP_TRANSHUGE;
3379-
}
3380-
33813375
/*
33823376
* Maximum number of reclaim retries without any progress before OOM killer
33833377
* is consider as the only way to move forward.
@@ -3536,8 +3530,11 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
35363530
if (page)
35373531
goto got_pg;
35383532

3539-
/* Checks for THP-specific high-order allocations */
3540-
if (is_thp_gfp_mask(gfp_mask)) {
3533+
/*
3534+
* Checks for costly allocations with __GFP_NORETRY, which
3535+
* includes THP page fault allocations
3536+
*/
3537+
if (gfp_mask & __GFP_NORETRY) {
35413538
/*
35423539
* If compaction is deferred for high-order allocations,
35433540
* it is because sync compaction recently failed. If
@@ -3557,11 +3554,10 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
35573554
goto nopage;
35583555

35593556
/*
3560-
* It can become very expensive to allocate transparent
3561-
* hugepages at fault, so use asynchronous memory
3562-
* compaction for THP unless it is khugepaged trying to
3563-
* collapse. All other requests should tolerate at
3564-
* least light sync migration.
3557+
* Looks like reclaim/compaction is worth trying, but
3558+
* sync compaction could be very expensive, so keep
3559+
* using async compaction, unless it's khugepaged
3560+
* trying to collapse.
35653561
*/
35663562
if (!(current->flags & PF_KTHREAD))
35673563
migration_mode = MIGRATE_ASYNC;

0 commit comments

Comments
 (0)