Skip to content

Commit 26cfdb3

Browse files
Panky-codesbrauner
authored andcommitted
readahead: allocate folios with mapping_min_order in readahead
page_cache_ra_unbounded() was allocating single pages (0 order folios) if there was no folio found in an index. Allocate mapping_min_order folios as we need to guarantee the minimum order if it is set. page_cache_ra_order() tries to allocate folio to the page cache with a higher order if the index aligns with that order. Modify it so that the order does not go below the mapping_min_order requirement of the page cache. This function will do the right thing even if the new_order passed is less than the mapping_min_order. When adding new folios to the page cache we must also ensure the index used is aligned to the mapping_min_order as the page cache requires the index to be aligned to the order of the folio. readahead_expand() is called from readahead aops to extend the range of the readahead so this function can assume ractl->_index to be aligned with min_order. Signed-off-by: Pankaj Raghav <[email protected]> Co-developed-by: Hannes Reinecke <[email protected]> Signed-off-by: Hannes Reinecke <[email protected]> Link: https://lore.kernel.org/r/[email protected] Tested-by: David Howells <[email protected]> Acked-by: Darrick J. Wong <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Reviewed-by: Daniel Gomez <[email protected]> Reviewed-by: Dave Chinner <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent ab95d23 commit 26cfdb3

File tree

1 file changed

+61
-18
lines changed

1 file changed

+61
-18
lines changed

