From: Usama Arif <usama.arif@linux.dev>
To: Andrew Morton <akpm@linux-foundation.org>,
david@kernel.org, willy@infradead.org, ryan.roberts@arm.com,
linux-mm@kvack.org
Cc: r@hev.cc, jack@suse.cz,
Andrew Donnellan <andrew+kernel@donnellan.id.au>,
apopple@nvidia.com, baohua@kernel.org,
baolin.wang@linux.alibaba.com, brauner@kernel.org,
catalin.marinas@arm.com, dev.jain@arm.com, kees@kernel.org,
kevin.brodsky@arm.com, lance.yang@linux.dev,
Liam R. Howlett <liam@infradead.org>,
linux-arm-kernel@lists.infradead.org,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
ljs@kernel.org, mhocko@suse.com, npache@redhat.com,
pasha.tatashin@soleen.com, rmclure@linux.ibm.com,
rppt@kernel.org, surenb@google.com, vbabka@kernel.org,
Al Viro <viro@zeniv.linux.org.uk>,
wilts.infradead.org, linux-fsdevel@vger.kernel.l@kernel.org,
ziy@nvidia.com, hannes@cmpxchg.org, kas@kernel.org,
shakeel.butt@linux.dev, kernel-team@meta.com,
Usama Arif <usama.arif@linux.dev>
Subject: [PATCH v5 2/2] mm: use mapping_max_folio_order() for force_thp_readahead order
Date: Fri, 22 May 2026 09:23:48 -0700 [thread overview]
Message-ID: <20260522162422.3856502-3-usama.arif@linux.dev> (raw)
In-Reply-To: <20260522162422.3856502-1-usama.arif@linux.dev>
The force_thp_readahead path in do_sync_mmap_readahead() was gated on
the compile-time check HPAGE_PMD_ORDER <= MAX_PAGECACHE_ORDER and
always drove the readahead at HPAGE_PMD_ORDER / HPAGE_PMD_NR. On
configurations where HPAGE_PMD_ORDER exceeds MAX_PAGECACHE_ORDER --
notably arm64 with a 64K base page size, where HPAGE_PMD_ORDER is 13
(512MB) -- VM_HUGEPAGE mappings could never reach this path and fell
back to base-page readahead, even when the mapping itself could serve
usefully large folios well below the cap.
Widen the gate to
min(HPAGE_PMD_ORDER, mapping_max_folio_order(mapping))
<= MAX_PAGECACHE_ORDER
so force_thp_readahead engages whenever either order fits, and pick
ra->order accordingly:
- HPAGE_PMD_ORDER when it fits (existing behaviour);
- otherwise min(mapping_max_folio_order(mapping), get_order(SZ_2M)),
capping the readahead folio at 2MB regardless of what the mapping
advertises.
Size and align the readahead window from (1UL << ra->order) instead
of the hardcoded HPAGE_PMD_NR / HPAGE_PMD_ORDER so the chosen order
is honoured end-to-end.
On arm64 with a 64K base page size this lets VM_HUGEPAGE mappings get
large-folio readahead at the mapping's supported order (capped at
2MB) rather than dropping back to base pages. 2MB is also the size of
an arm64 contiguous-PTE (contpte) block on a 64K base, so the
resulting folios coalesce into a single TLB entry and reduce TLB
pressure on the readahead path.
Signed-off-by: Usama Arif <usama.arif@linux.dev>
---
mm/filemap.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c
index f45a1b74870d..56fa715d66cd 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -3317,9 +3317,16 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
ractl._max_index = vmf->vma->vm_pgoff + vma_pages(vmf->vma) - 1;
/* Use the readahead code, even if readahead is disabled */
- if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
- (vm_flags & VM_HUGEPAGE) && HPAGE_PMD_ORDER <= MAX_PAGECACHE_ORDER)
+ if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && (vm_flags & VM_HUGEPAGE) &&
+ min(HPAGE_PMD_ORDER, mapping_max_folio_order(mapping)) <= MAX_PAGECACHE_ORDER) {
force_thp_readahead = true;
+ if (HPAGE_PMD_ORDER <= MAX_PAGECACHE_ORDER)
+ ra->order = HPAGE_PMD_ORDER;
+ else
+ ra->order = min_t(unsigned int,
+ mapping_max_folio_order(mapping),
+ get_order(SZ_2M));
+ }
if (!force_thp_readahead) {
/*
@@ -3354,17 +3361,18 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
}
if (force_thp_readahead) {
+ unsigned long folio_nr_pages = 1UL << ra->order;
+
fpin = maybe_unlock_mmap_for_io(vmf, fpin);
- ractl._index &= ~((unsigned long)HPAGE_PMD_NR - 1);
- ra->size = HPAGE_PMD_NR;
+ ractl._index &= ~(folio_nr_pages - 1);
+ ra->size = folio_nr_pages;
/*
- * Fetch two PMD folios, so we get the chance to actually
+ * Fetch two folios so we get the chance to actually
* readahead, unless we've been told not to.
*/
if (!(vm_flags & VM_RAND_READ))
ra->size *= 2;
- ra->async_size = HPAGE_PMD_NR;
- ra->order = HPAGE_PMD_ORDER;
+ ra->async_size = folio_nr_pages;
page_cache_ra_order(&ractl, ra);
return fpin;
}
--
2.52.0
WARNING: multiple messages have this Message-ID (diff)
From: Usama Arif <usama.arif@linux.dev>
To: Andrew Morton <akpm@linux-foundation.org>,
david@kernel.org, willy@infradead.org, ryan.roberts@arm.com,
linux-mm@kvack.org
Cc: r@hev.cc, jack@suse.cz,
Andrew Donnellan <andrew+kernel@donnellan.id.au>,
apopple@nvidia.com, baohua@kernel.org,
baolin.wang@linux.alibaba.com, brauner@kernel.org,
catalin.marinas@arm.com, dev.jain@arm.com, kees@kernel.org,
kevin.brodsky@arm.com, lance.yang@linux.dev,
Liam R.Howlett <liam@infradead.org>,
linux-arm-kernel@lists.infradead.org,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
ljs@kernel.org, mhocko@suse.com, npache@redhat.com,
pasha.tatashin@soleen.com, rmclure@linux.ibm.com,
rppt@kernel.org, surenb@google.com, vbabka@kernel.org,
Al Viro <viro@zeniv.linux.org.uk>,
wilts.infradead.org@kvack.org,
"linux-fsdevel@vger.kernel.l"@kernel.org, ziy@nvidia.com,
hannes@cmpxchg.org, kas@kernel.org, shakeel.butt@linux.dev,
kernel-team@meta.com, Usama Arif <usama.arif@linux.dev>
Subject: [PATCH v5 2/2] mm: use mapping_max_folio_order() for force_thp_readahead order
Date: Fri, 22 May 2026 09:23:48 -0700 [thread overview]
Message-ID: <20260522162422.3856502-3-usama.arif@linux.dev> (raw)
In-Reply-To: <20260522162422.3856502-1-usama.arif@linux.dev>
The force_thp_readahead path in do_sync_mmap_readahead() was gated on
the compile-time check HPAGE_PMD_ORDER <= MAX_PAGECACHE_ORDER and
always drove the readahead at HPAGE_PMD_ORDER / HPAGE_PMD_NR. On
configurations where HPAGE_PMD_ORDER exceeds MAX_PAGECACHE_ORDER --
notably arm64 with a 64K base page size, where HPAGE_PMD_ORDER is 13
(512MB) -- VM_HUGEPAGE mappings could never reach this path and fell
back to base-page readahead, even when the mapping itself could serve
usefully large folios well below the cap.
Widen the gate to
min(HPAGE_PMD_ORDER, mapping_max_folio_order(mapping))
<= MAX_PAGECACHE_ORDER
so force_thp_readahead engages whenever either order fits, and pick
ra->order accordingly:
- HPAGE_PMD_ORDER when it fits (existing behaviour);
- otherwise min(mapping_max_folio_order(mapping), get_order(SZ_2M)),
capping the readahead folio at 2MB regardless of what the mapping
advertises.
Size and align the readahead window from (1UL << ra->order) instead
of the hardcoded HPAGE_PMD_NR / HPAGE_PMD_ORDER so the chosen order
is honoured end-to-end.
On arm64 with a 64K base page size this lets VM_HUGEPAGE mappings get
large-folio readahead at the mapping's supported order (capped at
2MB) rather than dropping back to base pages. 2MB is also the size of
an arm64 contiguous-PTE (contpte) block on a 64K base, so the
resulting folios coalesce into a single TLB entry and reduce TLB
pressure on the readahead path.
Signed-off-by: Usama Arif <usama.arif@linux.dev>
---
mm/filemap.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c
index f45a1b74870d..56fa715d66cd 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -3317,9 +3317,16 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
ractl._max_index = vmf->vma->vm_pgoff + vma_pages(vmf->vma) - 1;
/* Use the readahead code, even if readahead is disabled */
- if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
- (vm_flags & VM_HUGEPAGE) && HPAGE_PMD_ORDER <= MAX_PAGECACHE_ORDER)
+ if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && (vm_flags & VM_HUGEPAGE) &&
+ min(HPAGE_PMD_ORDER, mapping_max_folio_order(mapping)) <= MAX_PAGECACHE_ORDER) {
force_thp_readahead = true;
+ if (HPAGE_PMD_ORDER <= MAX_PAGECACHE_ORDER)
+ ra->order = HPAGE_PMD_ORDER;
+ else
+ ra->order = min_t(unsigned int,
+ mapping_max_folio_order(mapping),
+ get_order(SZ_2M));
+ }
if (!force_thp_readahead) {
/*
@@ -3354,17 +3361,18 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
}
if (force_thp_readahead) {
+ unsigned long folio_nr_pages = 1UL << ra->order;
+
fpin = maybe_unlock_mmap_for_io(vmf, fpin);
- ractl._index &= ~((unsigned long)HPAGE_PMD_NR - 1);
- ra->size = HPAGE_PMD_NR;
+ ractl._index &= ~(folio_nr_pages - 1);
+ ra->size = folio_nr_pages;
/*
- * Fetch two PMD folios, so we get the chance to actually
+ * Fetch two folios so we get the chance to actually
* readahead, unless we've been told not to.
*/
if (!(vm_flags & VM_RAND_READ))
ra->size *= 2;
- ra->async_size = HPAGE_PMD_NR;
- ra->order = HPAGE_PMD_ORDER;
+ ra->async_size = folio_nr_pages;
page_cache_ra_order(&ractl, ra);
return fpin;
}
--
2.52.0
next prev parent reply other threads:[~2026-05-22 16:24 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-22 16:23 [PATCH v5 0/2] mm: improve large folio readahead for exec memory Usama Arif
2026-05-22 16:23 ` Usama Arif
2026-05-22 16:23 ` [PATCH v5 1/2] mm: bypass mmap_miss heuristic for VM_EXEC readahead Usama Arif
2026-05-22 16:23 ` Usama Arif
2026-05-22 16:23 ` Usama Arif [this message]
2026-05-22 16:23 ` [PATCH v5 2/2] mm: use mapping_max_folio_order() for force_thp_readahead order Usama Arif
2026-05-22 19:20 ` [PATCH v5 0/2] mm: improve large folio readahead for exec memory Andrew Morton
2026-05-25 15:01 ` Usama Arif
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=20260522162422.3856502-3-usama.arif@linux.dev \
--to=usama.arif@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=andrew+kernel@donnellan.id.au \
--cc=apopple@nvidia.com \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=brauner@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=jack@suse.cz \
--cc=kees@kernel.org \
--cc=kevin.brodsky@arm.com \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-fsdevel@vger.kernel.l \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=npache@redhat.com \
--cc=pasha.tatashin@soleen.com \
--cc=r@hev.cc \
--cc=rmclure@linux.ibm.com \
--cc=rppt@kernel.org \
--cc=ryan.roberts@arm.com \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
--cc=viro@zeniv.linux.org.uk \
--cc=willy@infradead.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.