Skip to contentSkip to conversation

mm: improve large folio readahead and alignment for exec memory

PATCH Superseded Usama Arif 5 participants 17 messages Apr 2 – Apr 13

Subsystems (7)
Memory management VFS MM core arm64 +3 more subsystems

v3 of 7 Superseded Latest is v7 →

lore
Share & tools
lore

Usama Arif

author reviewer
#0 lore raw

v3 cover mm: improve large folio readahead and alignment for exec memory

v2 -> v3: https://lore.kernel.org/all/[email protected]/
- Take into account READ_ONLY_THP_FOR_FS for elf alignment by aligning to HPAGE_PMD_SIZE limited to 2M (Rui)
- Reviewed-by tags for patch 1 from Kiryl and Jan
- Remove preferred_exec_order() (Jan)
- Change ra->order to HPAGE_PMD_ORDER if vma_pages(vma) >= HPAGE_PMD_NR otherwise use exec_folio_order() with gfp &= ~__GFP_RECLAIM for do_sync_mmap_readahead().
- Change exec_folio_order() to return 2M (cont-pte size) for 64K base page size for arm64.
- remove bprm->file NULL check (Matthew)
- Change filp to file (Matthew)
- Improve checking of p_vaddr and p_vaddr (Rui and Matthew)

v1 -> v2: https://lore.kernel.org/all/[email protected]/
- disable mmap_miss logic for VM_EXEC (Jan Kara)
- Align in elf only when segment VA and file offset are already aligned (Rui)
- preferred_exec_order() for VM_EXEC sync mmap_readahead which takes into account zone high watermarks (as an approximation of memory pressure) (David, or atleast my approach to what David suggested in [1] :))
- Extend max alignment to mapping_max_folio_size() instead of exec_folio_order()

Motiviation
===========
exec_folio_order() was introduced [2] to request readahead at an arch-preferred folio order for executable memory, enabling hardware PTE coalescing (e.g. arm64 contpte) and PMD mappings on the fault path.

However, several things prevent this from working optimally:

1. The mmap_miss heuristic in do_sync_mmap_readahead() silently disables exec readahead after 100 page faults. The mmap_miss counter tracks whether readahead is useful for mmap'd file access:

- Incremented by 1 in do_sync_mmap_readahead() on every page cache miss (page needed IO).

- Decremented by N in filemap_map_pages() for N pages successfully mapped via fault-around (pages found in cache without faulting, evidence that readahead was useful). Only non-workingset pages count and recently evicted and re-read pages don't count as hits.

- Decremented by 1 in do_async_mmap_readahead() when a PG_readahead marker page is found (indicates sequential consumption of readahead pages).

When mmap_miss exceeds MMAP_LOTSAMISS (100), all readahead is disabled. On arm64 with 64K pages, both decrement paths are inactive:

- filemap_map_pages() is never called because fault_around_pages (65536 >> PAGE_SHIFT = 1) disables should_fault_around(), which requires fault_around_pages > 1. With only 1 page in the fault-around window, there is nothing "around" to map.

- do_async_mmap_readahead() never fires for exec mappings because exec readahead sets async_size = 0, so no PG_readahead markers are placed.

With no decrements, mmap_miss monotonically increases past MMAP_LOTSAMISS after 100 faults, disabling exec readahead for the remainder of the mapping. Patch 1 fixes this by excluding VM_EXEC VMAs from the mmap_miss logic, similar to how VM_SEQ_READ is already excluded.

2. exec_folio_order() is an arch-specific hook that returns a static order (ilog2(SZ_64K >> PAGE_SHIFT)), which is suboptimal for non-4K page sizes. Patch 2 updates the arm64 exec_folio_order() to return 2M on 64K page configurations (for contpte coalescing, where the previous SZ_64K value collapsed to order 0) and uses a tiered allocation strategy in do_sync_mmap_readahead(): if the VMA is large enough for a full PMD, request HPAGE_PMD_ORDER so the folio can be PMD-mapped; otherwise fall back to exec_folio_order() for hardware PTE coalescing. The allocation uses ~__GFP_RECLAIM so it is opportunistic, falling back to smaller folios without stalling on reclaim or compaction.

3. Even with correct folio order and readahead, hardware PTE coalescing (e.g. contpte) and PMD mapping require the virtual address to be aligned to the folio size. The readahead path aligns file offsets and the buddy allocator aligns physical memory, but the virtual address depends on the VMA start. For PIE binaries, ASLR randomizes the load address at PAGE_SIZE granularity, so on arm64 with 64K pages only 1/32 of load addresses are 2M-aligned. When misaligned, contpte cannot be used for any folio in the VMA.

Patch 3 fixes this for the main binary by extending maximum_alignment() in the ELF loader with a folio_alignment() helper that tries two tiers matching the readahead strategy: first HPAGE_PMD_SIZE for PMD mapping, then exec_folio_order() as a fallback for hardware TLB coalescing. The alignment is capped to the segment size to avoid reducing ASLR entropy for small binaries.

Patch 4 fixes this for shared libraries by adding an exec_folio_order() alignment fallback in thp_get_unmapped_area_vmflags(). The existing PMD_SIZE alignment (512M on arm64 64K pages) is too large for typical shared libraries, so this smaller fallback succeeds where PMD fails.

I created a benchmark that mmaps a large executable file and calls RET-stub functions at PAGE_SIZE offsets across it. "Cold" measures fault + readahead cost. "Random" first faults in all pages with a sequential sweep (not measured), then measures time for calling random offsets, isolating iTLB miss cost for scattered execution.

The benchmark results on Neoverse V2 (Grace), arm64 with 64K base pages, 512MB executable file on ext4, averaged over 3 runs:

  Phase      | Baseline     | Patched      | Improvement
  -----------|--------------|--------------|------------------
  Cold fault | 83.4 ms      | 41.3 ms      | 50% faster
  Random     | 76.0 ms      | 58.3 ms      | 23% faster

[1] https://lore.kernel.org/all/[email protected]/
[2] https://lore.kernel.org/all/[email protected]/

Usama Arif (4):
mm: bypass mmap_miss heuristic for VM_EXEC readahead
mm: use tiered folio allocation for VM_EXEC readahead
elf: align ET_DYN base for PTE coalescing and PMD mapping
mm: align file-backed mmap to exec folio order in
thp_get_unmapped_area

 arch/arm64/include/asm/pgtable.h | 16 ++++++----
 fs/binfmt_elf.c                  | 50 ++++++++++++++++++++++++++++++++
 mm/filemap.c                     | 42 +++++++++++++++++++--------
 mm/huge_memory.c                 | 13 +++++++++
 mm/internal.h                    |  3 +-
 mm/readahead.c                   |  7 ++---
 6 files changed, 109 insertions(+), 22 deletions(-)
Signature · 1 line
2.52.0
author reviewer
#1 lore raw

PATCH v3 1/4 mm: bypass mmap_miss heuristic for VM_EXEC readahead

The mmap_miss counter in do_sync_mmap_readahead() tracks whether readahead is useful for mmap'd file access. It is incremented by 1 on every page cache miss in do_sync_mmap_readahead(), and decremented in two places:

- filemap_map_pages(): decremented by N for each of N pages successfully mapped via fault-around (pages found already in cache, evidence readahead was useful). Only pages not in the workingset count as hits.

- do_async_mmap_readahead(): decremented by 1 when a page with PG_readahead is found in cache.

When the counter exceeds MMAP_LOTSAMISS (100), all readahead is disabled, including the targeted VM_EXEC readahead [1] that requests large folio orders for contpte mapping.

On arm64 with 64K base pages, both decrement paths are inactive:

1. filemap_map_pages() is never called because fault_around_pages (65536 >> PAGE_SHIFT = 1) disables should_fault_around(), which requires fault_around_pages > 1. With only 1 page in the fault-around window, there is nothing "around" to map.

