[PATCH 4/8] mm/zswap: convert the store path to take a folio and index
COLD31d
From: Tal Zussman <hidden>
Date: 2026-08-30 10:33:58
Also in:
linux-mm, lkml
Subsystem:
memory management, the rest, zswap compressed swap caching · Maintainers:
Andrew Morton, Linus Torvalds, Johannes Weiner, Yosry Ahmed, Nhat Pham
zswap_store_page() and zswap_compress() take a page that zswap_store() just derived from a folio, then convert back to a folio for the swap entry, memcg, and node. Pass the folio and page index down instead, and use sg_set_folio() and kmap_local_folio(). zswap_decompress() already takes a folio, so this also makes the two paths match. This removes the last struct page usage from the zswap store path and saves two calls to compound_head(). No functional change. Signed-off-by: Tal Zussman <redacted> --- mm/zswap.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/mm/zswap.c b/mm/zswap.c
index f3ae3c81e48e..3a6f89017646 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c@@ -824,8 +824,8 @@ static int zswap_cpu_comp_prepare(unsigned int cpu, struct hlist_node *node) return ret; } -static bool zswap_compress(struct page *page, struct zswap_entry *entry, - struct zswap_pool *pool) +static bool zswap_compress(struct folio *folio, long index, + struct zswap_entry *entry, struct zswap_pool *pool) { struct crypto_acomp_ctx *acomp_ctx; struct scatterlist input, output;
@@ -841,7 +841,7 @@ static bool zswap_compress(struct page *page, struct zswap_entry *entry, dst = acomp_ctx->buffer; sg_init_table(&input, 1); - sg_set_page(&input, page, PAGE_SIZE, 0); + sg_set_folio(&input, folio, PAGE_SIZE, index * PAGE_SIZE); sg_init_one(&output, dst, PAGE_SIZE); acomp_request_set_params(acomp_ctx->req, &input, &output, PAGE_SIZE, dlen);
@@ -870,8 +870,7 @@ static bool zswap_compress(struct page *page, struct zswap_entry *entry, */ if (comp_ret || !dlen || dlen >= PAGE_SIZE) { rcu_read_lock(); - if (!mem_cgroup_zswap_writeback_enabled( - folio_memcg(page_folio(page)))) { + if (!mem_cgroup_zswap_writeback_enabled(folio_memcg(folio))) { rcu_read_unlock(); comp_ret = comp_ret ? comp_ret : -EINVAL; goto unlock;
@@ -879,12 +878,12 @@ static bool zswap_compress(struct page *page, struct zswap_entry *entry, rcu_read_unlock(); comp_ret = 0; dlen = PAGE_SIZE; - dst = kmap_local_page(page); + dst = kmap_local_folio(folio, index * PAGE_SIZE); mapped = true; } gfp = GFP_NOWAIT | __GFP_NORETRY | __GFP_HIGHMEM | __GFP_MOVABLE; - handle = zs_malloc(pool->zs_pool, dlen, gfp, page_to_nid(page)); + handle = zs_malloc(pool->zs_pool, dlen, gfp, folio_nid(folio)); if (IS_ERR_VALUE(handle)) { alloc_ret = PTR_ERR((void *)handle); goto unlock;
@@ -1392,21 +1391,21 @@ static void shrink_worker(struct work_struct *w) * main API **********************************/ -static bool zswap_store_page(struct page *page, +static bool zswap_store_page(struct folio *folio, long index, struct obj_cgroup *objcg, struct zswap_pool *pool) { - swp_entry_t page_swpentry = page_swap_entry(page); + swp_entry_t page_swpentry = folio_swap_entry(folio, index); struct zswap_entry *entry, *old; /* allocate entry */ - entry = zswap_entry_cache_alloc(GFP_KERNEL, page_to_nid(page)); + entry = zswap_entry_cache_alloc(GFP_KERNEL, folio_nid(folio)); if (!entry) { zswap_reject_kmemcache_fail++; return false; } - if (!zswap_compress(page, entry, pool)) + if (!zswap_compress(folio, index, entry, pool)) goto compress_failed; old = xa_store(swap_zswap_tree(page_swpentry),
@@ -1515,9 +1514,7 @@ bool zswap_store(struct folio *folio) } for (index = 0; index < nr_pages; ++index) { - struct page *page = folio_page(folio, index); - - if (!zswap_store_page(page, objcg, pool)) + if (!zswap_store_page(folio, index, objcg, pool)) goto put_pool; }
--
2.39.5