This was the original destination of the prior patch series. I have a few places in the THP patch set which add calls to find_get_entry() and it annoyed me that I was carefully calling find_subpage() in find_get_entry() only to immediately call thp_head() to get back to the original subpage. I'm not sure it's worth applying this as part of the patch series, which is why I left it out earlier. There are going to be some other functions which return only head pages. I currently have a find_get_heads_range_tag() in my tree, which is probably going to become find_get_entries_range_tag(). --- 8< --- mm: Return head pages from find_get_entry All the callers of find_get_entry() call compound_head() to get back to the head page. They still do because compound_head() calls are hidden in such functions as put_page() and lock_page(), but it lets us get rid of a few calls. diff --git a/mm/filemap.c b/mm/filemap.c index f0ae9a6308cb..7e0a7d02e7aa 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1487,9 +1487,9 @@ EXPORT_SYMBOL(page_cache_prev_miss); /** * find_get_entry - find and get a page cache entry * @mapping: the address_space to search - * @offset: the page cache index + * @index: the page cache index * - * Looks up the page cache slot at @mapping & @offset. If there is a + * Looks up the page cache slot at @mapping & @index. If there is a * page cache page, it is returned with an increased refcount. * * If the slot holds a shadow entry of a previously evicted page, or a @@ -1497,9 +1497,9 @@ EXPORT_SYMBOL(page_cache_prev_miss); * * Return: the found page or shadow entry, %NULL if nothing is found. */ -struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) +struct page *find_get_entry(struct address_space *mapping, pgoff_t index) { - XA_STATE(xas, &mapping->i_pages, offset); + XA_STATE(xas, &mapping->i_pages, index); struct page *page; rcu_read_lock(); @@ -1527,7 +1527,6 @@ struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) put_page(page); goto repeat; } - page = find_subpage(page, offset); out: rcu_read_unlock(); @@ -1537,9 +1536,9 @@ struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) /** * find_lock_entry - locate, pin and lock a page cache entry * @mapping: the address_space to search - * @offset: the page cache index + * @index: the page cache index * - * Looks up the page cache slot at @mapping & @offset. If there is a + * Looks up the page cache slot at @mapping & @index. If there is a * page cache page, it is returned locked and with an increased * refcount. * @@ -1550,21 +1549,22 @@ struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) * * Return: the found page or shadow entry, %NULL if nothing is found. */ -struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset) +struct page *find_lock_entry(struct address_space *mapping, pgoff_t index) { struct page *page; repeat: - page = find_get_entry(mapping, offset); + page = find_get_entry(mapping, index); if (page && !xa_is_value(page)) { lock_page(page); /* Has the page been truncated? */ - if (unlikely(page_mapping(page) != mapping)) { + if (unlikely(page->mapping != mapping)) { unlock_page(page); put_page(page); goto repeat; } - VM_BUG_ON_PAGE(page_to_pgoff(page) != offset, page); + page = find_subpage(page, index); + VM_BUG_ON_PAGE(page_to_pgoff(page) != index, page); } return page; } @@ -1620,12 +1620,13 @@ struct page *pagecache_get_page(struct address_space *mapping, pgoff_t index, } /* Has the page been truncated? */ - if (unlikely(compound_head(page)->mapping != mapping)) { + if (unlikely(page->mapping != mapping)) { unlock_page(page); put_page(page); goto repeat; } - VM_BUG_ON_PAGE(page->index != index, page); + VM_BUG_ON_PAGE(page->index != + (index & ~(thp_nr_pages(page) - 1)), page); } if (fgp_flags & FGP_ACCESSED) @@ -1666,7 +1667,7 @@ struct page *pagecache_get_page(struct address_space *mapping, pgoff_t index, unlock_page(page); } - return page; + return find_subpage(page, index); } EXPORT_SYMBOL(pagecache_get_page); diff --git a/mm/mincore.c b/mm/mincore.c index abc24ca6f0f7..cda857110d44 100644 --- a/mm/mincore.c +++ b/mm/mincore.c @@ -58,8 +58,10 @@ struct page *find_get_swap_page(struct address_space *mapping, pgoff_t index) struct swap_info_struct *si; struct page *page = find_get_entry(mapping, index); - if (!xa_is_value(page)) + if (!page) return page; + if (!xa_is_value(page)) + return find_subpage(page, index); if (!IS_ENABLED(CONFIG_SWAP) || !shmem_mapping(mapping)) return NULL;