2. do_async_mmap_readahead() never fires for exec mappings because exec readahead sets async_size = 0, so no PG_readahead markers are placed.

With no decrements, mmap_miss monotonically increases past MMAP_LOTSAMISS after 100 page faults, disabling all subsequent exec readahead.

Fix this by excluding VM_EXEC VMAs from the mmap_miss logic, similar to how VM_SEQ_READ is already excluded. The exec readahead path is targeted (one folio at the fault location, async_size=0), not speculative prefetch, so the mmap_miss heuristic designed to throttle wasteful speculative readahead should not apply to it.

[1] https://lore.kernel.org/all/[email protected]/

---
 mm/filemap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
mm/filemap.c +1 -1
index 2b933a1da9bd..a4ea869b2ca1 100644
@@ -3337,7 +3337,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 		}
 	}
 
-	if (!(vm_flags & VM_SEQ_READ)) {
+	if (!(vm_flags & (VM_SEQ_READ | VM_EXEC))) {
 		/* Avoid banging the cache line if not needed */
 		mmap_miss = READ_ONCE(ra->mmap_miss);
 		if (mmap_miss < MMAP_LOTSAMISS * 10)
Signature · 1 line
2.52.0
author reviewer
#2 lore raw

PATCH v3 2/4 mm: use tiered folio allocation for VM_EXEC readahead

In reply to Usama Arif

When executable pages are faulted via do_sync_mmap_readahead(), request a folio order that enables the best hardware TLB coalescing available:

- If the VMA is large enough to contain a full PMD, request HPAGE_PMD_ORDER so the folio can be PMD-mapped. This benefits architectures where PMD_SIZE is reasonable (e.g. 2M on x86-64 and arm64 with 4K pages). VM_EXEC VMAs are very unlikely to be large enough for 512M pages on ARM to take into affect.

- Otherwise, fall back to exec_folio_order(), which returns the minimum order for hardware PTE coalescing for arm64:
- arm64 4K: order 4 (64K) for contpte (16 PTEs → 1 iTLB entry)
- arm64 16K: order 2 (64K) for HPA (4 pages → 1 TLB entry)
- arm64 64K: order 5 (2M) for contpte (32 PTEs → 1 iTLB entry)
- generic: order 0 (no coalescing)

Update the arm64 exec_folio_order() to return ilog2(SZ_2M >> PAGE_SHIFT) on 64K page configurations, where the previous SZ_64K value collapsed to order 0 (a single page) and provided no coalescing benefit.

Use ~__GFP_RECLAIM so the allocation is opportunistic: if a large folio is readily available, use it, otherwise fall back to smaller folios without stalling on reclaim or compaction. The existing fallback in page_cache_ra_order() handles this naturally.

The readahead window is already clamped to the VMA boundaries, so ra->size naturally caps the folio order via ilog2(ra->size) in page_cache_ra_order().

---
 arch/arm64/include/asm/pgtable.h | 16 +++++++++----
 mm/filemap.c                     | 40 +++++++++++++++++++++++---------
 mm/internal.h                    |  3 ++-
 mm/readahead.c                   |  7 +++---
 4 files changed, 45 insertions(+), 21 deletions(-)
arch/arm64/include/asm/pgtable.h +11 -5
index 52bafe79c10a..9ce9f73a6f35 100644
@@ -1591,12 +1591,18 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
 #define arch_wants_old_prefaulted_pte	cpu_has_hw_af
 
 /*
- * Request exec memory is read into pagecache in at least 64K folios. This size
- * can be contpte-mapped when 4K base pages are in use (16 pages into 1 iTLB
- * entry), and HPA can coalesce it (4 pages into 1 TLB entry) when 16K base
- * pages are in use.
+ * Request exec memory is read into pagecache in folios large enough for
+ * hardware TLB coalescing. On 4K and 16K page configs this is 64K, which
+ * enables contpte mapping (16 × 4K) and HPA coalescing (4 × 16K). On
+ * 64K page configs, contpte requires 2M (32 × 64K).
  */
-#define exec_folio_order() ilog2(SZ_64K >> PAGE_SHIFT)
+#define exec_folio_order exec_folio_order
+static inline unsigned int exec_folio_order(void)
+{
+	if (PAGE_SIZE == SZ_64K)
+		return ilog2(SZ_2M >> PAGE_SHIFT);
+	return ilog2(SZ_64K >> PAGE_SHIFT);
+}
 
 static inline bool pud_sect_supported(void)
 {
mm/filemap.c +29 -11
index a4ea869b2ca1..7ffea986b3b4 100644
@@ -3311,6 +3311,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 	DEFINE_READAHEAD(ractl, file, ra, mapping, vmf->pgoff);
 	struct file *fpin = NULL;
 	vm_flags_t vm_flags = vmf->vma->vm_flags;
+	gfp_t gfp = readahead_gfp_mask(mapping);
 	bool force_thp_readahead = false;
 	unsigned short mmap_miss;
 
@@ -3363,28 +3364,45 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 			ra->size *= 2;
 		ra->async_size = HPAGE_PMD_NR;
 		ra->order = HPAGE_PMD_ORDER;
-		page_cache_ra_order(&ractl, ra);
+		page_cache_ra_order(&ractl, ra, gfp);
 		return fpin;
 	}
 
 	if (vm_flags & VM_EXEC) {
 		/*
-		 * Allow arch to request a preferred minimum folio order for
-		 * executable memory. This can often be beneficial to
-		 * performance if (e.g.) arm64 can contpte-map the folio.
-		 * Executable memory rarely benefits from readahead, due to its
-		 * random access nature, so set async_size to 0.
+		 * Request large folios for executable memory to enable
+		 * hardware PTE coalescing and PMD mappings:
 		 *
-		 * Limit to the boundaries of the VMA to avoid reading in any
-		 * pad that might exist between sections, which would be a waste
-		 * of memory.
+		 *  - If the VMA is large enough for a PMD, request
+		 *    HPAGE_PMD_ORDER so the folio can be PMD-mapped.
+		 *  - Otherwise, use exec_folio_order() which returns
+		 *    the minimum order for hardware TLB coalescing
+		 *    (e.g. arm64 contpte/HPA).
+		 *
+		 * Use ~__GFP_RECLAIM so large folio allocation is
+		 * opportunistic — if memory isn't readily available,
+		 * fall back to smaller folios rather than stalling on
+		 * reclaim or compaction.
+		 *
+		 * Executable memory rarely benefits from speculative
+		 * readahead due to its random access nature, so set
+		 * async_size to 0.
+		 *
+		 * Limit to the boundaries of the VMA to avoid reading
+		 * in any pad that might exist between sections, which
+		 * would be a waste of memory.
 		 */
+		gfp &= ~__GFP_RECLAIM;
 		struct vm_area_struct *vma = vmf->vma;
 		unsigned long start = vma->vm_pgoff;
 		unsigned long end = start + vma_pages(vma);
 		unsigned long ra_end;
 
-		ra->order = exec_folio_order();
+		if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
+		    vma_pages(vma) >= HPAGE_PMD_NR)
+			ra->order = HPAGE_PMD_ORDER;
+		else
+			ra->order = exec_folio_order();
 		ra->start = round_down(vmf->pgoff, 1UL << ra->order);
 		ra->start = max(ra->start, start);
 		ra_end = round_up(ra->start + ra->ra_pages, 1UL << ra->order);
@@ -3403,7 +3421,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 
 	fpin = maybe_unlock_mmap_for_io(vmf, fpin);
 	ractl._index = ra->start;
-	page_cache_ra_order(&ractl, ra);
+	page_cache_ra_order(&ractl, ra, gfp);
 	return fpin;
 }
 
mm/internal.h +2 -1
index 475bd281a10d..e624cb619057 100644
@@ -545,7 +545,8 @@ int zap_vma_for_reaping(struct vm_area_struct *vma);
 int folio_unmap_invalidate(struct address_space *mapping, struct folio *folio,
 			   gfp_t gfp);
 
-void page_cache_ra_order(struct readahead_control *, struct file_ra_state *);
+void page_cache_ra_order(struct readahead_control *, struct file_ra_state *,
+			 gfp_t gfp);
 void force_page_cache_ra(struct readahead_control *, unsigned long nr);
 static inline void force_page_cache_readahead(struct address_space *mapping,
 		struct file *file, pgoff_t index, unsigned long nr_to_read)
mm/readahead.c +3 -4
index 7b05082c89ea..b3dc08cf180c 100644
@@ -465,7 +465,7 @@ static inline int ra_alloc_folio(struct readahead_control *ractl, pgoff_t index,
 }
 
 void page_cache_ra_order(struct readahead_control *ractl,
-		struct file_ra_state *ra)
+		struct file_ra_state *ra, gfp_t gfp)
 {
 	struct address_space *mapping = ractl->mapping;
 	pgoff_t start = readahead_index(ractl);
@@ -475,7 +475,6 @@ void page_cache_ra_order(struct readahead_control *ractl,
 	pgoff_t mark = index + ra->size - ra->async_size;
 	unsigned int nofs;
 	int err = 0;
-	gfp_t gfp = readahead_gfp_mask(mapping);
 	unsigned int new_order = ra->order;
 
 	trace_page_cache_ra_order(mapping->host, start, ra);
@@ -626,7 +625,7 @@ void page_cache_sync_ra(struct readahead_control *ractl,
 readit:
 	ra->order = 0;
 	ractl->_index = ra->start;
-	page_cache_ra_order(ractl, ra);
+	page_cache_ra_order(ractl, ra, readahead_gfp_mask(ractl->mapping));
 }
 EXPORT_SYMBOL_GPL(page_cache_sync_ra);
 
@@ -697,7 +696,7 @@ void page_cache_async_ra(struct readahead_control *ractl,
 		ra->size -= end - aligned_end;
 	ra->async_size = ra->size;
 	ractl->_index = ra->start;
-	page_cache_ra_order(ractl, ra);
+	page_cache_ra_order(ractl, ra, readahead_gfp_mask(ractl->mapping));
 }
 EXPORT_SYMBOL_GPL(page_cache_async_ra);
 
Signature · 1 line
2.52.0
maintainer
#3 lore raw

Re: [PATCH v3 2/4] mm: use tiered folio allocation for VM_EXEC readahead

Quoted 8 lines · Usama Arif

When executable pages are faulted via do_sync_mmap_readahead(), request a folio order that enables the best hardware TLB coalescing available:

- If the VMA is large enough to contain a full PMD, request HPAGE_PMD_ORDER so the folio can be PMD-mapped. This benefits architectures where PMD_SIZE is reasonable (e.g. 2M on x86-64 and arm64 with 4K pages). VM_EXEC VMAs are very unlikely to be large enough for 512M pages on ARM to take into affect.

I'm not sure relying on PMD_SIZE will be too much for a VMA is a great strategy. With 16k PAGE_SIZE the PMD would be 32MB large which would fit in the .text size but already looks a bit too much? Mapping with PMD sized folios brings some benefits but at the same time it costs because now parts of VMA that would be never paged in are pulled into memory and also LRU tracking now happens with this very large granularity making it fairly inefficient (big folios have much higher chances of getting accessed similarly often making LRU order mostly random). We are already getting reports of people with small machines (phones etc.) where the memory overhead of large folios (in the page cache) is simply too much. So I'd have a bigger peace of mind if we capped folio size at 2MB for now until we come with a more sophisticated heuristic of picking sensible folio order given the machine size. Now I'm not really an MM person so my feeling here may be just wrong but I wanted to voice this concern from what I can see...

Honza

Quoted 190 lines

- Otherwise, fall back to exec_folio_order(), which returns the minimum order for hardware PTE coalescing for arm64:
- arm64 4K: order 4 (64K) for contpte (16 PTEs → 1 iTLB entry)
- arm64 16K: order 2 (64K) for HPA (4 pages → 1 TLB entry)
- arm64 64K: order 5 (2M) for contpte (32 PTEs → 1 iTLB entry)
- generic: order 0 (no coalescing)

Update the arm64 exec_folio_order() to return ilog2(SZ_2M >> PAGE_SHIFT) on 64K page configurations, where the previous SZ_64K value collapsed to order 0 (a single page) and provided no coalescing benefit.

Use ~__GFP_RECLAIM so the allocation is opportunistic: if a large folio is readily available, use it, otherwise fall back to smaller folios without stalling on reclaim or compaction. The existing fallback in page_cache_ra_order() handles this naturally.

The readahead window is already clamped to the VMA boundaries, so ra->size naturally caps the folio order via ilog2(ra->size) in page_cache_ra_order().

---
 arch/arm64/include/asm/pgtable.h | 16 +++++++++----
 mm/filemap.c                     | 40 +++++++++++++++++++++++---------
 mm/internal.h                    |  3 ++-
 mm/readahead.c                   |  7 +++---
 4 files changed, 45 insertions(+), 21 deletions(-)
arch/arm64/include/asm/pgtable.h +11 -5
index 52bafe79c10a..9ce9f73a6f35 100644
@@ -1591,12 +1591,18 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
 #define arch_wants_old_prefaulted_pte	cpu_has_hw_af
 
 /*
- * Request exec memory is read into pagecache in at least 64K folios. This size
- * can be contpte-mapped when 4K base pages are in use (16 pages into 1 iTLB
- * entry), and HPA can coalesce it (4 pages into 1 TLB entry) when 16K base
- * pages are in use.
+ * Request exec memory is read into pagecache in folios large enough for
+ * hardware TLB coalescing. On 4K and 16K page configs this is 64K, which
+ * enables contpte mapping (16 × 4K) and HPA coalescing (4 × 16K). On
+ * 64K page configs, contpte requires 2M (32 × 64K).
  */
-#define exec_folio_order() ilog2(SZ_64K >> PAGE_SHIFT)
+#define exec_folio_order exec_folio_order
+static inline unsigned int exec_folio_order(void)
+{
+	if (PAGE_SIZE == SZ_64K)
+		return ilog2(SZ_2M >> PAGE_SHIFT);
+	return ilog2(SZ_64K >> PAGE_SHIFT);
+}
 
 static inline bool pud_sect_supported(void)
 {
mm/filemap.c +29 -11
index a4ea869b2ca1..7ffea986b3b4 100644
@@ -3311,6 +3311,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 	DEFINE_READAHEAD(ractl, file, ra, mapping, vmf->pgoff);
 	struct file *fpin = NULL;
 	vm_flags_t vm_flags = vmf->vma->vm_flags;
+	gfp_t gfp = readahead_gfp_mask(mapping);
 	bool force_thp_readahead = false;
 	unsigned short mmap_miss;
 
@@ -3363,28 +3364,45 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 			ra->size *= 2;
 		ra->async_size = HPAGE_PMD_NR;
 		ra->order = HPAGE_PMD_ORDER;
-		page_cache_ra_order(&ractl, ra);
+		page_cache_ra_order(&ractl, ra, gfp);
 		return fpin;
 	}
 
 	if (vm_flags & VM_EXEC) {
 		/*
-		 * Allow arch to request a preferred minimum folio order for
-		 * executable memory. This can often be beneficial to
-		 * performance if (e.g.) arm64 can contpte-map the folio.
-		 * Executable memory rarely benefits from readahead, due to its
-		 * random access nature, so set async_size to 0.
+		 * Request large folios for executable memory to enable
+		 * hardware PTE coalescing and PMD mappings:
 		 *
-		 * Limit to the boundaries of the VMA to avoid reading in any
-		 * pad that might exist between sections, which would be a waste
-		 * of memory.
+		 *  - If the VMA is large enough for a PMD, request
+		 *    HPAGE_PMD_ORDER so the folio can be PMD-mapped.
+		 *  - Otherwise, use exec_folio_order() which returns
+		 *    the minimum order for hardware TLB coalescing
+		 *    (e.g. arm64 contpte/HPA).
+		 *
+		 * Use ~__GFP_RECLAIM so large folio allocation is
+		 * opportunistic — if memory isn't readily available,
+		 * fall back to smaller folios rather than stalling on
+		 * reclaim or compaction.
+		 *
+		 * Executable memory rarely benefits from speculative
+		 * readahead due to its random access nature, so set
+		 * async_size to 0.
+		 *
+		 * Limit to the boundaries of the VMA to avoid reading
+		 * in any pad that might exist between sections, which
+		 * would be a waste of memory.
 		 */
+		gfp &= ~__GFP_RECLAIM;
 		struct vm_area_struct *vma = vmf->vma;
 		unsigned long start = vma->vm_pgoff;
 		unsigned long end = start + vma_pages(vma);
 		unsigned long ra_end;
 
-		ra->order = exec_folio_order();
+		if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
+		    vma_pages(vma) >= HPAGE_PMD_NR)
+			ra->order = HPAGE_PMD_ORDER;
+		else
+			ra->order = exec_folio_order();
 		ra->start = round_down(vmf->pgoff, 1UL << ra->order);
 		ra->start = max(ra->start, start);
 		ra_end = round_up(ra->start + ra->ra_pages, 1UL << ra->order);
@@ -3403,7 +3421,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 
 	fpin = maybe_unlock_mmap_for_io(vmf, fpin);
 	ractl._index = ra->start;
-	page_cache_ra_order(&ractl, ra);
+	page_cache_ra_order(&ractl, ra, gfp);
 	return fpin;
 }
 
mm/internal.h +2 -1
index 475bd281a10d..e624cb619057 100644
@@ -545,7 +545,8 @@ int zap_vma_for_reaping(struct vm_area_struct *vma);
 int folio_unmap_invalidate(struct address_space *mapping, struct folio *folio,
 			   gfp_t gfp);
 
-void page_cache_ra_order(struct readahead_control *, struct file_ra_state *);
+void page_cache_ra_order(struct readahead_control *, struct file_ra_state *,
+			 gfp_t gfp);
 void force_page_cache_ra(struct readahead_control *, unsigned long nr);
 static inline void force_page_cache_readahead(struct address_space *mapping,
 		struct file *file, pgoff_t index, unsigned long nr_to_read)
mm/readahead.c +3 -4
index 7b05082c89ea..b3dc08cf180c 100644
@@ -465,7 +465,7 @@ static inline int ra_alloc_folio(struct readahead_control *ractl, pgoff_t index,
 }
 
 void page_cache_ra_order(struct readahead_control *ractl,
-		struct file_ra_state *ra)
+		struct file_ra_state *ra, gfp_t gfp)
 {
 	struct address_space *mapping = ractl->mapping;
 	pgoff_t start = readahead_index(ractl);
@@ -475,7 +475,6 @@ void page_cache_ra_order(struct readahead_control *ractl,
 	pgoff_t mark = index + ra->size - ra->async_size;
 	unsigned int nofs;
 	int err = 0;
-	gfp_t gfp = readahead_gfp_mask(mapping);
 	unsigned int new_order = ra->order;
 
 	trace_page_cache_ra_order(mapping->host, start, ra);
@@ -626,7 +625,7 @@ void page_cache_sync_ra(struct readahead_control *ractl,
 readit:
 	ra->order = 0;
 	ractl->_index = ra->start;
-	page_cache_ra_order(ractl, ra);
+	page_cache_ra_order(ractl, ra, readahead_gfp_mask(ractl->mapping));
 }
 EXPORT_SYMBOL_GPL(page_cache_sync_ra);
 
@@ -697,7 +696,7 @@ void page_cache_async_ra(struct readahead_control *ractl,
 		ra->size -= end - aligned_end;
 	ra->async_size = ra->size;
 	ractl->_index = ra->start;
-	page_cache_ra_order(ractl, ra);
+	page_cache_ra_order(ractl, ra, readahead_gfp_mask(ractl->mapping));
 }
 EXPORT_SYMBOL_GPL(page_cache_async_ra);
 
Signature · 1 line
2.52.0
Signature · 2 lines
Jan Kara <[email protected]>
SUSE Labs, CR
author reviewer
#4 lore raw

Re: [PATCH v3 2/4] mm: use tiered folio allocation for VM_EXEC readahead

Quoted 25 lines · Jan Kara
Quoted 8 lines · Usama Arif

When executable pages are faulted via do_sync_mmap_readahead(), request a folio order that enables the best hardware TLB coalescing available:

- If the VMA is large enough to contain a full PMD, request HPAGE_PMD_ORDER so the folio can be PMD-mapped. This benefits architectures where PMD_SIZE is reasonable (e.g. 2M on x86-64 and arm64 with 4K pages). VM_EXEC VMAs are very unlikely to be large enough for 512M pages on ARM to take into affect.

I'm not sure relying on PMD_SIZE will be too much for a VMA is a great strategy. With 16k PAGE_SIZE the PMD would be 32MB large which would fit in the .text size but already looks a bit too much? Mapping with PMD sized folios brings some benefits but at the same time it costs because now parts of VMA that would be never paged in are pulled into memory and also LRU tracking now happens with this very large granularity making it fairly inefficient (big folios have much higher chances of getting accessed similarly often making LRU order mostly random). We are already getting reports of people with small machines (phones etc.) where the memory overhead of large folios (in the page cache) is simply too much. So I'd have a bigger peace of mind if we capped folio size at 2MB for now until we come with a more sophisticated heuristic of picking sensible folio order given the machine size. Now I'm not really an MM person so my feeling here may be just wrong but I wanted to voice this concern from what I can see...

Quoted 3 lines

Honza

Thanks for the feedback! I agree, it makes sense. I did that in the previous revision [1]. I will reinistante that in the next one.

[1] https://lore.kernel.org/all/[email protected]/

Quoted 190 lines
Quoted 190 lines

- Otherwise, fall back to exec_folio_order(), which returns the minimum order for hardware PTE coalescing for arm64:
- arm64 4K: order 4 (64K) for contpte (16 PTEs → 1 iTLB entry)
- arm64 16K: order 2 (64K) for HPA (4 pages → 1 TLB entry)
- arm64 64K: order 5 (2M) for contpte (32 PTEs → 1 iTLB entry)
- generic: order 0 (no coalescing)

Update the arm64 exec_folio_order() to return ilog2(SZ_2M >> PAGE_SHIFT) on 64K page configurations, where the previous SZ_64K value collapsed to order 0 (a single page) and provided no coalescing benefit.

Use ~__GFP_RECLAIM so the allocation is opportunistic: if a large folio is readily available, use it, otherwise fall back to smaller folios without stalling on reclaim or compaction. The existing fallback in page_cache_ra_order() handles this naturally.

The readahead window is already clamped to the VMA boundaries, so ra->size naturally caps the folio order via ilog2(ra->size) in page_cache_ra_order().

---
 arch/arm64/include/asm/pgtable.h | 16 +++++++++----
 mm/filemap.c                     | 40 +++++++++++++++++++++++---------
 mm/internal.h                    |  3 ++-
 mm/readahead.c                   |  7 +++---
 4 files changed, 45 insertions(+), 21 deletions(-)
arch/arm64/include/asm/pgtable.h +11 -5
index 52bafe79c10a..9ce9f73a6f35 100644
@@ -1591,12 +1591,18 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
 #define arch_wants_old_prefaulted_pte	cpu_has_hw_af
 
 /*
- * Request exec memory is read into pagecache in at least 64K folios. This size
- * can be contpte-mapped when 4K base pages are in use (16 pages into 1 iTLB
- * entry), and HPA can coalesce it (4 pages into 1 TLB entry) when 16K base
- * pages are in use.
+ * Request exec memory is read into pagecache in folios large enough for
+ * hardware TLB coalescing. On 4K and 16K page configs this is 64K, which
+ * enables contpte mapping (16 × 4K) and HPA coalescing (4 × 16K). On
+ * 64K page configs, contpte requires 2M (32 × 64K).
  */
-#define exec_folio_order() ilog2(SZ_64K >> PAGE_SHIFT)
+#define exec_folio_order exec_folio_order
+static inline unsigned int exec_folio_order(void)
+{
+	if (PAGE_SIZE == SZ_64K)
+		return ilog2(SZ_2M >> PAGE_SHIFT);
+	return ilog2(SZ_64K >> PAGE_SHIFT);
+}
 
 static inline bool pud_sect_supported(void)
 {
mm/filemap.c +29 -11
index a4ea869b2ca1..7ffea986b3b4 100644
@@ -3311,6 +3311,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 	DEFINE_READAHEAD(ractl, file, ra, mapping, vmf->pgoff);
 	struct file *fpin = NULL;
 	vm_flags_t vm_flags = vmf->vma->vm_flags;
+	gfp_t gfp = readahead_gfp_mask(mapping);
 	bool force_thp_readahead = false;
 	unsigned short mmap_miss;
 
@@ -3363,28 +3364,45 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 			ra->size *= 2;
 		ra->async_size = HPAGE_PMD_NR;
 		ra->order = HPAGE_PMD_ORDER;
-		page_cache_ra_order(&ractl, ra);
+		page_cache_ra_order(&ractl, ra, gfp);
 		return fpin;
 	}
 
 	if (vm_flags & VM_EXEC) {
 		/*
-		 * Allow arch to request a preferred minimum folio order for
-		 * executable memory. This can often be beneficial to
-		 * performance if (e.g.) arm64 can contpte-map the folio.
-		 * Executable memory rarely benefits from readahead, due to its
-		 * random access nature, so set async_size to 0.
+		 * Request large folios for executable memory to enable
+		 * hardware PTE coalescing and PMD mappings:
 		 *
-		 * Limit to the boundaries of the VMA to avoid reading in any
-		 * pad that might exist between sections, which would be a waste
-		 * of memory.
+		 *  - If the VMA is large enough for a PMD, request
+		 *    HPAGE_PMD_ORDER so the folio can be PMD-mapped.
+		 *  - Otherwise, use exec_folio_order() which returns
+		 *    the minimum order for hardware TLB coalescing
+		 *    (e.g. arm64 contpte/HPA).
+		 *
+		 * Use ~__GFP_RECLAIM so large folio allocation is
+		 * opportunistic — if memory isn't readily available,
+		 * fall back to smaller folios rather than stalling on
+		 * reclaim or compaction.
+		 *
+		 * Executable memory rarely benefits from speculative
+		 * readahead due to its random access nature, so set
+		 * async_size to 0.
+		 *
+		 * Limit to the boundaries of the VMA to avoid reading
+		 * in any pad that might exist between sections, which
+		 * would be a waste of memory.
 		 */
+		gfp &= ~__GFP_RECLAIM;
 		struct vm_area_struct *vma = vmf->vma;
 		unsigned long start = vma->vm_pgoff;
 		unsigned long end = start + vma_pages(vma);
 		unsigned long ra_end;
 
-		ra->order = exec_folio_order();
+		if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
+		    vma_pages(vma) >= HPAGE_PMD_NR)
+			ra->order = HPAGE_PMD_ORDER;
+		else
+			ra->order = exec_folio_order();
 		ra->start = round_down(vmf->pgoff, 1UL << ra->order);
 		ra->start = max(ra->start, start);
 		ra_end = round_up(ra->start + ra->ra_pages, 1UL << ra->order);
@@ -3403,7 +3421,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 
 	fpin = maybe_unlock_mmap_for_io(vmf, fpin);
 	ractl._index = ra->start;
-	page_cache_ra_order(&ractl, ra);
+	page_cache_ra_order(&ractl, ra, gfp);
 	return fpin;
 }
 
mm/internal.h +2 -1
index 475bd281a10d..e624cb619057 100644
@@ -545,7 +545,8 @@ int zap_vma_for_reaping(struct vm_area_struct *vma);
 int folio_unmap_invalidate(struct address_space *mapping, struct folio *folio,
 			   gfp_t gfp);
 
-void page_cache_ra_order(struct readahead_control *, struct file_ra_state *);
+void page_cache_ra_order(struct readahead_control *, struct file_ra_state *,
+			 gfp_t gfp);
 void force_page_cache_ra(struct readahead_control *, unsigned long nr);
 static inline void force_page_cache_readahead(struct address_space *mapping,
 		struct file *file, pgoff_t index, unsigned long nr_to_read)
mm/readahead.c +3 -4
index 7b05082c89ea..b3dc08cf180c 100644
@@ -465,7 +465,7 @@ static inline int ra_alloc_folio(struct readahead_control *ractl, pgoff_t index,
 }
 
 void page_cache_ra_order(struct readahead_control *ractl,
-		struct file_ra_state *ra)
+		struct file_ra_state *ra, gfp_t gfp)
 {
 	struct address_space *mapping = ractl->mapping;
 	pgoff_t start = readahead_index(ractl);
@@ -475,7 +475,6 @@ void page_cache_ra_order(struct readahead_control *ractl,
 	pgoff_t mark = index + ra->size - ra->async_size;
 	unsigned int nofs;
 	int err = 0;
-	gfp_t gfp = readahead_gfp_mask(mapping);
 	unsigned int new_order = ra->order;
 
 	trace_page_cache_ra_order(mapping->host, start, ra);
@@ -626,7 +625,7 @@ void page_cache_sync_ra(struct readahead_control *ractl,
 readit:
 	ra->order = 0;
 	ractl->_index = ra->start;
-	page_cache_ra_order(ractl, ra);
+	page_cache_ra_order(ractl, ra, readahead_gfp_mask(ractl->mapping));
 }
 EXPORT_SYMBOL_GPL(page_cache_sync_ra);
 
@@ -697,7 +696,7 @@ void page_cache_async_ra(struct readahead_control *ractl,
 		ra->size -= end - aligned_end;
 	ra->async_size = ra->size;
 	ractl->_index = ra->start;
-	page_cache_ra_order(ractl, ra);
+	page_cache_ra_order(ractl, ra, readahead_gfp_mask(ractl->mapping));
 }
 EXPORT_SYMBOL_GPL(page_cache_async_ra);
 
Signature · 1 line
2.52.0
author reviewer
#5 lore raw

PATCH v3 3/4 elf: align ET_DYN base for PTE coalescing and PMD mapping

In reply to Usama Arif

For PIE binaries (ET_DYN), the load address is randomized at PAGE_SIZE granularity via arch_mmap_rnd(). On arm64 with 64K base pages, this means the binary is 64K-aligned, but contpte mapping requires 2M (CONT_PTE_SIZE) alignment.

Without proper virtual address alignment, readahead patches that allocate large folios with aligned file offsets and physical addresses cannot benefit from contpte mapping, as the contpte fold check in contpte_set_ptes() requires the virtual address to be CONT_PTE_SIZE- aligned.

Fix this by extending maximum_alignment() to consider folio alignment at two tiers, matching the readahead allocation strategy:

- HPAGE_PMD_SIZE, so large folios can be PMD-mapped on architectures where PMD_SIZE is reasonable (e.g. 2M on x86-64 and arm64 with 4K pages).

- exec_folio_order(), the minimum order for hardware TLB coalescing (e.g. arm64 contpte/HPA).

For each PT_LOAD segment, folio_alignment() tries both tiers and returns the largest power-of-2 alignment that fits within the segment size, with both p_vaddr and p_offset aligned to that size. This ensures load_bias is folio-aligned so that file-offset-aligned folios map to properly aligned virtual addresses, enabling hardware PTE coalescing and PMD mappings for large folios.

The segment size check in folio_alignment() avoids reducing ASLR entropy for small binaries that cannot benefit from large folio alignment.

---
 fs/binfmt_elf.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)
fs/binfmt_elf.c +50 -0
index 16a56b6b3f6c..f84fae6daf23 100644
@@ -488,6 +488,54 @@ static int elf_read(struct file *file, void *buf, size_t len, loff_t pos)
 	return 0;
 }
 
