From: Kefeng Wang <wangkefeng.wang@huawei.com>
To: Andrew Morton <akpm@linux-foundation.org>,
David Hildenbrand <david@kernel.org>,
Oscar Salvador <osalvador@suse.de>,
Muchun Song <muchun.song@linux.dev>, <linux-mm@kvack.org>
Cc: <sidhartha.kumar@oracle.com>, <jane.chu@oracle.com>,
Zi Yan <ziy@nvidia.com>, Vlastimil Babka <vbabka@suse.cz>,
Brendan Jackman <jackmanb@google.com>,
Johannes Weiner <hannes@cmpxchg.org>,
Matthew Wilcox <willy@infradead.org>,
Kefeng Wang <wangkefeng.wang@huawei.com>
Subject: [PATCH v2 3/5] mm: hugetlb: optimize replace_free_hugepage_folios()
Date: Wed, 14 Jan 2026 21:55:12 +0800 [thread overview]
Message-ID: <20260114135512.2159799-1-wangkefeng.wang@huawei.com> (raw)
In-Reply-To: <20260112150954.1802953-4-wangkefeng.wang@huawei.com>
If no free hugepage folios are available, there is no need to perform
any replacement operations. Additionally, gigantic folios should not
be replaced under any circumstances. Therefore, we only check for the
presence of non-gigantic folios, also adding the gigantic folio check
to avoid accidental replacement.
To optimize performance, we skip unnecessary iterations over pfn
for compound pages and high-order buddy pages to save processing time.
A simple test on machine with 114G free memory, allocate 120 * 1G
HugeTLB folios(104 successfully returned),
time echo 120 > /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
Before: 0m0.602s
After: 0m0.431s
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
v2:
- Turn back to use alloc_and_dissolve_hugetlb_folio() since Oscar
pointed out that the return value is different. Then adding
gigantic folio check independently, also update changelog.
mm/hugetlb.c | 54 ++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 44 insertions(+), 10 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 8c197307db0c..e3c34718fc98 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2806,23 +2806,57 @@ int isolate_or_dissolve_huge_folio(struct folio *folio, struct list_head *list)
*/
int replace_free_hugepage_folios(unsigned long start_pfn, unsigned long end_pfn)
{
- struct folio *folio;
+ unsigned long nr = 0;
+ struct page *page;
+ struct hstate *h;
+ LIST_HEAD(list);
int ret = 0;
- LIST_HEAD(isolate_list);
+ /* Avoid pfn iterations if no free non-gigantic huge pages */
+ for_each_hstate(h) {
+ if (hstate_is_gigantic(h))
+ continue;
+
+ nr += h->free_huge_pages;
+ if (nr)
+ break;
+ }
+
+ if (!nr)
+ return 0;
while (start_pfn < end_pfn) {
- folio = pfn_folio(start_pfn);
+ page = pfn_to_page(start_pfn);
+ nr = 1;
- /* Not to disrupt normal path by vainly holding hugetlb_lock */
- if (folio_test_hugetlb(folio) && !folio_ref_count(folio)) {
- ret = alloc_and_dissolve_hugetlb_folio(folio, &isolate_list);
- if (ret)
- break;
+ if (PageHuge(page) || PageCompound(page)) {
+ struct folio *folio = page_folio(page);
+
+ nr = folio_nr_pages(folio) - folio_page_idx(folio, page);
+
+ /* Not to disrupt normal path by vainly holding hugetlb_lock */
+ if (folio_test_hugetlb(folio) && !folio_ref_count(folio)) {
+ if (order_is_gigantic(folio_order(folio)))
+ return -ENOMEM;
+
+ ret = alloc_and_dissolve_hugetlb_folio(folio, &list);
+ if (ret)
+ break;
+
+ putback_movable_pages(&list);
+ }
+ } else if (PageBuddy(page)) {
+ /*
+ * Buddy order check without zone lock is unsafe and
+ * the order is maybe invalid, but race should be
+ * small, and the worst thing is skipping free hugetlb.
+ */
+ const unsigned int order = buddy_order_unsafe(page);
- putback_movable_pages(&isolate_list);
+ if (order <= MAX_PAGE_ORDER)
+ nr = 1UL << order;
}
- start_pfn++;
+ start_pfn += nr;
}
return ret;
--
2.27.0
next prev parent reply other threads:[~2026-01-14 13:55 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-12 15:09 [PATCH mm-new resend 0/5] mm: accelerate gigantic folio allocation Kefeng Wang
2026-01-12 15:09 ` [PATCH 1/5] mm: page_isolation: introduce page_is_unmovable() Kefeng Wang
2026-01-12 16:36 ` Zi Yan
2026-01-13 4:37 ` Oscar Salvador
2026-01-12 15:09 ` [PATCH 2/5] mm: page_alloc: optimize pfn_range_valid_contig() Kefeng Wang
2026-01-12 17:02 ` Zi Yan
2026-01-13 1:24 ` Kefeng Wang
2026-01-13 1:27 ` Zi Yan
2026-01-13 9:55 ` Kefeng Wang
2026-01-14 1:47 ` Andrew Morton
2026-01-13 5:14 ` Oscar Salvador
2026-01-13 9:55 ` Kefeng Wang
2026-01-12 15:09 ` [PATCH 3/5] mm: hugetlb: optimize replace_free_hugepage_folios() Kefeng Wang
2026-01-13 5:27 ` Oscar Salvador
2026-01-13 11:38 ` Kefeng Wang
2026-01-14 13:55 ` Kefeng Wang [this message]
2026-01-12 15:09 ` [PATCH 4/5] mm: hugetlb_cma: optimize hugetlb_cma_alloc_frozen_folio() Kefeng Wang
2026-01-13 16:29 ` Zi Yan
2026-01-12 15:09 ` [PATCH 5/5] mm: hugetlb_cma: mark hugetlb_cma{_only} as __ro_after_init Kefeng Wang
2026-01-13 16:29 ` Zi Yan
2026-01-14 7:36 ` Muchun Song
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260114135512.2159799-1-wangkefeng.wang@huawei.com \
--to=wangkefeng.wang@huawei.com \
--cc=akpm@linux-foundation.org \
--cc=david@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=jackmanb@google.com \
--cc=jane.chu@oracle.com \
--cc=linux-mm@kvack.org \
--cc=muchun.song@linux.dev \
--cc=osalvador@suse.de \
--cc=sidhartha.kumar@oracle.com \
--cc=vbabka@suse.cz \
--cc=willy@infradead.org \
--cc=ziy@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox