Skip to content

Commit 69805ea

Browse files
ryncsnakpm00
authored andcommitted
mm/shmem, swap: never use swap cache and readahead for SWP_SYNCHRONOUS_IO
For SWP_SYNCHRONOUS_IO devices, if a cache bypassing THP swapin failed due to reasons like memory pressure, partially conflicting swap cache or ZSWAP enabled, shmem will fallback to cached order 0 swapin. Right now the swap cache still has a non-trivial overhead, and readahead is not helpful for SWP_SYNCHRONOUS_IO devices, so we should always skip the readahead and swap cache even if the swapin falls back to order 0. So handle the fallback logic without falling back to the cached read. Link: https://lkml.kernel.org/r/20250728075306.12704-6-ryncsn@gmail.com Signed-off-by: Kairui Song <kasong@tencent.com> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Baoquan He <bhe@redhat.com> Cc: Barry Song <baohua@kernel.org> Cc: Chris Li <chrisl@kernel.org> Cc: Dev Jain <dev.jain@arm.com> Cc: Hugh Dickins <hughd@google.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Nhat Pham <nphamcs@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 91ab656 commit 69805ea

1 file changed

Lines changed: 28 additions & 13 deletions

File tree

mm/shmem.c

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,13 +2019,15 @@ static struct folio *shmem_swap_alloc_folio(struct inode *inode,
20192019
struct shmem_inode_info *info = SHMEM_I(inode);
20202020
int nr_pages = 1 << order;
20212021
struct folio *new;
2022+
gfp_t alloc_gfp;
20222023
void *shadow;
20232024

20242025
/*
20252026
* We have arrived here because our zones are constrained, so don't
20262027
* limit chance of success with further cpuset and node constraints.
20272028
*/
20282029
gfp &= ~GFP_CONSTRAINT_MASK;
2030+
alloc_gfp = gfp;
20292031
if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
20302032
if (WARN_ON_ONCE(order))
20312033
return ERR_PTR(-EINVAL);
@@ -2040,19 +2042,22 @@ static struct folio *shmem_swap_alloc_folio(struct inode *inode,
20402042
if ((vma && unlikely(userfaultfd_armed(vma))) ||
20412043
!zswap_never_enabled() ||
20422044
non_swapcache_batch(entry, nr_pages) != nr_pages)
2043-
return ERR_PTR(-EINVAL);
2045+
goto fallback;
20442046

2045-
gfp = limit_gfp_mask(vma_thp_gfp_mask(vma), gfp);
2047+
alloc_gfp = limit_gfp_mask(vma_thp_gfp_mask(vma), gfp);
2048+
}
2049+
retry:
2050+
new = shmem_alloc_folio(alloc_gfp, order, info, index);
2051+
if (!new) {
2052+
new = ERR_PTR(-ENOMEM);
2053+
goto fallback;
20462054
}
2047-
2048-
new = shmem_alloc_folio(gfp, order, info, index);
2049-
if (!new)
2050-
return ERR_PTR(-ENOMEM);
20512055

20522056
if (mem_cgroup_swapin_charge_folio(new, vma ? vma->vm_mm : NULL,
2053-
gfp, entry)) {
2057+
alloc_gfp, entry)) {
20542058
folio_put(new);
2055-
return ERR_PTR(-ENOMEM);
2059+
new = ERR_PTR(-ENOMEM);
2060+
goto fallback;
20562061
}
20572062

20582063
/*
@@ -2067,7 +2072,9 @@ static struct folio *shmem_swap_alloc_folio(struct inode *inode,
20672072
*/
20682073
if (swapcache_prepare(entry, nr_pages)) {
20692074
folio_put(new);
2070-
return ERR_PTR(-EEXIST);
2075+
new = ERR_PTR(-EEXIST);
2076+
/* Try smaller folio to avoid cache conflict */
2077+
goto fallback;
20712078
}
20722079

20732080
__folio_set_locked(new);
@@ -2081,6 +2088,15 @@ static struct folio *shmem_swap_alloc_folio(struct inode *inode,
20812088
folio_add_lru(new);
20822089
swap_read_folio(new, NULL);
20832090
return new;
2091+
fallback:
2092+
/* Order 0 swapin failed, nothing to fallback to, abort */
2093+
if (!order)
2094+
return new;
2095+
entry.val += index - round_down(index, nr_pages);
2096+
alloc_gfp = gfp;
2097+
nr_pages = 1;
2098+
order = 0;
2099+
goto retry;
20842100
}
20852101

20862102
/*
@@ -2350,13 +2366,12 @@ static int shmem_swapin_folio(struct inode *inode, pgoff_t index,
23502366
}
23512367

23522368
/*
2353-
* Fallback to swapin order-0 folio unless the swap entry
2354-
* already exists.
2369+
* Direct swapin handled order 0 fallback already,
2370+
* if it failed, abort.
23552371
*/
23562372
error = PTR_ERR(folio);
23572373
folio = NULL;
2358-
if (error == -EEXIST)
2359-
goto failed;
2374+
goto failed;
23602375
}
23612376

23622377
/*

0 commit comments

Comments
 (0)