+/*
+ * Return the largest folio alignment for a PT_LOAD segment, so the
+ * hardware can coalesce PTEs (e.g. arm64 contpte) or use PMD mappings
+ * for large folios.
+ *
+ * Try PMD alignment so large folios can be PMD-mapped. Then try
+ * exec_folio_order() alignment for hardware TLB coalescing (e.g.
+ * arm64 contpte/HPA).
+ *
+ * Use the largest power-of-2 that fits within the segment size, capped
+ * by the target folio size.
+ * Only align when the segment's virtual address and file offset are
+ * already aligned to that size, as misalignment would prevent coalescing
+ * anyway.
+ *
+ * The segment size check avoids reducing ASLR entropy for small binaries
+ * that cannot benefit.
+ */
+static unsigned long folio_alignment(struct elf_phdr *cmd)
+{
+	unsigned long alignment = 0;
+	unsigned long seg_size;
+
+	if (!cmd->p_filesz)
+		return 0;
+
+	seg_size = rounddown_pow_of_two(cmd->p_filesz);
+
+	if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
+		unsigned long size = min(seg_size, HPAGE_PMD_SIZE);
+
+		if (size > PAGE_SIZE &&
+		    IS_ALIGNED(cmd->p_vaddr | cmd->p_offset, size))
+			alignment = size;
+	}
+
+	if (!alignment && exec_folio_order()) {
+		unsigned long size = min(seg_size,
+					PAGE_SIZE << exec_folio_order());
+
+		if (size > PAGE_SIZE &&
+		    IS_ALIGNED(cmd->p_vaddr | cmd->p_offset, size))
+			alignment = size;
+	}
+
+	return alignment;
+}
+
 static unsigned long maximum_alignment(struct elf_phdr *cmds, int nr)
 {
 	unsigned long alignment = 0;
@@ -501,6 +549,8 @@ static unsigned long maximum_alignment(struct elf_phdr *cmds, int nr)
 			if (!is_power_of_2(p_align))
 				continue;
 			alignment = max(alignment, p_align);
+			alignment = max(alignment,
+					folio_alignment(&cmds[i]));
 		}
 	}
 
