Four folio-related fixes for 5.19:

- Mark a folio accessed at the right time (Yu Kuai)
 
  - Fix a race for folios being replaced in the middle of a read (Brian Foster)
 
  - Clear folio->private in more places (Xiubo Li)
 
  - Take the invalidate_lock in page_cache_ra_order() (Alistair Popple)
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEejHryeLBw/spnjHrDpNsjXcpgj4FAmK0l3kACgkQDpNsjXcp
 gj7vAAf8CLJqVFaJHXDhpvCKVqenn7yufrf9AQg78JsMa1Bym8ZjwYS+60F3znET
 UPIqcjPgqFQI17c0NhcB10ZqnwlVUsFa+bQC1HIwWEXrFJ3G2JKftrMg5PeESyDI
 ZzFQWyjFtNtMUG5Tl5FYjG+OQ6U71+7zr136SmxbcMgrGObkOR40DQ4nzkswMuU3
 F8sJJ9lULdMPS/xtviQwNeVAfz9brteCb5EU3xFw2Hxx8S+nWEguHSFV7Yo52KXg
 pyvOlxEr7FmsMhiwltL/yZbUS8yoQZAp1NacH843C3t2OE3grKrLWAR/CnCpvCjn
 atMeFS8QuXUqtWOgMYxfUYmr2i1GBA==
 =eAFT
 -----END PGP SIGNATURE-----

Merge tag 'folio-5.19b' of git://git.infradead.org/users/willy/pagecache

Pull pagecache fixes from Matthew Wilcox:
 "Four folio-related fixes for 5.19:

   - Mark a folio accessed at the right time (Yu Kuai)

   - Fix a race for folios being replaced in the middle of a read (Brian
     Foster)

   - Clear folio->private in more places (Xiubo Li)

   - Take the invalidate_lock in page_cache_ra_order() (Alistair Popple)"

* tag 'folio-5.19b' of git://git.infradead.org/users/willy/pagecache:
  filemap: Fix serialization adding transparent huge pages to page cache
  mm: Clear page->private when splitting or migrating a page
  filemap: Handle sibling entries in filemap_get_read_batch()
  filemap: Correct the conditions for marking a folio as accessed
This commit is contained in:
Linus Torvalds 2022-06-23 12:16:14 -05:00
commit 16e4bce6de
4 changed files with 16 additions and 3 deletions

View File

@ -2385,6 +2385,8 @@ static void filemap_get_read_batch(struct address_space *mapping,
continue;
if (xas.xa_index > max || xa_is_value(folio))
break;
if (xa_is_sibling(folio))
break;
if (!folio_try_get_rcu(folio))
goto retry;
@ -2629,6 +2631,13 @@ static int filemap_get_pages(struct kiocb *iocb, struct iov_iter *iter,
return err;
}
static inline bool pos_same_folio(loff_t pos1, loff_t pos2, struct folio *folio)
{
unsigned int shift = folio_shift(folio);
return (pos1 >> shift == pos2 >> shift);
}
/**
* filemap_read - Read data from the page cache.
* @iocb: The iocb to read.
@ -2700,11 +2709,11 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter,
writably_mapped = mapping_writably_mapped(mapping);
/*
* When a sequential read accesses a page several times, only
* When a read accesses the same folio several times, only
* mark it as accessed the first time.
*/
if (iocb->ki_pos >> PAGE_SHIFT !=
ra->prev_pos >> PAGE_SHIFT)
if (!pos_same_folio(iocb->ki_pos, ra->prev_pos - 1,
fbatch.folios[0]))
folio_mark_accessed(fbatch.folios[0]);
for (i = 0; i < folio_batch_count(&fbatch); i++) {

View File

@ -2377,6 +2377,7 @@ static void __split_huge_page_tail(struct page *head, int tail,
page_tail);
page_tail->mapping = head->mapping;
page_tail->index = head->index + tail;
page_tail->private = 0;
/* Page flags must be visible before we make the page non-compound. */
smp_wmb();

View File

@ -1106,6 +1106,7 @@ static int unmap_and_move(new_page_t get_new_page,
if (!newpage)
return -ENOMEM;
newpage->private = 0;
rc = __unmap_and_move(page, newpage, force, mode);
if (rc == MIGRATEPAGE_SUCCESS)
set_page_owner_migrate_reason(newpage, reason);

View File

@ -510,6 +510,7 @@ void page_cache_ra_order(struct readahead_control *ractl,
new_order--;
}
filemap_invalidate_lock_shared(mapping);
while (index <= limit) {
unsigned int order = new_order;
@ -536,6 +537,7 @@ void page_cache_ra_order(struct readahead_control *ractl,
}
read_pages(ractl);
filemap_invalidate_unlock_shared(mapping);
/*
* If there were already pages in the page cache, then we may have