[PATCH] mm/mempolicy: speedup page alloc for MPOL_PREFERRED_MANY

From: Feng Tang
Date: Tue Mar 09 2021 - 23:31:24 EST


When doing broader test, we noticed allocation slowness in one test
case that malloc memory with size which is slightly bigger than free
memory of targeted nodes, but much less then the total free memory
of system.

The reason is the code enters the slowpath of __alloc_pages_nodemask(),
which takes quite some time.

Since alloc_pages_policy() will give it a 2nd try with NULL nodemask,
we tried solution which creates a new gfp_mask bit __GFP_NO_SLOWPATH
for explicitely skipping entering slowpath in the first try, which is
brutal and costs one precious gfp mask bit.

Based on discussion with Michal/Ben/Dave [1], only skip entering direct
reclaim while still allowing it to wakeup kswapd, which can fix the
slowness and make MPOL_PREFERRED_MANY more close to the semantic of
MPOL_PREFERRED, while avoid creating a new gfp bit.

[1]. https://lore.kernel.org/lkml/1614766858-90344-15-git-send-email-feng.tang@xxxxxxxxx/
Suggested-by: Michal Hocko <mhocko@xxxxxxxx>
Signed-off-by: Feng Tang <feng.tang@xxxxxxxxx>
---
mm/mempolicy.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index d66c1c0..00b19f7 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -2205,9 +2205,13 @@ static struct page *alloc_pages_policy(struct mempolicy *pol, gfp_t gfp,
* | MPOL_PREFERRED_MANY (round 2) | local | NULL |
* +-------------------------------+---------------+------------+
*/
- if (pol->mode == MPOL_PREFERRED_MANY)
+ if (pol->mode == MPOL_PREFERRED_MANY) {
gfp_mask |= __GFP_RETRY_MAYFAIL | __GFP_NOWARN;

+ /* Skip direct reclaim, as there will be a second try */
+ gfp_mask &= ~__GFP_DIRECT_RECLAIM;
+ }
+
page = __alloc_pages_nodemask(gfp_mask, order,
policy_node(gfp, pol, preferred_nid),
policy_nodemask(gfp, pol));
--
2.7.4