Signature · 1 line
2.52.0
author reviewer
#6 lore raw

PATCH v3 4/4 mm: align file-backed mmap to exec folio order in thp_get_unmapped_area

In reply to Usama Arif

thp_get_unmapped_area() is the get_unmapped_area callback for filesystems like ext4, xfs, and btrfs. It attempts to align the virtual address for PMD_SIZE THP mappings, but on arm64 with 64K base pages PMD_SIZE is 512M, which is too large for typical shared library mappings, so the alignment always fails and falls back to PAGE_SIZE.

This means shared libraries loaded by ld.so via mmap() get 64K-aligned virtual addresses, preventing contpte mapping even when large folios are allocated with properly aligned file offsets and physical addresses.

Add a fallback in thp_get_unmapped_area_vmflags() that uses exec_folio_order() to determine alignment, matching the readahead allocation strategy. This aligns mappings to the hardware TLB coalescing size (e.g. 2M for contpte on arm64 64K pages, 64K for contpte/HPA on arm64 4K/16K pages), capped to the mapping length via rounddown_pow_of_two(len).

The fallback is naturally a no-op on architectures where exec_folio_order() returns 0, and skips the retry when the alignment would equal PMD_SIZE (already attempted above) incase another architecture changes exec_folio_order() in the future.

---
 mm/huge_memory.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
