mm: convert swap_cluster_readahead and swap_vma_readahead to return a folio
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Wed, 13 Dec 2023 21:58:42 +0000 (21:58 +0000)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 29 Dec 2023 19:58:32 +0000 (11:58 -0800)
shmem_swapin_cluster() immediately converts the page back to a folio, and
swapin_readahead() may as well call folio_file_page() once instead of
having each function call it.

[willy@infradead.org: avoid NULL pointer deref]
Link: https://lkml.kernel.org/r/ZYI7OcVlM1voKfBl@casper.infradead.org
Link: https://lkml.kernel.org/r/20231213215842.671461-14-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/shmem.c
mm/swap.h
mm/swap_state.c

index c62f904ba1ca1c4cd82c146bd95932cc0b585649..a4d388973021a94271a891134de652eaa648bc48 100644 (file)
@@ -1570,15 +1570,13 @@ static struct folio *shmem_swapin_cluster(swp_entry_t swap, gfp_t gfp,
 {
        struct mempolicy *mpol;
        pgoff_t ilx;
-       struct page *page;
+       struct folio *folio;
 
        mpol = shmem_get_pgoff_policy(info, index, 0, &ilx);
-       page = swap_cluster_readahead(swap, gfp, mpol, ilx);
+       folio = swap_cluster_readahead(swap, gfp, mpol, ilx);
        mpol_cond_put(mpol);
 
-       if (!page)
-               return NULL;
-       return page_folio(page);
+       return folio;
 }
 
 /*
index 82c68ccb5ab1a98b33aa3e6f10e3ed46ca9ed238..758c46ca671ed110ae8e25fad48196d3feed03dc 100644 (file)
--- a/mm/swap.h
+++ b/mm/swap.h
@@ -52,8 +52,8 @@ struct folio *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
 struct folio *__read_swap_cache_async(swp_entry_t entry, gfp_t gfp_flags,
                struct mempolicy *mpol, pgoff_t ilx, bool *new_page_allocated,
                bool skip_if_exists);
-struct page *swap_cluster_readahead(swp_entry_t entry, gfp_t flag,
-                                   struct mempolicy *mpol, pgoff_t ilx);
+struct folio *swap_cluster_readahead(swp_entry_t entry, gfp_t flag,
+               struct mempolicy *mpol, pgoff_t ilx);
 struct page *swapin_readahead(swp_entry_t entry, gfp_t flag,
                              struct vm_fault *vmf);
 
@@ -80,7 +80,7 @@ static inline void show_swap_cache_info(void)
 {
 }
 
-static inline struct page *swap_cluster_readahead(swp_entry_t entry,
+static inline struct folio *swap_cluster_readahead(swp_entry_t entry,
                        gfp_t gfp_mask, struct mempolicy *mpol, pgoff_t ilx)
 {
        return NULL;
index 97c8a950dd1814ced790cd0075f14a637f34ca30..e671266ad77241f461a17cbb2e486fe48a423f69 100644 (file)
@@ -620,7 +620,7 @@ static unsigned long swapin_nr_pages(unsigned long offset)
  * @mpol: NUMA memory allocation policy to be applied
  * @ilx: NUMA interleave index, for use only when MPOL_INTERLEAVE
  *
- * Returns the struct page for entry and addr, after queueing swapin.
+ * Returns the struct folio for entry and addr, after queueing swapin.
  *
  * Primitive swap readahead code. We simply read an aligned block of
  * (1 << page_cluster) entries in the swap area. This method is chosen
@@ -631,7 +631,7 @@ static unsigned long swapin_nr_pages(unsigned long offset)
  * are used for every page of the readahead: neighbouring pages on swap
  * are fairly likely to have been swapped out from the same node.
  */
-struct page *swap_cluster_readahead(swp_entry_t entry, gfp_t gfp_mask,
+struct folio *swap_cluster_readahead(swp_entry_t entry, gfp_t gfp_mask,
                                    struct mempolicy *mpol, pgoff_t ilx)
 {
        struct folio *folio;
@@ -683,7 +683,7 @@ skip:
        if (unlikely(page_allocated))
                swap_read_folio(folio, false, NULL);
        zswap_folio_swapin(folio);
-       return folio_file_page(folio, swp_offset(entry));
+       return folio;
 }
 
 int init_swap_address_space(unsigned int type, unsigned long nr_pages)
@@ -787,7 +787,7 @@ static void swap_ra_info(struct vm_fault *vmf,
  * @targ_ilx: NUMA interleave index, for use only when MPOL_INTERLEAVE
  * @vmf: fault information
  *
- * Returns the struct page for entry and addr, after queueing swapin.
+ * Returns the struct folio for entry and addr, after queueing swapin.
  *
  * Primitive swap readahead code. We simply read in a few pages whose
  * virtual addresses are around the fault address in the same vma.
@@ -795,9 +795,8 @@ static void swap_ra_info(struct vm_fault *vmf,
  * Caller must hold read mmap_lock if vmf->vma is not NULL.
  *
  */
-static struct page *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask,
-                                      struct mempolicy *mpol, pgoff_t targ_ilx,
-                                      struct vm_fault *vmf)
+static struct folio *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask,
+               struct mempolicy *mpol, pgoff_t targ_ilx, struct vm_fault *vmf)
 {
        struct blk_plug plug;
        struct swap_iocb *splug = NULL;
@@ -859,7 +858,7 @@ skip:
        if (unlikely(page_allocated))
                swap_read_folio(folio, false, NULL);
        zswap_folio_swapin(folio);
-       return folio_file_page(folio, swp_offset(entry));
+       return folio;
 }
 
 /**
@@ -879,14 +878,17 @@ struct page *swapin_readahead(swp_entry_t entry, gfp_t gfp_mask,
 {
        struct mempolicy *mpol;
        pgoff_t ilx;
-       struct page *page;
+       struct folio *folio;
 
        mpol = get_vma_policy(vmf->vma, vmf->address, 0, &ilx);
-       page = swap_use_vma_readahead() ?
+       folio = swap_use_vma_readahead() ?
                swap_vma_readahead(entry, gfp_mask, mpol, ilx, vmf) :
                swap_cluster_readahead(entry, gfp_mask, mpol, ilx);
        mpol_cond_put(mpol);
-       return page;
+
+       if (!folio)
+               return NULL;
+       return folio_file_page(folio, swp_offset(entry));
 }
 
 #ifdef CONFIG_SYSFS