From: Domenico Cerasuolo <cerasuolodomenico@gmail.com>
To: vitaly.wool@konsulko.com, minchan@kernel.org,
senozhatsky@chromium.org, yosryahmed@google.com,
linux-mm@kvack.org
Cc: ddstreet@ieee.org, sjenning@redhat.com, nphamcs@gmail.com,
hannes@cmpxchg.org, akpm@linux-foundation.org,
linux-kernel@vger.kernel.org, kernel-team@meta.com,
Domenico Cerasuolo <cerasuolodomenico@gmail.com>
Subject: [PATCH v3 6/7] mm: zswap: simplify writeback function
Date: Mon, 12 Jun 2023 11:38:14 +0200 [thread overview]
Message-ID: <20230612093815.133504-7-cerasuolodomenico@gmail.com> (raw)
In-Reply-To: <20230612093815.133504-1-cerasuolodomenico@gmail.com>
zswap_writeback_entry() used to be a callback for the backends, which
don't know about struct zswap_entry.
Now that the only user is the generic zswap LRU reclaimer, it can be
simplified: pass the pinned zswap_entry directly, and consolidate the
refcount management in the shrink function.
Tested-by: Yosry Ahmed <yosryahmed@google.com>
Signed-off-by: Domenico Cerasuolo <cerasuolodomenico@gmail.com>
---
mm/zswap.c | 70 +++++++++++++++---------------------------------------
1 file changed, 19 insertions(+), 51 deletions(-)
diff --git a/mm/zswap.c b/mm/zswap.c
index a4f8c20e161b..3a6b07a19262 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -254,7 +254,8 @@ static bool zswap_has_pool;
pr_debug("%s pool %s/%s\n", msg, (p)->tfm_name, \
zpool_get_type((p)->zpool))
-static int zswap_writeback_entry(struct zpool *pool, unsigned long handle);
+static int zswap_writeback_entry(struct zswap_entry *entry, struct zswap_header *zhdr,
+ struct zswap_tree *tree);
static int zswap_pool_get(struct zswap_pool *pool);
static void zswap_pool_put(struct zswap_pool *pool);
@@ -635,7 +636,7 @@ static int zswap_reclaim_entry(struct zswap_pool *pool)
zswap_entry_get(entry);
spin_unlock(&tree->lock);
- ret = zswap_writeback_entry(pool->zpool, entry->handle);
+ ret = zswap_writeback_entry(entry, zhdr, tree);
spin_lock(&tree->lock);
if (ret) {
@@ -643,8 +644,17 @@ static int zswap_reclaim_entry(struct zswap_pool *pool)
spin_lock(&pool->lru_lock);
list_move(&entry->lru, &pool->lru);
spin_unlock(&pool->lru_lock);
+ goto put_unlock;
}
+ /* Check for invalidate() race */
+ if (entry != zswap_rb_search(&tree->rbroot, swpoffset))
+ goto put_unlock;
+
+ /* Drop base reference */
+ zswap_entry_put(tree, entry);
+
+put_unlock:
/* Drop local reference */
zswap_entry_put(tree, entry);
unlock:
@@ -1045,16 +1055,14 @@ static int zswap_get_swap_cache_page(swp_entry_t entry,
* the swap cache, the compressed version stored by zswap can be
* freed.
*/
-static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
+static int zswap_writeback_entry(struct zswap_entry *entry, struct zswap_header *zhdr,
+ struct zswap_tree *tree)
{
- struct zswap_header *zhdr;
- swp_entry_t swpentry;
- struct zswap_tree *tree;
- pgoff_t offset;
- struct zswap_entry *entry;
+ swp_entry_t swpentry = zhdr->swpentry;
struct page *page;
struct scatterlist input, output;
struct crypto_acomp_ctx *acomp_ctx;
+ struct zpool *pool = entry->pool->zpool;
u8 *src, *tmp = NULL;
unsigned int dlen;
@@ -1069,25 +1077,6 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
return -ENOMEM;
}
- /* extract swpentry from data */
- zhdr = zpool_map_handle(pool, handle, ZPOOL_MM_RO);
- swpentry = zhdr->swpentry; /* here */
- tree = zswap_trees[swp_type(swpentry)];
- offset = swp_offset(swpentry);
- zpool_unmap_handle(pool, handle);
-
- /* find and ref zswap entry */
- spin_lock(&tree->lock);
- entry = zswap_entry_find_get(&tree->rbroot, offset);
- if (!entry) {
- /* entry was invalidated */
- spin_unlock(&tree->lock);
- kfree(tmp);
- return 0;
- }
- spin_unlock(&tree->lock);
- BUG_ON(offset != entry->offset);
-
/* try to allocate swap cache page */
switch (zswap_get_swap_cache_page(swpentry, &page)) {
case ZSWAP_SWAPCACHE_FAIL: /* no memory or invalidate happened */
@@ -1121,12 +1110,12 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
acomp_ctx = raw_cpu_ptr(entry->pool->acomp_ctx);
dlen = PAGE_SIZE;
- zhdr = zpool_map_handle(pool, handle, ZPOOL_MM_RO);
+ zhdr = zpool_map_handle(pool, entry->handle, ZPOOL_MM_RO);
src = (u8 *)zhdr + sizeof(struct zswap_header);
if (!zpool_can_sleep_mapped(pool)) {
memcpy(tmp, src, entry->length);
src = tmp;
- zpool_unmap_handle(pool, handle);
+ zpool_unmap_handle(pool, entry->handle);
}
mutex_lock(acomp_ctx->mutex);
@@ -1141,7 +1130,7 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
if (!zpool_can_sleep_mapped(pool))
kfree(tmp);
else
- zpool_unmap_handle(pool, handle);
+ zpool_unmap_handle(pool, entry->handle);
BUG_ON(ret);
BUG_ON(dlen != PAGE_SIZE);
@@ -1158,23 +1147,7 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
put_page(page);
zswap_written_back_pages++;
- spin_lock(&tree->lock);
- /* drop local reference */
- zswap_entry_put(tree, entry);
-
- /*
- * There are two possible situations for entry here:
- * (1) refcount is 1(normal case), entry is valid and on the tree
- * (2) refcount is 0, entry is freed and not on the tree
- * because invalidate happened during writeback
- * search the tree and free the entry if find entry
- */
- if (entry == zswap_rb_search(&tree->rbroot, offset))
- zswap_entry_put(tree, entry);
- spin_unlock(&tree->lock);
-
return ret;
-
fail:
if (!zpool_can_sleep_mapped(pool))
kfree(tmp);
@@ -1183,13 +1156,8 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
* if we get here due to ZSWAP_SWAPCACHE_EXIST
* a load may be happening concurrently.
* it is safe and okay to not free the entry.
- * if we free the entry in the following put
* it is also okay to return !0
*/
- spin_lock(&tree->lock);
- zswap_entry_put(tree, entry);
- spin_unlock(&tree->lock);
-
return ret;
}
--
2.34.1
next prev parent reply other threads:[~2023-06-12 9:55 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-12 9:38 [PATCH v3 0/7] mm: zswap: move writeback LRU from zpool to zswap Domenico Cerasuolo
2023-06-12 9:38 ` [PATCH v3 1/7] mm: zswap: add pool shrinking mechanism Domenico Cerasuolo
2023-06-12 13:34 ` Johannes Weiner
2023-06-12 18:18 ` Yosry Ahmed
2023-06-18 4:38 ` Sergey Senozhatsky
2023-06-18 4:48 ` Yosry Ahmed
2023-06-18 5:25 ` Sergey Senozhatsky
2023-06-18 5:28 ` Yosry Ahmed
2023-06-18 5:30 ` Sergey Senozhatsky
2023-06-18 5:31 ` Yosry Ahmed
2023-06-12 9:38 ` [PATCH v3 2/7] mm: zswap: remove page reclaim logic from zbud Domenico Cerasuolo
2023-06-12 9:38 ` [PATCH v3 3/7] mm: zswap: remove page reclaim logic from z3fold Domenico Cerasuolo
2023-06-12 9:38 ` [PATCH v3 4/7] mm: zswap: remove page reclaim logic from zsmalloc Domenico Cerasuolo
2023-06-12 9:38 ` [PATCH v3 5/7] mm: zswap: remove shrink from zpool interface Domenico Cerasuolo
2023-06-12 9:38 ` Domenico Cerasuolo [this message]
2023-06-12 13:38 ` [PATCH v3 6/7] mm: zswap: simplify writeback function Johannes Weiner
2023-06-12 9:38 ` [PATCH v3 7/7] mm: zswap: remove zswap_header Domenico Cerasuolo
2023-06-12 18:47 ` Johannes Weiner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230612093815.133504-7-cerasuolodomenico@gmail.com \
--to=cerasuolodomenico@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=ddstreet@ieee.org \
--cc=hannes@cmpxchg.org \
--cc=kernel-team@meta.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=minchan@kernel.org \
--cc=nphamcs@gmail.com \
--cc=senozhatsky@chromium.org \
--cc=sjenning@redhat.com \
--cc=vitaly.wool@konsulko.com \
--cc=yosryahmed@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®