mm/huge_memory.c +13 -0
index b2a6060b3c20..ad97ac8406dc 100644
@@ -1218,6 +1218,19 @@ unsigned long thp_get_unmapped_area_vmflags(struct file *filp, unsigned long add
 	if (ret)
 		return ret;
 
+	if (filp && exec_folio_order()) {
+		unsigned long exec_folio_size = PAGE_SIZE << exec_folio_order();
+		unsigned long size = rounddown_pow_of_two(len);
+
+		size = min(size, exec_folio_size);
+		if (size > PAGE_SIZE && size != PMD_SIZE) {
+			ret = __thp_get_unmapped_area(filp, addr, len, off,
+						      flags, size, vm_flags);
+			if (ret)
+				return ret;
+		}
+	}
+
 	return mm_get_unmapped_area_vmflags(filp, addr, len, pgoff, flags,
 					    vm_flags);
 }
Signature · 1 line
2.52.0
author reviewer
#7 lore raw
In reply to Usama Arif
Quoted 5 lines · Usama Arif

v2 -> v3: https://lore.kernel.org/all/[email protected]/
- Take into account READ_ONLY_THP_FOR_FS for elf alignment by aligning to HPAGE_PMD_SIZE limited to 2M (Rui)
- Reviewed-by tags for patch 1 from Kiryl and Jan
- Remove preferred_exec_order() (Jan)

