linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Nhat Pham <nphamcs@gmail.com>
To: akpm@linux-foundation.org
Cc: hannes@cmpxchg.org, linux-mm@kvack.org,
	linux-kernel@vger.kernel.org, minchan@kernel.org,
	ngupta@vflare.org, senozhatsky@chromium.org, sjenning@redhat.com,
	ddstreet@ieee.org, vitaly.wool@konsulko.com
Subject: [PATCH v6 1/6] zswap: fix writeback lock ordering for zsmalloc
Date: Fri, 18 Nov 2022 16:15:31 -0800	[thread overview]
Message-ID: <20221119001536.2086599-2-nphamcs@gmail.com> (raw)
In-Reply-To: <20221119001536.2086599-1-nphamcs@gmail.com>

From: Johannes Weiner <hannes@cmpxchg.org>

zswap's customary lock order is tree->lock before pool->lock, because
the tree->lock protects the entries' refcount, and the free callbacks in
the backends acquire their respective pool locks to dispatch the backing
object. zsmalloc's map callback takes the pool lock, so zswap must not
grab the tree->lock while a handle is mapped. This currently only
happens during writeback, which isn't implemented for zsmalloc. In
preparation for it, move the tree->lock section out of the mapped entry
section

Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Nhat Pham <nphamcs@gmail.com>
---
 mm/zswap.c | 37 ++++++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/mm/zswap.c b/mm/zswap.c
index 2d48fd59cc7a..2d69c1d678fe 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -958,7 +958,7 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
 	};

 	if (!zpool_can_sleep_mapped(pool)) {
-		tmp = kmalloc(PAGE_SIZE, GFP_ATOMIC);
+		tmp = kmalloc(PAGE_SIZE, GFP_KERNEL);
 		if (!tmp)
 			return -ENOMEM;
 	}
@@ -968,6 +968,7 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
 	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);
@@ -975,20 +976,12 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
 	if (!entry) {
 		/* entry was invalidated */
 		spin_unlock(&tree->lock);
-		zpool_unmap_handle(pool, handle);
 		kfree(tmp);
 		return 0;
 	}
 	spin_unlock(&tree->lock);
 	BUG_ON(offset != entry->offset);

-	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);
-	}
-
 	/* try to allocate swap cache page */
 	switch (zswap_get_swap_cache_page(swpentry, &page)) {
 	case ZSWAP_SWAPCACHE_FAIL: /* no memory or invalidate happened */
@@ -1006,6 +999,14 @@ 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);
+		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);
+		}
+
 		mutex_lock(acomp_ctx->mutex);
 		sg_init_one(&input, src, entry->length);
 		sg_init_table(&output, 1);
@@ -1015,6 +1016,11 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
 		dlen = acomp_ctx->req->dlen;
 		mutex_unlock(acomp_ctx->mutex);

+		if (!zpool_can_sleep_mapped(pool))
+			kfree(tmp);
+		else
+			zpool_unmap_handle(pool, handle);
+
 		BUG_ON(ret);
 		BUG_ON(dlen != PAGE_SIZE);

@@ -1045,7 +1051,11 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
 		zswap_entry_put(tree, entry);
 	spin_unlock(&tree->lock);

-	goto end;
+	return ret;
+
+fail:
+	if (!zpool_can_sleep_mapped(pool))
+		kfree(tmp);

 	/*
 	* if we get here due to ZSWAP_SWAPCACHE_EXIST
@@ -1054,17 +1064,10 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
 	* if we free the entry in the following put
 	* it is also okay to return !0
 	*/
-fail:
 	spin_lock(&tree->lock);
 	zswap_entry_put(tree, entry);
 	spin_unlock(&tree->lock);

-end:
-	if (zpool_can_sleep_mapped(pool))
-		zpool_unmap_handle(pool, handle);
-	else
-		kfree(tmp);
-
 	return ret;
 }

--
2.30.2

  reply	other threads:[~2022-11-19  1:18 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-19  0:15 [PATCH v6 0/6] Implement writeback for zsmalloc Nhat Pham
2022-11-19  0:15 ` Nhat Pham [this message]
2022-11-22  1:43   ` [PATCH v6 1/6] zswap: fix writeback lock ordering " Sergey Senozhatsky
2022-11-19  0:15 ` [PATCH v6 2/6] zpool: clean out dead code Nhat Pham
2022-11-22  1:46   ` Sergey Senozhatsky
2022-11-19  0:15 ` [PATCH v6 3/6] zsmalloc: Consolidate zs_pool's migrate_lock and size_class's locks Nhat Pham
2022-11-19  0:15 ` [PATCH v6 4/6] zsmalloc: Add a LRU to zs_pool to keep track of zspages in LRU order Nhat Pham
2022-11-19 16:38   ` Johannes Weiner
2022-11-19 17:34   ` Minchan Kim
2022-11-22  1:52   ` Sergey Senozhatsky
2022-11-22 17:42     ` Johannes Weiner
2022-11-23  3:50       ` Sergey Senozhatsky
2022-11-23  8:02         ` Yosry Ahmed
2022-11-23  8:11           ` Yosry Ahmed
2022-11-23 16:30             ` Johannes Weiner
2022-11-24  3:29               ` Sergey Senozhatsky
2022-11-24  3:21           ` Sergey Senozhatsky
2022-11-23  3:58   ` Sergey Senozhatsky
2022-11-19  0:15 ` [PATCH v6 5/6] zsmalloc: Add zpool_ops field to zs_pool to store evict handlers Nhat Pham
2022-11-19 16:39   ` Johannes Weiner
2022-11-22  1:11     ` Sergey Senozhatsky
2022-11-19  0:15 ` [PATCH v6 6/6] zsmalloc: Implement writeback mechanism for zsmalloc Nhat Pham
2022-11-19 16:45   ` Johannes Weiner
2022-11-19 17:35   ` Minchan Kim
2022-11-22  1:40   ` Sergey Senozhatsky
2022-11-22  2:00   ` Sergey Senozhatsky
2022-11-22  2:15   ` Sergey Senozhatsky
2022-11-22  3:12     ` Johannes Weiner
2022-11-22  3:42       ` Sergey Senozhatsky
2022-11-22  6:09         ` Johannes Weiner
2022-11-22  6:35           ` Sergey Senozhatsky
2022-11-22  7:10             ` Johannes Weiner
2022-11-22  7:19               ` Sergey Senozhatsky
2022-11-22  6:37   ` Sergey Senozhatsky
2022-11-23 16:30     ` Nhat Pham
2022-11-23 17:27       ` Johannes Weiner
2022-11-23 17:18     ` Johannes Weiner
2022-11-21 19:29 ` [PATCH v6 0/6] Implement writeback " Nhat Pham
2022-11-23 19:26   ` Nhat Pham

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=20221119001536.2086599-2-nphamcs@gmail.com \
    --to=nphamcs@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=ddstreet@ieee.org \
    --cc=hannes@cmpxchg.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=minchan@kernel.org \
    --cc=ngupta@vflare.org \
    --cc=senozhatsky@chromium.org \
    --cc=sjenning@redhat.com \
    --cc=vitaly.wool@konsulko.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;
as well as URLs for NNTP newsgroup(s).