The patch titled Subject: mm/zswap: refactor zswap_store_page() has been added to the -mm mm-hotfixes-unstable branch. Its filename is mm-zswap-fix-inconsistency-when-zswap_store_page-fails-fix.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-zswap-fix-inconsistency-when-zswap_store_page-fails-fix.patch This patch will later appear in the mm-hotfixes-unstable branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via the mm-everything branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there every 2-3 working days ------------------------------------------------------ From: Hyeonggon Yoo <42.hyeyoo@xxxxxxxxx> Subject: mm/zswap: refactor zswap_store_page() Date: Fri, 31 Jan 2025 17:20:37 +0900 Change zswap_store_page() to return a boolean value, where true indicates the page is successfully stored in zswap, and false otherwise. Since zswap_store_page() no longer returns the size of the entry, remove 'bytes' variable from zswap_store(), and jump to the put_pool label when it fails. Move the objcg charging and the incrementing of zswap_store_pages just after the tree store is successful. At that point, there's no chance of failure, and the freeing path will certainly uncharge zswap memory and decrement the counter. Link: https://lkml.kernel.org/r/20250131082037.2426-1-42.hyeyoo@xxxxxxxxx Signed-off-by: Hyeonggon Yoo <42.hyeyoo@xxxxxxxxx> Suggested-by: Yosry Ahmed <yosry.ahmed@xxxxxxxxx> Cc: Chengming Zhou <chengming.zhou@xxxxxxxxx> Cc: Johannes Weiner <hannes@xxxxxxxxxxx> Cc: Kanchana P Sridhar <kanchana.p.sridhar@xxxxxxxxx> Cc: Nhat Pham <nphamcs@xxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- mm/zswap.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) --- a/mm/zswap.c~mm-zswap-fix-inconsistency-when-zswap_store_page-fails-fix +++ a/mm/zswap.c @@ -1445,9 +1445,9 @@ resched: * main API **********************************/ -static ssize_t zswap_store_page(struct page *page, - struct obj_cgroup *objcg, - struct zswap_pool *pool) +static bool zswap_store_page(struct page *page, + struct obj_cgroup *objcg, + struct zswap_pool *pool) { swp_entry_t page_swpentry = page_swap_entry(page); struct zswap_entry *entry, *old; @@ -1456,7 +1456,7 @@ static ssize_t zswap_store_page(struct p entry = zswap_entry_cache_alloc(GFP_KERNEL, page_to_nid(page)); if (!entry) { zswap_reject_kmemcache_fail++; - return -EINVAL; + return false; } if (!zswap_compress(page, entry, pool)) @@ -1483,13 +1483,17 @@ static ssize_t zswap_store_page(struct p /* * The entry is successfully compressed and stored in the tree, there is - * no further possibility of failure. Grab refs to the pool and objcg. - * These refs will be dropped by zswap_entry_free() when the entry is - * removed from the tree. + * no further possibility of failure. Grab refs to the pool and objcg, + * charge zswap memory, and increment zswap_stored_pages. + * The opposite actions will be performed by zswap_entry_free() + * when the entry is removed from the tree. */ zswap_pool_get(pool); - if (objcg) + if (objcg) { obj_cgroup_get(objcg); + obj_cgroup_charge_zswap(objcg, entry->length); + } + atomic_long_inc(&zswap_stored_pages); /* * We finish initializing the entry while it's already in xarray. @@ -1504,22 +1508,19 @@ static ssize_t zswap_store_page(struct p entry->pool = pool; entry->swpentry = page_swpentry; entry->objcg = objcg; - if (objcg) - obj_cgroup_charge_zswap(objcg, entry->length); entry->referenced = true; if (entry->length) { INIT_LIST_HEAD(&entry->lru); zswap_lru_add(&zswap_list_lru, entry); } - atomic_long_inc(&zswap_stored_pages); - return entry->length; + return true; store_failed: zpool_free(pool->zpool, entry->handle); compress_failed: zswap_entry_cache_free(entry); - return -EINVAL; + return false; } bool zswap_store(struct folio *folio) @@ -1566,10 +1567,8 @@ bool zswap_store(struct folio *folio) for (index = 0; index < nr_pages; ++index) { struct page *page = folio_page(folio, index); - ssize_t bytes; - bytes = zswap_store_page(page, objcg, pool); - if (bytes < 0) + if (!zswap_store_page(page, objcg, pool)) goto put_pool; } _ Patches currently in -mm which might be from 42.hyeyoo@xxxxxxxxx are mm-zsmalloc-add-__maybe_unused-attribute-for-is_first_zpdesc.patch mm-zswap-fix-inconsistency-when-zswap_store_page-fails.patch mm-zswap-fix-inconsistency-when-zswap_store_page-fails-fix.patch