Quoted 9 lines

- Change ra->order to HPAGE_PMD_ORDER if vma_pages(vma) >= HPAGE_PMD_NR otherwise use exec_folio_order() with gfp &= ~__GFP_RECLAIM for do_sync_mmap_readahead().
- Change exec_folio_order() to return 2M (cont-pte size) for 64K base page size for arm64.
- remove bprm->file NULL check (Matthew)
- Change filp to file (Matthew)
- Improve checking of p_vaddr and p_vaddr (Rui and Matthew)

Hello!

Just wanted to check if there was any feedback/review on the latest revision?

Thanks!

#8 lore raw
Quoted 18 lines · Usama Arif
Quoted 5 lines · Usama Arif

v2 -> v3: https://lore.kernel.org/all/[email protected]/
- Take into account READ_ONLY_THP_FOR_FS for elf alignment by aligning to HPAGE_PMD_SIZE limited to 2M (Rui)
- Reviewed-by tags for patch 1 from Kiryl and Jan
- Remove preferred_exec_order() (Jan)

Quoted 9 lines

- Change ra->order to HPAGE_PMD_ORDER if vma_pages(vma) >= HPAGE_PMD_NR otherwise use exec_folio_order() with gfp &= ~__GFP_RECLAIM for do_sync_mmap_readahead().
- Change exec_folio_order() to return 2M (cont-pte size) for 64K base page size for arm64.
- remove bprm->file NULL check (Matthew)
- Change filp to file (Matthew)
- Improve checking of p_vaddr and p_vaddr (Rui and Matthew)

Quoted 4 lines

Hello!

Just wanted to check if there was any feedback/review on the latest revision?

It's -rc7, this is definitely something for next cycle :)

On my part, my upstream bandwidth has drastically reduced, and review is probably going to have to be a hobbyist thing at least for now.

Also, not to be mean but:

$ git log -E -i --grep "(Reviewed|Acked)-by: Usama Arif" --oneline | wc -l
21

So... :)

Review in mm is very lop-sided, let's try to balance it out a bit!

Quoted 3 lines

Thanks!

Thanks, Lorenzo

#9 lore raw
Quoted 36 lines · Lorenzo Stoakes
Quoted 18 lines · Usama Arif
Quoted 5 lines · Usama Arif