mm/readahead.c

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,10 @@ void page_cache_ra_unbounded(struct readahead_control *ractl,
206206
unsigned long nr_to_read, unsigned long lookahead_size)
207207
{
208208
struct address_space *mapping = ractl->mapping;
209-
unsigned long index = readahead_index(ractl);
209+
unsigned long ra_folio_index, index = readahead_index(ractl);
210210
gfp_t gfp_mask = readahead_gfp_mask(mapping);
211-
unsigned long i;
211+
unsigned long mark, i = 0;
212+
unsigned int min_nrpages = mapping_min_folio_nrpages(mapping);
212213

213214
/*
214215
* Partway through the readahead operation, we will have added
@@ -223,10 +224,24 @@ void page_cache_ra_unbounded(struct readahead_control *ractl,
223224
unsigned int nofs = memalloc_nofs_save();
224225

225226
filemap_invalidate_lock_shared(mapping);
227+
index = mapping_align_index(mapping, index);
228+
229+
/*
230+
* As iterator `i` is aligned to min_nrpages, round_up the
231+
* difference between nr_to_read and lookahead_size to mark the
232+
* index that only has lookahead or "async_region" to set the
233+
* readahead flag.
234+
*/
235+
ra_folio_index = round_up(readahead_index(ractl) + nr_to_read - lookahead_size,
236+
min_nrpages);
237+
mark = ra_folio_index - index;
238+
nr_to_read += readahead_index(ractl) - index;
239+
ractl->_index = index;
240+
226241
/*
227242
* Preallocate as many pages as we will need.
228243
*/
229-
for (i = 0; i < nr_to_read; i++) {
244+
while (i < nr_to_read) {
230245
struct folio *folio = xa_load(&mapping->i_pages, index + i);
231246
int ret;
232247

@@ -240,12 +255,13 @@ void page_cache_ra_unbounded(struct readahead_control *ractl,
240255
* not worth getting one just for that.
241256
*/
242257
read_pages(ractl);
243-
ractl->_index++;
244-
i = ractl->_index + ractl->_nr_pages - index - 1;
258+
ractl->_index += min_nrpages;
259+
i = ractl->_index + ractl->_nr_pages - index;
245260
continue;
246261
}
247262

248-
folio = filemap_alloc_folio(gfp_mask, 0);
263+
folio = filemap_alloc_folio(gfp_mask,
264+
mapping_min_folio_order(mapping));
249265
if (!folio)
250266
break;
251267

@@ -255,14 +271,15 @@ void page_cache_ra_unbounded(struct readahead_control *ractl,
255271
if (ret == -ENOMEM)
256272
break;
257273
read_pages(ractl);
258-
ractl->_index++;
259-
i = ractl->_index + ractl->_nr_pages - index - 1;
274+
ractl->_index += min_nrpages;
275+
i = ractl->_index + ractl->_nr_pages - index;
260276
continue;
261277
}
262-
if (i == nr_to_read - lookahead_size)
278+
if (i == mark)
263279
folio_set_readahead(folio);
264280
ractl->_workingset |= folio_test_workingset(folio);
265-
ractl->_nr_pages++;
281+
ractl->_nr_pages += min_nrpages;
282+
i += min_nrpages;
266283
}
267284

268285
/*
@@ -438,13 +455,19 @@ void page_cache_ra_order(struct readahead_control *ractl,
438455
struct address_space *mapping = ractl->mapping;
439456
pgoff_t start = readahead_index(ractl);
440457
pgoff_t index = start;
458+
unsigned int min_order = mapping_min_folio_order(mapping);
441459
pgoff_t limit = (i_size_read(mapping->host) - 1) >> PAGE_SHIFT;
442460
pgoff_t mark = index + ra->size - ra->async_size;
443461
unsigned int nofs;
444462
int err = 0;
445463
gfp_t gfp = readahead_gfp_mask(mapping);
464+
unsigned int min_ra_size = max(4, mapping_min_folio_nrpages(mapping));
446465

447-
if (!mapping_large_folio_support(mapping) || ra->size < 4)
466+
/*
467+
* Fallback when size < min_nrpages as each folio should be
468+
* at least min_nrpages anyway.
469+
*/
470+
if (!mapping_large_folio_support(mapping) || ra->size < min_ra_size)
448471
goto fallback;
449472

450473
limit = min(limit, index + ra->size - 1);
@@ -454,18 +477,27 @@ void page_cache_ra_order(struct readahead_control *ractl,
454477

455478
new_order = min(mapping_max_folio_order(mapping), new_order);
456479
new_order = min_t(unsigned int, new_order, ilog2(ra->size));
480+
new_order = max(new_order, min_order);
457481

458482
/* See comment in page_cache_ra_unbounded() */
459483
nofs = memalloc_nofs_save();
460484
filemap_invalidate_lock_shared(mapping);
485+
/*
486+
* If the new_order is greater than min_order and index is
487+
* already aligned to new_order, then this will be noop as index
488+
* aligned to new_order should also be aligned to min_order.
489+
*/
490+
ractl->_index = mapping_align_index(mapping, index);
491+
index = readahead_index(ractl);
492+
461493
while (index <= limit) {
462494
unsigned int order = new_order;
463495

464496
/* Align with smaller pages if needed */
465497
if (index & ((1UL << order) - 1))
466498
order = __ffs(index);
467499
/* Don't allocate pages past EOF */
468-
while (index + (1UL << order) - 1 > limit)
500+
while (order > min_order && index + (1UL << order) - 1 > limit)
469501
order--;
470502
err = ra_alloc_folio(ractl, index, mark, order, gfp);
471503
if (err)
@@ -703,8 +735,15 @@ void readahead_expand(struct readahead_control *ractl,
703735
struct file_ra_state *ra = ractl->ra;
704736
pgoff_t new_index, new_nr_pages;
705737
gfp_t gfp_mask = readahead_gfp_mask(mapping);
738+
unsigned long min_nrpages = mapping_min_folio_nrpages(mapping);
739+
unsigned int min_order = mapping_min_folio_order(mapping);
706740

707741
new_index = new_start / PAGE_SIZE;
742+
/*
743+
* Readahead code should have aligned the ractl->_index to
744+
* min_nrpages before calling readahead aops.
745+
*/
746+
VM_BUG_ON(!IS_ALIGNED(ractl->_index, min_nrpages));
708747

709748
/* Expand the leading edge downwards */
710749
while (ractl->_index > new_index) {
@@ -714,9 +753,11 @@ void readahead_expand(struct readahead_control *ractl,
714753
if (folio && !xa_is_value(folio))
715754
return; /* Folio apparently present */
716755

717-
folio = filemap_alloc_folio(gfp_mask, 0);
756+
folio = filemap_alloc_folio(gfp_mask, min_order);
718757
if (!folio)
719758
return;
759+
760+
index = mapping_align_index(mapping, index);
720761
if (filemap_add_folio(mapping, folio, index, gfp_mask) < 0) {
721762
folio_put(folio);
722763
return;
@@ -726,7 +767,7 @@ void readahead_expand(struct readahead_control *ractl,
726767
ractl->_workingset = true;
727768
psi_memstall_enter(&ractl->_pflags);
728769
}
729-
ractl->_nr_pages++;
770+
ractl->_nr_pages += min_nrpages;
730771
ractl->_index = folio->index;
731772
}
732773

@@ -741,9 +782,11 @@ void readahead_expand(struct readahead_control *ractl,
741782
if (folio && !xa_is_value(folio))
742783
return; /* Folio apparently present */
743784

744-
folio = filemap_alloc_folio(gfp_mask, 0);
785+
folio = filemap_alloc_folio(gfp_mask, min_order);
745786
if (!folio)
746787
return;
788+
789+
index = mapping_align_index(mapping, index);
747790
if (filemap_add_folio(mapping, folio, index, gfp_mask) < 0) {
748791
folio_put(folio);
749792
return;
@@ -753,10 +796,10 @@ void readahead_expand(struct readahead_control *ractl,
753796
ractl->_workingset = true;
754797
psi_memstall_enter(&ractl->_pflags);
755798
}
756-
ractl->_nr_pages++;
799+
ractl->_nr_pages += min_nrpages;
757800
if (ra) {
758-
ra->size++;
759-
ra->async_size++;
801+
ra->size += min_nrpages;
802+
ra->async_size += min_nrpages;
760803
}
761804
}
762805
}

0 commit comments

Comments
 (0)