From: Chi Zhiling Apply the same optimization used in filemap_get_read_batch() by moving the boundary check from the loop condition to before xas_advance(), avoiding an unnecessary xarray lookup and reducing branches in the fast path. Signed-off-by: Chi Zhiling --- mm/filemap.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index d54450e529bd..5a5268a7c802 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2258,11 +2258,14 @@ unsigned filemap_get_folios_contig(struct address_space *mapping, XA_STATE(xas, &mapping->i_pages, *start); unsigned long nr; struct folio *folio; + pgoff_t next; + + if (unlikely(*start > end)) + return 0; rcu_read_lock(); - for (folio = xas_load(&xas); folio && xas.xa_index <= end; - folio = xas_next(&xas)) { + for (folio = xas_load(&xas); folio; folio = xas_next(&xas)) { if (xas_retry(&xas, folio)) continue; /* @@ -2270,11 +2273,11 @@ unsigned filemap_get_folios_contig(struct address_space *mapping, * No current caller is looking for DAX entries. */ if (xa_is_value(folio)) - goto update_start; + break; /* If we landed in the middle of a THP, continue at its end. */ if (xa_is_sibling(folio)) - goto update_start; + break; if (!folio_try_get(folio)) goto retry; @@ -2282,12 +2285,15 @@ unsigned filemap_get_folios_contig(struct address_space *mapping, if (unlikely(folio != xas_reload(&xas))) goto put_folio; + next = folio_next_index(folio); if (!folio_batch_add(fbatch, folio)) { - nr = folio_nr_pages(folio); - *start = folio->index + nr; + *start = next; goto out; } - xas_advance(&xas, folio_next_index(folio) - 1); + + if (next > end) + break; + xas_advance(&xas, next - 1); continue; put_folio: folio_put(folio); @@ -2296,9 +2302,7 @@ unsigned filemap_get_folios_contig(struct address_space *mapping, xas_reset(&xas); } -update_start: nr = folio_batch_count(fbatch); - if (nr) { folio = fbatch->folios[nr - 1]; *start = folio_next_index(folio); -- 2.43.0