v2 -> v3: https://lore.kernel.org/all/[email protected]/
- Take into account READ_ONLY_THP_FOR_FS for elf alignment by aligning to HPAGE_PMD_SIZE limited to 2M (Rui)
- Reviewed-by tags for patch 1 from Kiryl and Jan
- Remove preferred_exec_order() (Jan)

Quoted 9 lines

- Change ra->order to HPAGE_PMD_ORDER if vma_pages(vma) >= HPAGE_PMD_NR otherwise use exec_folio_order() with gfp &= ~__GFP_RECLAIM for do_sync_mmap_readahead().
- Change exec_folio_order() to return 2M (cont-pte size) for 64K base page size for arm64.
- remove bprm->file NULL check (Matthew)
- Change filp to file (Matthew)
- Improve checking of p_vaddr and p_vaddr (Rui and Matthew)

Quoted 4 lines

Hello!

Just wanted to check if there was any feedback/review on the latest revision?

It's -rc7, this is definitely something for next cycle :)

On my part, my upstream bandwidth has drastically reduced, and review is probably going to have to be a hobbyist thing at least for now.

Also, not to be mean but:

$ git log -E -i --grep "(Reviewed|Acked)-by: Usama Arif" --oneline | wc -l
21

So... :)

Quoted 7 lines

Review in mm is very lop-sided, let's try to balance it out a bit!

Quoted 3 lines

Thanks!

Thanks, Lorenzo

(Note that we're in a 'quiet period' from here until -rc1 of next cycle and won't be taking anything new until then. We plan to do this from around rc5 or rc6 of each cycle in future).

author reviewer
#10 lore raw
Quoted 40 lines · Lorenzo Stoakes
Quoted 39 lines · Lorenzo Stoakes
Quoted 18 lines · Usama Arif
Quoted 5 lines · Usama Arif

v2 -> v3: https://lore.kernel.org/all/[email protected]/
- Take into account READ_ONLY_THP_FOR_FS for elf alignment by aligning to HPAGE_PMD_SIZE limited to 2M (Rui)
- Reviewed-by tags for patch 1 from Kiryl and Jan
- Remove preferred_exec_order() (Jan)

Quoted 9 lines

- Change ra->order to HPAGE_PMD_ORDER if vma_pages(vma) >= HPAGE_PMD_NR otherwise use exec_folio_order() with gfp &= ~__GFP_RECLAIM for do_sync_mmap_readahead().
- Change exec_folio_order() to return 2M (cont-pte size) for 64K base page size for arm64.
- remove bprm->file NULL check (Matthew)
- Change filp to file (Matthew)
- Improve checking of p_vaddr and p_vaddr (Rui and Matthew)

Quoted 4 lines

Hello!

Just wanted to check if there was any feedback/review on the latest revision?

It's -rc7, this is definitely something for next cycle :)

On my part, my upstream bandwidth has drastically reduced, and review is probably going to have to be a hobbyist thing at least for now.

Also, not to be mean but:

$ git log -E -i --grep "(Reviewed|Acked)-by: Usama Arif" --oneline | wc -l
21

So... :)

Review in mm is very lop-sided, let's try to balance it out a bit!

Quoted 1 line
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

Thanks!

Thanks, Lorenzo

(Note that we're in a 'quiet period' from here until -rc1 of next cycle and won't be taking anything new until then. We plan to do this from around rc5 or rc6 of each cycle in future).

Thanks! Just wanted to check, as I am always confused about this. Is it ok to send patches for review for next release at this time? So that they are in a good state when rc1 comes. I wanted to send PMD swap entries for review after I am finished testing, but I want them for review for next release.

#11 lore raw
Quoted 52 lines · Usama Arif
Quoted 40 lines · Lorenzo Stoakes
Quoted 39 lines · Lorenzo Stoakes
Quoted 18 lines · Usama Arif
Quoted 5 lines · Usama Arif

v2 -> v3: https://lore.kernel.org/all/[email protected]/
- Take into account READ_ONLY_THP_FOR_FS for elf alignment by aligning to HPAGE_PMD_SIZE limited to 2M (Rui)
- Reviewed-by tags for patch 1 from Kiryl and Jan
- Remove preferred_exec_order() (Jan)

Quoted 9 lines

- Change ra->order to HPAGE_PMD_ORDER if vma_pages(vma) >= HPAGE_PMD_NR otherwise use exec_folio_order() with gfp &= ~__GFP_RECLAIM for do_sync_mmap_readahead().
- Change exec_folio_order() to return 2M (cont-pte size) for 64K base page size for arm64.
- remove bprm->file NULL check (Matthew)
- Change filp to file (Matthew)
- Improve checking of p_vaddr and p_vaddr (Rui and Matthew)

Quoted 4 lines

Hello!

Just wanted to check if there was any feedback/review on the latest revision?

It's -rc7, this is definitely something for next cycle :)

On my part, my upstream bandwidth has drastically reduced, and review is probably going to have to be a hobbyist thing at least for now.

Also, not to be mean but:

$ git log -E -i --grep "(Reviewed|Acked)-by: Usama Arif" --oneline | wc -l
21

So... :)

Review in mm is very lop-sided, let's try to balance it out a bit!

Quoted 1 line
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

Thanks!

Thanks, Lorenzo

(Note that we're in a 'quiet period' from here until -rc1 of next cycle and won't be taking anything new until then. We plan to do this from around rc5 or rc6 of each cycle in future).

Quoted 5 lines

Thanks! Just wanted to check, as I am always confused about this. Is it ok to send patches for review for next release at this time? So that they are in a good state when rc1 comes. I wanted to send PMD swap entries for review after I am finished testing, but I want them for review for next release.

I think different people have different views on that :)

I mean it's debateable whether having a glut of new material on day one of -rc1 is preferable to having a bunch come in that might or might not get lost along the way :)

I personally feel it'd be better to send during the cycle window rather than before but I suspect others disagree with that!

So from your point of view, feel free to do what you like, but maybe David + others would want to chime in with their opinions?

Thanks, Lorenzo

#12 lore raw
Quoted 19 lines · Lorenzo Stoakes
Quoted 11 lines · Usama Arif
Quoted 5 lines
Quoted 1 line

Thanks, Lorenzo

(Note that we're in a 'quiet period' from here until -rc1 of next cycle and won't be taking anything new until then. We plan to do this from around rc5 or rc6 of each cycle in future).

Thanks! Just wanted to check, as I am always confused about this. Is it ok to send patches for review for next release at this time? So that they are in a good state when rc1 comes. I wanted to send PMD swap entries for review after I am finished testing, but I want them for review for next release.

I think different people have different views on that :)

I mean it's debateable whether having a glut of new material on day one of -rc1 is preferable to having a bunch come in that might or might not get lost along the way :)

Quoted 5 lines

I personally feel it'd be better to send during the cycle window rather than before but I suspect others disagree with that!

So from your point of view, feel free to do what you like, but maybe David + others would want to chime in with their opinions?

For me the more important part of the quiet period is that patches can't be merged, so there's less urgency to review them immediately. So I think it's fine to still send patches, but not having expectations about quick response, as people might be taking time off.

On the other hand it would be better if new series could mature in this quiet period, so there would be less work after rc1. But the key to making that possible I think is to feel less urgency/being overwhelmed also in the non-quiet period (rc1-rc5/6). Then it's should be less necessary to take time off during the quiet period. So hopefully we'll get there through involving more reviewers, and by having more submaintainers agency.

Vlastimil

#13 lore raw
Quoted 31 lines · Vlastimil Babka (SUSE)
Quoted 19 lines · Lorenzo Stoakes
Quoted 11 lines · Usama Arif
Quoted 5 lines
Quoted 1 line

Thanks, Lorenzo

