From patchwork Wed Feb 21 09:27:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baolin Wang X-Patchwork-Id: 13565163 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 195EDC54788 for ; Wed, 21 Feb 2024 09:28:19 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id A25CE6B0087; Wed, 21 Feb 2024 04:28:18 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 9D36D6B0088; Wed, 21 Feb 2024 04:28:18 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 825D96B0089; Wed, 21 Feb 2024 04:28:18 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 6EB516B0087 for ; Wed, 21 Feb 2024 04:28:18 -0500 (EST) Received: from smtpin10.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id 452D21C0AB8 for ; Wed, 21 Feb 2024 09:28:18 +0000 (UTC) X-FDA: 81815285076.10.CC83F63 Received: from out30-97.freemail.mail.aliyun.com (out30-97.freemail.mail.aliyun.com [115.124.30.97]) by imf15.hostedemail.com (Postfix) with ESMTP id 29933A000F for ; Wed, 21 Feb 2024 09:28:14 +0000 (UTC) Authentication-Results: imf15.hostedemail.com; dkim=pass header.d=linux.alibaba.com header.s=default header.b=N8dnYYs4; dmarc=pass (policy=none) header.from=linux.alibaba.com; spf=pass (imf15.hostedemail.com: domain of baolin.wang@linux.alibaba.com designates 115.124.30.97 as permitted sender) smtp.mailfrom=baolin.wang@linux.alibaba.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1708507696; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=ImWD/LFam8uPK216oOawCtCWE3yiiD0csaC4SgFveA8=; b=kPxipEc/exao5rxwzTnnSUG5j5R9eaOwzI3PRW69Gba7sx4aperDyTC7XqTtwVFmP/pu8Y NE1fXQDYQvcFOIMKksQ3qXhqT6eXTnwzKyuVmSjuaticEduUEcRT7/sQj7Q+V4/kwbE+aQ OMAy/R9rKpLlQqiDsGdQTkjXV0512UE= ARC-Authentication-Results: i=1; imf15.hostedemail.com; dkim=pass header.d=linux.alibaba.com header.s=default header.b=N8dnYYs4; dmarc=pass (policy=none) header.from=linux.alibaba.com; spf=pass (imf15.hostedemail.com: domain of baolin.wang@linux.alibaba.com designates 115.124.30.97 as permitted sender) smtp.mailfrom=baolin.wang@linux.alibaba.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1708507696; a=rsa-sha256; cv=none; b=0/lrK+xgpEMUoBma4E5qmSIxGH/SKuVMShiCdmYVPp1zcBdWpp3lZsShbqJoc+/ihmagGW ye/FtuvsY33H3Ki/fqXqlCeVLinN/u3L9PUFwA6BZLX/3xOvvyKktI4PZqUyD2NSXF7N+G BTK7clnCKV7e5NcHFxmTpKUj6MsIQcw= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1708507686; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=ImWD/LFam8uPK216oOawCtCWE3yiiD0csaC4SgFveA8=; b=N8dnYYs4/RxkmL95EU9cddIr52GZltuM1MHI6/tbV4RPoxPXk9YywsZeJpvCq+yb+h+GRpBqbYGz0eOfRhOoOK4DZoYPDa3SlNqtFT0iQgtTOpcc2tV/1WQy7vIwK1QQ+b4NrsPOQ3rv4egKD2VaQ+Kdtn+92jFwoAlKI90t/iU= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R951e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046056;MF=baolin.wang@linux.alibaba.com;NM=1;PH=DS;RN=10;SR=0;TI=SMTPD_---0W0zUu6x_1708507684; Received: from localhost(mailfrom:baolin.wang@linux.alibaba.com fp:SMTPD_---0W0zUu6x_1708507684) by smtp.aliyun-inc.com; Wed, 21 Feb 2024 17:28:05 +0800 From: Baolin Wang To: akpm@linux-foundation.org Cc: muchun.song@linux.dev, osalvador@suse.de, david@redhat.com, linmiaohe@huawei.com, naoya.horiguchi@nec.com, mhocko@kernel.org, baolin.wang@linux.alibaba.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 2/3] mm: hugetlb: make the hugetlb migration strategy consistent Date: Wed, 21 Feb 2024 17:27:54 +0800 Message-Id: <0514e5139b17ecf3cd9e09d86c93e586c56688dc.1708507022.git.baolin.wang@linux.alibaba.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: References: MIME-Version: 1.0 X-Rspamd-Queue-Id: 29933A000F X-Rspam-User: X-Rspamd-Server: rspam02 X-Stat-Signature: 9qntack5go4u6eotuwbxsi48s4cd5b9j X-HE-Tag: 1708507694-758009 X-HE-Meta: U2FsdGVkX1/gIVF/7OAQlbKBI1Fc5yQk+0kr41cRIhRNYxRMr+LCmWsbIOdUEOi5NB0tOPDYjGMi+zKMg4sNMtGrEHd+ReP1kaKBXlWP9jbwyilJ2SasGtGvDBL3+uF3DV8P7DU1+1cH3mB61Q6JXg0LrO8FjZ9PS8xA8DWmvLtTlxcI9JnGVQv4Kmhe+APHMm7D9bh9QctEBqlRX3nbruAPwCsvd7anjTZYRw39soclNX5fj/jMsSLo36WS+vC/5aeUF4Zs6lgQtwCbcRKm5niK02CjqNGDPQGgsG+h3XnSGuava+fjCk/YYVRNowRROAmFpmxqhtQ58KUAgrMiINKYyc61rQB024GVBE6zR1F4x7n0/jQjk9LLRfIs0tlLmj6zRPJMF1O44w+HOb62X7aGXypFgC0jqG3irVZNVVZuecDubz4GASvDwF2bsBvQv6L/dr3XuJ0FRIi37rjVvEVIN8Zee6nHgILEa5vLScbuw28650cDVn/hgdHNkVRyJTn5WnSNQAhCia18TmBxmID+ciSffgjqJKQTnoIEorSwXcfHhj7kIl7tyZUpTrwbVgdarO/tzjUpAHDCx0hxwqfIscuxwx2p9AmWfoasHeBcAQ4g8d+ZUvRTwhmkPMzLJ6CZ0P4gnzu/flP9NbMqmrn/wqIh5a00dnwP4xhDS+0Gotw1kEpTw3tEc55t4rtFZZ06eclayQ8JuQWw9A++UQQM5clMP67/Ac8RSjygoV3xTD6pM3gEA6lPE9SA9iJhZvLt2YxYoEaNcCbGQGnBV8ziE63TJCA//CrZ4SHhfUH0BCqFPKBABBsP/GX5ilxuL+bGTDUlhoEtitah1PtT00awBA2N+z5/4HZYvrbNlOatYymx71dFDRhT+HpBRUQaPg5n5NSLkmX7+n7FaIJ1EUpF9p0wNnjY X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: As discussed in previous thread [1], there is an inconsistency when handing hugetlb migration. When handling the migration of freed hugetlb, it prevents fallback to other NUMA nodes in alloc_and_dissolve_hugetlb_folio(). However, when dealing with in-use hugetlb, it allows fallback to other NUMA nodes in alloc_hugetlb_folio_nodemask(), which can break the per-node hugetlb pool and might result in unexpected failures when node bound workloads doesn't get what is asssumed available. To make hugetlb migration strategy more clear, we should list all the scenarios of hugetlb migration and analyze whether allocation fallback is permitted: 1) Memory offline: will call dissolve_free_huge_pages() to free the freed hugetlb, and call do_migrate_range() to migrate the in-use hugetlb. Both can break the per-node hugetlb pool, but as this is an explicit offlining operation, no better choice. So should allow the hugetlb allocation fallback. 2) Memory failure: same as memory offline. Should allow fallback to a different node might be the only option to handle it, otherwise the impact of poisoned memory can be amplified. 3) Longterm pinning: will call migrate_longterm_unpinnable_pages() to migrate in-use and not-longterm-pinnable hugetlb, which can break the per-node pool. But we should fail to longterm pinning if can not allocate on current node to avoid breaking the per-node pool. 4) Syscalls (mbind, migrate_pages, move_pages): these are explicit users operation to move pages to other nodes, so fallback to other nodes should not be prohibited. 5) alloc_contig_range: used by CMA allocation and virtio-mem fake-offline to allocate given range of pages. Now the freed hugetlb migration is not allowed to fallback, to keep consistency, the in-use hugetlb migration should be also not allowed to fallback. 6) alloc_contig_pages: used by kfence, pgtable_debug etc. The strategy should be consistent with that of alloc_contig_range(). Based on the analysis of the various scenarios above, determine whether fallback is permitted according to the migration reason in alloc_hugetlb_folio_nodemask(). [1] https://lore.kernel.org/all/6f26ce22d2fcd523418a085f2c588fe0776d46e7.1706794035.git.baolin.wang@linux.alibaba.com/ Signed-off-by: Baolin Wang --- include/linux/hugetlb.h | 4 ++-- mm/hugetlb.c | 28 ++++++++++++++++++++++++++-- mm/mempolicy.c | 2 +- mm/migrate.c | 2 +- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 77b30a8c6076..fa122dc509cf 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -747,7 +747,7 @@ int isolate_or_dissolve_huge_page(struct page *page, struct list_head *list); struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma, unsigned long addr, int avoid_reserve); struct folio *alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid, - nodemask_t *nmask, gfp_t gfp_mask); + nodemask_t *nmask, gfp_t gfp_mask, int reason); int hugetlb_add_to_page_cache(struct folio *folio, struct address_space *mapping, pgoff_t idx); void restore_reserve_on_error(struct hstate *h, struct vm_area_struct *vma, @@ -1065,7 +1065,7 @@ static inline struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma, static inline struct folio * alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid, - nodemask_t *nmask, gfp_t gfp_mask) + nodemask_t *nmask, gfp_t gfp_mask, int reason) { return NULL; } diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 68283e54c899..a55cfc7844bc 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2621,8 +2621,10 @@ struct folio *alloc_buddy_hugetlb_folio_with_mpol(struct hstate *h, /* folio migration callback function */ struct folio *alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid, - nodemask_t *nmask, gfp_t gfp_mask) + nodemask_t *nmask, gfp_t gfp_mask, int reason) { + bool allowed_fallback = false; + spin_lock_irq(&hugetlb_lock); if (available_huge_pages(h)) { struct folio *folio; @@ -2636,6 +2638,28 @@ struct folio *alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid, } spin_unlock_irq(&hugetlb_lock); + if (gfp_mask & __GFP_THISNODE) + goto alloc_new; + + /* + * Note: the memory offline, memory failure and migration syscalls can break + * the per-node hugetlb pool. Other cases can not allocate new hugetlb on + * other nodes. + */ + switch (reason) { + case MR_MEMORY_HOTPLUG: + case MR_MEMORY_FAILURE: + case MR_SYSCALL: + case MR_MEMPOLICY_MBIND: + allowed_fallback = true; + break; + default: + break; + } + + if (!allowed_fallback) + gfp_mask |= __GFP_THISNODE; +alloc_new: return alloc_migrate_hugetlb_folio(h, gfp_mask, preferred_nid, nmask); } @@ -6666,7 +6690,7 @@ static struct folio *alloc_hugetlb_folio_vma(struct hstate *h, gfp_mask = htlb_alloc_mask(h); node = huge_node(vma, address, gfp_mask, &mpol, &nodemask); - folio = alloc_hugetlb_folio_nodemask(h, node, nodemask, gfp_mask); + folio = alloc_hugetlb_folio_nodemask(h, node, nodemask, gfp_mask, -1); mpol_cond_put(mpol); return folio; diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 98ceb12e0e17..436e817eeaeb 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1228,7 +1228,7 @@ static struct folio *alloc_migration_target_by_mpol(struct folio *src, h = folio_hstate(src); gfp = htlb_alloc_mask(h); nodemask = policy_nodemask(gfp, pol, ilx, &nid); - return alloc_hugetlb_folio_nodemask(h, nid, nodemask, gfp); + return alloc_hugetlb_folio_nodemask(h, nid, nodemask, gfp, MR_MEMPOLICY_MBIND); } if (folio_test_large(src)) diff --git a/mm/migrate.c b/mm/migrate.c index bde63010a3cf..0c2b70800da3 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -2022,7 +2022,7 @@ struct folio *alloc_migration_target(struct folio *src, unsigned long private) gfp_mask = htlb_modify_alloc_mask(h, gfp_mask); return alloc_hugetlb_folio_nodemask(h, nid, - mtc->nmask, gfp_mask); + mtc->nmask, gfp_mask, mtc->reason); } if (folio_test_large(src)) {