Re: [linux-next:master] [mm] 7b32f64bc5: pts.svt-av1.Preset13.Bosphorus4K.frames_per_second 45.8% regression
Frederick Mayle <[email protected]> Thu, 23 Jul 2026 13:34:38 -0700
| Newsgroups | dev.linux.lists.oe-lkp,org.kernel.vger.linux-fsdevel,org.kvack.linux-mm |
|---|---|
| Message-ID | <CAHCxdc64d-6qNBwwSZX8mdz4-V+88No2x0wG4mex5WPXBDE9AA@mail.gmail.com> |
On Wed, Jul 22, 2026 at 7:46=E2=80=AFPM Bo Zhang <[email protected]> wr= ote: > > From: zhangbo56 <[email protected]> > > On Thu 18-06-26 16:00:42, kernel test robot wrote: > > kernel test robot noticed a 45.8% regression of > > pts.svt-av1.Preset13.Bosphorus4K.frames_per_second on: > > > > commit: 7b32f64bc512b40b268776c5ac4d354b325b3197 > > ("mm: limit filemap_fault readahead to VMA boundaries") > > > > 169.95 +/- 6% -45.8% 92.15 +/- 10% pts.svt-av1.Preset13.B= osphorus4K.frames_per_second > > 220.57 +/- 3% +870.9% 2141 pts.time.major_page_faul= ts > > Hi Oliver, > > Could you help test if the below patch fixes the regression? > > The 870% increase in major faults suggests that readahead is being cut > short too aggressively. The current approach unconditionally sets > _max_index on every fault, which likely prevents readahead from > prefetching ahead effectively for sequential access patterns. > > The fix: only limit readahead when the fault is close to the VMA end -- > if there are fewer pages remaining in the VMA than ra_pages, set > _max_index. Otherwise, do nothing. > > For a 4MB VMA with ra_pages=3D32, only faults in the last 32 pages (128KB= ) > trigger the limit. The other 99.9% of faults see no change at all. > > Similarly, only clamp the read-around start when the fault is near the > VMA beginning. > > This applies on top of 7b32f64bc512 and can be applied with git am. > > Reported-by: kernel test robot <[email protected]> > Signed-off-by: Bo Zhang <[email protected]> > --- > mm/filemap.c | 15 ++++++++++++--- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/mm/filemap.c b/mm/filemap.c > index 97772a05a18e..9f1e1c9ea6df 100644 > --- a/mm/filemap.c > +++ b/mm/filemap.c > @@ -3313,8 +3313,11 @@ static struct file *do_sync_mmap_readahead(struct = vm_fault *vmf) > vm_flags_t vm_flags =3D vmf->vma->vm_flags; > bool force_thp_readahead =3D false; > unsigned short mmap_miss; > + unsigned long vma_end_pgoff =3D vmf->vma->vm_pgoff + vma_pages(vm= f->vma); > + unsigned long vma_pages_left =3D vma_end_pgoff - vmf->pgoff; > > - ractl._max_index =3D vmf->vma->vm_pgoff + vma_pages(vmf->vma) - 1= ; > + if (vma_pages_left < ra->ra_pages) > + ractl._max_index =3D vma_end_pgoff - 1; > > /* Use the readahead code, even if readahead is disabled */ > if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && > @@ -3398,7 +3401,8 @@ static struct file *do_sync_mmap_readahead(struct v= m_fault *vmf) > * mmap read-around > */ > ra->start =3D max_t(long, 0, vmf->pgoff - ra->ra_pages / = 2); > - ra->start =3D max(ra->start, vmf->vma->vm_pgoff); > + if (vmf->pgoff - vmf->vma->vm_pgoff < ra->ra_pages / 2) > + ra->start =3D max(ra->start, vmf->vma->vm_pgoff); > ra->size =3D ra->ra_pages; > ra->async_size =3D ra->ra_pages / 4; > ra->order =3D 0; > @@ -3441,7 +3445,12 @@ static struct file *do_async_mmap_readahead(struct= vm_fault *vmf, > } > > if (folio_test_readahead(folio)) { > - ractl._max_index =3D vmf->vma->vm_pgoff + vma_pages(vmf->= vma) - 1; > + unsigned long vma_end_pgoff =3D vmf->vma->vm_pgoff + > + vma_pages(vmf->vma); > + unsigned long vma_pages_left =3D vma_end_pgoff - vmf->pgo= ff; > + > + if (vma_pages_left < ra->ra_pages) > + ractl._max_index =3D vma_end_pgoff - 1; > fpin =3D maybe_unlock_mmap_for_io(vmf, fpin); > page_cache_async_ra(&ractl, folio, ra->ra_pages); > } > -- > 2.34.1 > I maybe missing something subtle, but, I think you've changed it from "don'= t read beyond the VMA" to "if there is a chance we could read beyond the VMA, don't read beyond the VMA", which seems like a more complex expression of t= he same behavior.