(Note that we're in a 'quiet period' from here until -rc1 of next cycle and won't be taking anything new until then. We plan to do this from around rc5 or rc6 of each cycle in future).

Thanks! Just wanted to check, as I am always confused about this. Is it ok to send patches for review for next release at this time? So that they are in a good state when rc1 comes. I wanted to send PMD swap entries for review after I am finished testing, but I want them for review for next release.

I think different people have different views on that :)

I mean it's debateable whether having a glut of new material on day one of -rc1 is preferable to having a bunch come in that might or might not get lost along the way :)

Quoted 5 lines

I personally feel it'd be better to send during the cycle window rather than before but I suspect others disagree with that!

So from your point of view, feel free to do what you like, but maybe David + others would want to chime in with their opinions?

For me the more important part of the quiet period is that patches can't be merged, so there's less urgency to review them immediately. So I think it's fine to still send patches, but not having expectations about quick response, as people might be taking time off.

Quoted 6 lines

On the other hand it would be better if new series could mature in this quiet period, so there would be less work after rc1. But the key to making that possible I think is to feel less urgency/being overwhelmed also in the non-quiet period (rc1-rc5/6). Then it's should be less necessary to take time off during the quiet period. So hopefully we'll get there through involving more reviewers, and by having more submaintainers agency.

Yeah I sympathise with that.

But until we for-sure have <you know what :))> signoff, I worry about the risk of series 'just being taken' at -rc1 because it maybe seems easier to do that, and then we have a series from 5 weeks ago you forgot about suddenly crop up.

So I guess the more nuanced take I have is:

Once we have a robust set up end-to-end _that can handle_ having series that are deferred to next cycle without risk of things getting mixed up - then that makes sense, yes.

But while there's still a bit of uncertainty around that, then I'd rather not.

But I think if people DO just resend their stuff in -rc1 then we're OK and it addresses my concerns.

One thing we could do here is to tag series appropriately like:

[PATCH v7.2] 00/42

To make it clear where it's intended to head to.

P.S. Having the 'quiet period' REALLY REALLY helps. So thanks for that Andrew!

Quoted 2 lines

Vlastimil

Thanks, Lorenzo

#14 lore raw
In reply to Lorenzo Stoakes
Quoted 21 lines · Lorenzo Stoakes
Quoted 8 lines · Usama Arif
Quoted 4 lines · Lorenzo Stoakes

(Note that we're in a 'quiet period' from here until -rc1 of next cycle and won't be taking anything new until then. We plan to do this from around rc5 or rc6 of each cycle in future).

Quoted 5 lines

Thanks! Just wanted to check, as I am always confused about this. Is it ok to send patches for review for next release at this time? So that they are in a good state when rc1 comes. I wanted to send PMD swap entries for review after I am finished testing, but I want them for review for next release.

I think different people have different views on that :)

I mean it's debateable whether having a glut of new material on day one of -rc1 is preferable to having a bunch come in that might or might not get lost along the way :)

Quoted 5 lines

I personally feel it'd be better to send during the cycle window rather than before but I suspect others disagree with that!

So from your point of view, feel free to do what you like, but maybe David + others would want to chime in with their opinions?

I personally don't care that much. People just have to be prepared that there will be little review on new (non-fix) material during the quiet period.

It will sit in my inbox one way or the other :)

Signature · 3 lines
Cheers,

David
author reviewer
#15 lore raw
In reply to Lorenzo Stoakes
Quoted 19 lines · Lorenzo Stoakes
Quoted 18 lines · Usama Arif
Quoted 14 lines · Usama Arif

v2 -> v3: https://lore.kernel.org/all/[email protected]/
- Take into account READ_ONLY_THP_FOR_FS for elf alignment by aligning to HPAGE_PMD_SIZE limited to 2M (Rui)
- Reviewed-by tags for patch 1 from Kiryl and Jan
- Remove preferred_exec_order() (Jan)
- Change ra->order to HPAGE_PMD_ORDER if vma_pages(vma) >= HPAGE_PMD_NR otherwise use exec_folio_order() with gfp &= ~__GFP_RECLAIM for do_sync_mmap_readahead().
- Change exec_folio_order() to return 2M (cont-pte size) for 64K base page size for arm64.
- remove bprm->file NULL check (Matthew)
- Change filp to file (Matthew)
- Improve checking of p_vaddr and p_vaddr (Rui and Matthew)

Quoted 7 lines
Quoted 4 lines

Hello!

Just wanted to check if there was any feedback/review on the latest revision?

It's -rc7, this is definitely something for next cycle :)

Yeah no worries! Just wanted to check what people thought about it!

Quoted 12 lines

On my part, my upstream bandwidth has drastically reduced, and review is probably going to have to be a hobbyist thing at least for now.

Also, not to be mean but:

$ git log -E -i --grep "(Reviewed|Acked)-by: Usama Arif" --oneline | wc -l
21

So... :)

Review in mm is very lop-sided, let's try to balance it out a bit!

Ah yeah actually I have been reviewing a lot over the last few months. I dont ack patches that have already been acked-by/reviewed-by maintainers. as I am not sure if it adds anything. I never really cared about Reviewed/Acked by/patch count but I can start adding tags if it helps in stats.

The reviews I have done over the last week alone:
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/all/[email protected]/T/#t
https://lore.kernel.org/all/[email protected]/

#16 lore raw
Quoted 24 lines · Usama Arif
Quoted 21 lines · Lorenzo Stoakes
Quoted 20 lines · Usama Arif
Quoted 5 lines · Usama Arif

v2 -> v3: https://lore.kernel.org/all/[email protected]/
- Take into account READ_ONLY_THP_FOR_FS for elf alignment by aligning to HPAGE_PMD_SIZE limited to 2M (Rui)
- Reviewed-by tags for patch 1 from Kiryl and Jan
- Remove preferred_exec_order() (Jan)

Quoted 9 lines

- Change ra->order to HPAGE_PMD_ORDER if vma_pages(vma) >= HPAGE_PMD_NR otherwise use exec_folio_order() with gfp &= ~__GFP_RECLAIM for do_sync_mmap_readahead().
- Change exec_folio_order() to return 2M (cont-pte size) for 64K base page size for arm64.
- remove bprm->file NULL check (Matthew)
- Change filp to file (Matthew)
- Improve checking of p_vaddr and p_vaddr (Rui and Matthew)

Hello!

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

Just wanted to check if there was any feedback/review on the latest revision?

It's -rc7, this is definitely something for next cycle :)

Yeah no worries! Just wanted to check what people thought about it!

We'll come back to it! With LSF coming too I think people are fairly distracted as well.

Quoted 9 lines
Quoted 9 lines

On my part, my upstream bandwidth has drastically reduced, and review is probably going to have to be a hobbyist thing at least for now.

Also, not to be mean but:

$ git log -E -i --grep "(Reviewed|Acked)-by: Usama Arif" --oneline | wc -l
21
Quoted 6 lines
Quoted 4 lines

So... :)

Review in mm is very lop-sided, let's try to balance it out a bit!

Ah yeah actually I have been reviewing a lot over the last few months.

Good :)

Quoted 1 line

I dont ack patches that have already been acked-by/reviewed-by maintainers.

You should do that, it is meaningful. If you think a patch is OK, it's how you say so!

Maintainers get things wrong too by the way, assume we are wrong and try to find issues, this is how a healthy technical community operates (as long as everybody is civil about it :)

Quoted 2 lines

as I am not sure if it adds anything. I never really cared about Reviewed/Acked by/patch count but I can start adding tags if it helps in stats.

It's the only metric I can quickly bring up, so sorry that in this case I got it wrong, but the overall point remains the same - we want to see a balance of review and contributions, right now the two are really very lopsided!

Quoted 14 lines

The reviews I have done over the last week alone:
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/all/[email protected]/T/#t
https://lore.kernel.org/all/[email protected]/

Cheers, Lorenzo