Matthew Wilcox (Oracle) [Mon, 16 Aug 2021 18:37:08 +0000 (14:37 -0400)]
fs/writeback: Convert wbc_account_cgroup_owner to take a folio
Convert all callers to do the folio conversion instead of doing it in
wbc_account_cgroup_owner(). All callers are in the writeback path,
so they're actually handling head pages and will soon be converted to
use folios.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Pass a folio from folio_mark_dirty() to the filesystem.
Include the address_space as a parameter as many implementations of
->dirty_folio want to examine the address space, and several are confused
as to whether ->dirty_folio can race with truncation or not.
Convert the return value from int to bool to reflect what's actually
being communicated.
mm/writeback: Convert set_page_dirty_lock to use folios
Keep the external API the same, but convert to a folio internally and
use the folio APIs. Reduces the number of calls to compound_page()
from three to one.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Tue, 12 Jan 2021 18:29:42 +0000 (13:29 -0500)]
fs: Convert invalidatepage to work on folios
No existing user of invalidatepage supports compound pages, so all pages
being passed to invalidatepage are folios by definition. Convert all
the implementations to use folios and also change the offset/length
parameters from unsigned int to size_t to make it clear they're byte
counters and not blocks.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Wed, 30 Dec 2020 22:51:56 +0000 (17:51 -0500)]
fs: Convert is_partially_uptodate to folios
Since the uptodate property is maintained on a per-folio basis, the
is_partially_uptodate method should also take a folio. Fix the types
at the same time so it's clear that it returns true/false and takes
the count in bytes, not blocks.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Thu, 24 Dec 2020 04:18:40 +0000 (23:18 -0500)]
fs: Convert page_mkwrite_check_truncate to folio_mkwrite_check_truncate
If a filesystem uses multi-page folios then its ->page_mkwrite() method
may be called with a tail page. If it is, the filesystem should treat
the entire folio as being made dirty, so it must iterate over every
extent covered by the folio in case it needs to be COWed.
Change both callers to pass the folio of the page.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Mon, 21 Dec 2020 14:37:16 +0000 (09:37 -0500)]
drm: Use folios in drm_gem_get_pages
Take one refcount per folio instead of per page. This will be a mild
performance improvement, but the real purpose of this is to only put
head pages in the pagevec in preparation for converting pagevecs to
only containing folios.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Tue, 15 Dec 2020 15:48:32 +0000 (10:48 -0500)]
fs: Change readpage to take a folio
We track the uptodate state on the entire folio, not individual
pages. That means the readpage should be passed a folio and told
to update the entire folio. Filesystems will not have multi-page
folios created for them until they indicate support for them by
setting the FS_MULTI_PAGE_FOLIO flag. Until they do, they can
assume that the folio being passed in contains a single page.
Also convert filler_t to take a folio as these two are tightly
intertwined.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Mon, 14 Dec 2020 20:16:44 +0000 (15:16 -0500)]
fs: Change page refcount rules for readahead
This brings ->readahead into line with ->readpage for the refcount on
struct page. It simplifies the various filesystems which implement
readahead and will reduce the number of atomic operations on the page
refcount in the future. This change is combined with the conversion of
readahead to use the struct folio in order to make unconverted filesystems
fail to compile.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Mon, 15 Mar 2021 02:47:59 +0000 (22:47 -0400)]
mm/memory: Use a folio in copy_pte_range
Removes three calls to compound_head() and two calls to check if the page
is devmap. Shrinks the kernel by 121 bytes overall (a few functions which
seem entirely unrelated grow, but copy_pte_range() shrinks by 232 bytes).
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Sun, 14 Mar 2021 10:41:59 +0000 (06:41 -0400)]
mm/memory: Turn cow_page into a folio
We always allocate a single page for cow_page, so by definition it's
a folio. Change its type and update all users. Saves 57 bytes of
text overall, including 175 bytes from do_cow_fault() and 77 from
do_fault().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Sat, 13 Mar 2021 04:57:44 +0000 (23:57 -0500)]
mm/filemap: Use a folio in filemap_page_mkwrite
This fixes a bug for tail pages. They always have a NULL mapping, so
the check would fail and we would never mark the page as dirty.
Ends up growing the kernel by 19 bytes although there will be fewer
calls to compound_head() dynamically.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Tue, 30 Mar 2021 18:35:53 +0000 (14:35 -0400)]
mm/swap: Convert put_pages_list to use folios
Pages on the LRU list cannot be tail pages as ->compound_head is in
a union with one of the words of the list_head, and they cannot be
ZONE_DEVICE pages as ->pgmap is in a union with the same word. So add
lru_to_folio() and use folio_put() in put_pages_list(). Saves 86 bytes
of text.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Thu, 17 Dec 2020 16:21:43 +0000 (11:21 -0500)]
mm/swap: Convert release_pages to use a folio internally
This function was already calling compound_head(), but now it can
cache the result of calling compound_head() and avoid calling it again.
Saves 112 bytes of text by avoiding various calls to compound_page()
and avoiding checks of PageTail.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Fri, 14 May 2021 14:21:42 +0000 (10:21 -0400)]
mm/swap: Add pagevec_add_and_move()
All but one of the callers of pagevec_add_and_need_flush() conditionally
call pagevec_lru_move_fn(). Simplify by passing the move_fn to
pagevec_add_and_move(). If the move_fn is NULL, then we want to call
__pagevec_lru_add() instead of pagevec_lru_move_fn().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
All the move functions now work in terms of folios, so convert the
page from the pagevec into a folio before calling them. Saves a few
dozen bytes of text.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Thu, 17 Dec 2020 04:41:15 +0000 (23:41 -0500)]
mm/swap: Add folio_deactivate_file
Convert deactivate_file_page() to folio_deactivate_file(). We can
use folio_get() instead of folio_try_get() because the only caller of
folio_deactivate_file() definitely has a reference to the folio already.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Convert migrate_misplaced_transhuge_page() and alloc_migration_target()
to allocate folios instead of pages. Probably wants to get split up
and done differently.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Sat, 8 May 2021 03:40:19 +0000 (23:40 -0400)]
mm/khugepaged: Allocate folios
khugepaged only wants to deal in terms of folios, so switch to
using the folio allocation functions. This eliminates the calls to
prep_transhuge_page() and saves dozens of bytes of text.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Mon, 17 May 2021 12:58:51 +0000 (08:58 -0400)]
mm: Allow pagevecs to contain a folio
Use a union to allow pagevecs to contain an array of folios instead of
pages. Some pagevecs currently contain tail pages, so be sure that all
providers populate with folios before a particular consumer is converted.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Sat, 8 May 2021 14:22:02 +0000 (10:22 -0400)]
mm/shmem: Convert shmem_getpage_gfp to use a folio
Rename shmem_alloc_and_acct_page() to shmem_alloc_and_acct_folio() and
have it return a folio, then use a folio throuughout shmem_getpage_gfp().
It continues to return a struct page.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Fri, 7 May 2021 21:24:45 +0000 (17:24 -0400)]
mm/shmem: Convert shmem_alloc_and_acct_page to use a folio
Convert shmem_alloc_hugepage() to return the folio that it uses
and use a folio throughout shmem_alloc_and_acct_page(). Continue
to return a page from shmem_alloc_and_acct_page() for now.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Thu, 6 May 2021 15:41:34 +0000 (11:41 -0400)]
mm/shmem: Turn shmem_alloc_page() into shmem_alloc_folio()
Call vma_alloc_folio() directly instead of alloc_page_vma().
It's a bit messy in the callers, but they're about to be
cleaned up when they get converted to folios.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Thu, 6 May 2021 12:22:16 +0000 (08:22 -0400)]
mm/shmem: Use a folio in shmem_unused_huge_shrink
When calling split_huge_page() we usually have to find the precise page,
but that's not necessary here because we only need to unlock and put
the folio afterwards. Saves 231 bytes of text (20% of this function).
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Tue, 22 Dec 2020 12:55:18 +0000 (07:55 -0500)]
mm/page_alloc: Convert alloc_pages_vma to vma_alloc_folio
Remove the alloc_hugepage_vma() wrapper, and convert all callers to use
a folio. The callers no longer need to call prep_transhuge_page().
Saves 27 bytes of kernel text (some functions expand, others shrink).
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Thu, 6 May 2021 12:42:34 +0000 (08:42 -0400)]
mm/swap: Add folio_throttle_swaprate
The only use of the page argument to cgroup_throttle_swaprate() is to
get the node ID, and this will be the same for all pages in the folio,
so there's no need to convert the page to a folio before calling it.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Wed, 26 May 2021 17:03:12 +0000 (13:03 -0400)]
mm,fs: Split dump_mapping() out from dump_page()
dump_mapping() is a big chunk of dump_page(), and it'd be handy to be
able to call it when we don't have a struct page. Split it out and move
it to fs/inode.c. Take the opportunity to simplify some of the debug
messages a little.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
do_page_cache_ra() was being exposed for the benefit of
do_sync_mmap_readahead(). Switch it over to page_cache_ra_order()
partly because it's a better interface but mostly for the benefit of
the next patch.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Wed, 5 Feb 2020 16:27:01 +0000 (11:27 -0500)]
mm/readahead: Add multi-page folio readahead
If the filesystem supports multi-page folios, allocate larger pages in
the readahead code when it seems worth doing. The heuristic for choosing
larger page sizes will surely need some tuning, but this aggressive
ramp-up has been good for testing.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
mm/filemap: Allow multi-page folios to be added to the page cache
We return -EEXIST if there are any non-shadow entries in the page
cache in the range covered by the folio. If there are multiple
shadow entries in the range, we set *shadowp to one of them (currently
the one at the highest index). If that turns out to be the wrong
answer, we can implement something more complex. This is mostly
modelled after the equivalent function in the shmem code.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
mm/vmscan: Free non-shmem THPs without splitting them
We have to allocate memory in order to split a file-backed page,
so it's not a good idea to split them. It also doesn't work for XFS
because pages have an extra reference count from page_has_private() and
split_huge_page() expects that reference to have already been removed.
Unfortunately, we still have to split shmem THPs because we can't handle
swapping out an entire THP yet.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Sun, 28 Jun 2020 02:19:08 +0000 (22:19 -0400)]
mm: Use multi-index entries in the page cache
We currently store order-N THPs as 2^N consecutive entries. While this
consumes rather more memory than necessary, it also turns out to be buggy.
A writeback operation which starts in the middle of a dirty THP will not
notice as the dirty bit is only set on the head index. With multi-index
entries, the dirty bit will be found no matter where in the THP the
iteration starts.
This does end up simplifying the page cache slightly, although not as
much as I had hoped.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
mm/filemap: Return only head pages from find_get_entries
All callers now expect head (and base) pages, and can handle multiple
head pages in a single batch, so make find_get_entries() behave that way.
Also take the opportunity to make it use the pagevec infrastructure
instead of open-coding how pvecs behave. This has the side-effect of
being able to append to a pagevec with existing contents, although we
don't make use of that functionality anywhere yet.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: William Kucharski <william.kucharski@oracle.com>
Matthew Wilcox (Oracle) [Wed, 27 May 2020 21:59:22 +0000 (17:59 -0400)]
mm/truncate,shmem: Handle truncates that split THPs
Handle THP splitting in the parts of the truncation functions which
already handle partial pages. Factor all that code out into a new
function called truncate_inode_partial_page().
We lose the easy 'bail out' path if a truncate or hole punch is entirely
within a single page. We can add some more complex logic to restore
the optimisation if it proves to be worthwhile.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: William Kucharski <william.kucharski@oracle.com>
Matthew Wilcox (Oracle) [Mon, 14 Dec 2020 12:57:07 +0000 (07:57 -0500)]
fs: Convert vfs_dedupe_file_range_compare to folios
We still only operate on a single page of data at a time due to using
kmap(). A more complex implementation would work on each page in a folio,
but it's not clear that such a complex implementation would be worthwhile.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Tue, 25 May 2021 14:11:25 +0000 (10:11 -0400)]
mm/filemap: Remove PageHWPoison check from next_uptodate_page()
Pages are individually marked as suffering from hardware poisoning.
Checking that the head page is not hardware poisoned doesn't make
sense; we might be after a subpage. We check each page individually
before we use it, so this was an optimisation gone wrong.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Wed, 16 Dec 2020 16:45:30 +0000 (11:45 -0500)]
mm/filemap: Add read_cache_folio and read_mapping_folio
Reimplement read_cache_page() as a wrapper around read_cache_folio().
Saves over 400 bytes of text from do_read_cache_folio() which more
thn makes up for the extra 100 bytes of text added to the various
wrapper functions.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Wed, 10 Mar 2021 15:46:41 +0000 (10:46 -0500)]
mm/filemap: Convert filemap_fault to folio
Instead of converting back-and-forth between the actual page and
the head page, just convert once at the end of the function where we
set the vmf->page. Saves 241 bytes of text, or 15% of the size of
filemap_fault().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Wed, 10 Mar 2021 15:19:30 +0000 (10:19 -0500)]
mm/filemap: Convert filemap_read_page to take a folio
One of the callers already had a folio; the other two grow by a few
bytes, but filemap_read_page() shrinks by 50 bytes for a net reduction
of 27 bytes.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Sat, 6 Mar 2021 21:38:38 +0000 (16:38 -0500)]
mm/filemap: Convert find_get_pages_contig to folios
None of the callers of find_get_pages_contig() want tail pages. They all
use order-0 pages today, but if they were converted, they'd want folios.
So just remove the call to find_subpage() instead of replacing it with
folio_page().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Sun, 9 May 2021 13:33:42 +0000 (09:33 -0400)]
mm/filemap: Add filemap_remove_folio and __filemap_remove_folio
Reimplement __delete_from_page_cache() as a wrapper around
__filemap_remove_folio() and delete_from_page_cache() as a wrapper
around filemap_remove_folio(). Remove the EXPORT_SYMBOL as
delete_from_page_cache() was not used by any in-tree modules.
Convert page_cache_free_page() into filemap_free_folio().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
mm/filemap: Convert tracing of page cache operations to folio
Pass the folio instead of a page. The page was already implicitly a
folio as it accessed page->mapping directly. Add the order of the folio
to the tracepoint, as this is important information. Also drop printing
the address of the struct page as the pfn provides better information
than the struct page address.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Sun, 9 May 2021 00:04:05 +0000 (20:04 -0400)]
mm/filemap: Convert unaccount_page_cache_page to filemap_unaccount_folio
Use folios throughout filemap_unaccount_folio(), except for the bug
handling path which would need to use total_mapcount(), which is currently
only defined for builds with THP enabled.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Sat, 8 May 2021 04:35:49 +0000 (00:35 -0400)]
mm/filemap: Convert page_cache_delete to take a folio
It was already assuming a head page, so this is a straightforward
conversion. Convert the one caller to call page_folio(), even though
it must currently be passing in a head page.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Tue, 17 Aug 2021 03:36:31 +0000 (23:36 -0400)]
mm/filemap: Add folio_put_wait_locked()
Convert all three callers of put_and_wait_on_page_locked() to
folio_put_wait_locked(). This shrinks the kernel overall by 19 bytes.
filemap_update_page() shrinks by 19 bytes while __migration_entry_wait()
is unchanged. folio_put_wait_locked() is 14 bytes smaller than
put_and_wait_on_page_locked(), but pmd_migration_entry_wait() grows by
14 bytes. It removes the assumption from pmd_migration_entry_wait()
that pages cannot be larger than a PMD (which is true today, but
may be interesting to explore in the future).
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Matthew Wilcox (Oracle) [Wed, 13 Jan 2021 15:48:49 +0000 (10:48 -0500)]
iomap: Support multi-page folios in invalidatepage
If we're punching a hole in a multi-page folio, we need to remove the
per-folio iomap data as the folio is about to be split and each page will
need its own. If a dirty folio is only partially-uptodate, the iomap
data contains the information about which blocks cannot be written back,
so assert that a dirty folio is fully uptodate.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>