All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH mm/zswap 0/2] Fix the compatibility of zsmalloc and zswap
@ 2021-01-19  5:54 Tian Tao
  2021-01-19  5:54 ` [PATCH mm/zswap 1/2] mm/zswap: add the flag can_sleep_mapped Tian Tao
  2021-01-19  5:54 ` [PATCH mm/zswap 2/2] mm: set the sleep_mapped to true for zbud and z3fold Tian Tao
  0 siblings, 2 replies; 4+ messages in thread
From: Tian Tao @ 2021-01-19  5:54 UTC (permalink / raw)
  To: vitaly.wool, akpm, sjenning, ddstreet, efault, bigeasy, song.bao.hua
  Cc: linux-mm

patch #1 add a flag to zpool, then zswap used to determine if zpool
drivers such as zbud/z3fold/zsmalloc will enter an atomic context after
mapping. the difference between zbud/z3fold and zsmalloc is that zsmalloc
requires an atomic context that since its map function holds a
preempt-disabled, but zbud/z3fold don't require an atomic context. so
patch #2 set flag sleep_mapped to true indicates that zbud/z3fold can
sleep after mapping. zsmalloc didin't support sleep after mapping, so not
set that flag to true.

Tian Tao (2):
  mm/zswap: add the flag can_sleep_mapped
  mm: set the sleep_mapped to true for zbud and z3fold

 include/linux/zpool.h |  3 +++
 mm/z3fold.c           |  1 +
 mm/zbud.c             |  1 +
 mm/zpool.c            | 13 +++++++++++++
 mm/zswap.c            | 50 +++++++++++++++++++++++++++++++++++++++++++++-----
 5 files changed, 63 insertions(+), 5 deletions(-)

-- 
2.7.4



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH mm/zswap 1/2] mm/zswap: add the flag can_sleep_mapped
  2021-01-19  5:54 [PATCH mm/zswap 0/2] Fix the compatibility of zsmalloc and zswap Tian Tao
@ 2021-01-19  5:54 ` Tian Tao
  2021-01-20 14:46   ` kernel test robot
  2021-01-19  5:54 ` [PATCH mm/zswap 2/2] mm: set the sleep_mapped to true for zbud and z3fold Tian Tao
  1 sibling, 1 reply; 4+ messages in thread
From: Tian Tao @ 2021-01-19  5:54 UTC (permalink / raw)
  To: vitaly.wool, akpm, sjenning, ddstreet, efault, bigeasy, song.bao.hua
  Cc: linux-mm

add a flag to zpool, named is "can_sleep_mapped", and have it set true
for zbud/z3fold, not set this flag for zsmalloc, so its default value is
false. Then zswap could go the current path if the flag is true; and if
it's false, copy data from src to a temporary buffer, then unmap the
handle, take the mutex, process the buffer instead of src to avoid
sleeping function called from atomic context.

Signed-off-by: Tian Tao <tiantao6@hisilicon.com>
Reviewed-by: Vitaly Wool <vitaly.wool@konsulko.com>
Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reported-by: Mike Galbraith <efault@gmx.de>
---
 include/linux/zpool.h |  3 +++
 mm/zpool.c            | 13 +++++++++++++
 mm/zswap.c            | 50 +++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/include/linux/zpool.h b/include/linux/zpool.h
index 51bf430..e899701 100644
--- a/include/linux/zpool.h
+++ b/include/linux/zpool.h
@@ -73,6 +73,7 @@ u64 zpool_get_total_size(struct zpool *pool);
  * @malloc:	allocate mem from a pool.
  * @free:	free mem from a pool.
  * @shrink:	shrink the pool.
+ * @sleep_mapped: whether zpool driver can sleep during map.
  * @map:	map a handle.
  * @unmap:	unmap a handle.
  * @total_size:	get total size of a pool.
@@ -100,6 +101,7 @@ struct zpool_driver {
 	int (*shrink)(void *pool, unsigned int pages,
 				unsigned int *reclaimed);
 
+	bool sleep_mapped;
 	void *(*map)(void *pool, unsigned long handle,
 				enum zpool_mapmode mm);
 	void (*unmap)(void *pool, unsigned long handle);
@@ -112,5 +114,6 @@ void zpool_register_driver(struct zpool_driver *driver);
 int zpool_unregister_driver(struct zpool_driver *driver);
 
 bool zpool_evictable(struct zpool *pool);
+bool zpool_can_sleep_mapped(struct zpool *pool);
 
 #endif
diff --git a/mm/zpool.c b/mm/zpool.c
index 3744a2d..5ed7120 100644
--- a/mm/zpool.c
+++ b/mm/zpool.c
@@ -23,6 +23,7 @@ struct zpool {
 	void *pool;
 	const struct zpool_ops *ops;
 	bool evictable;
+	bool can_sleep_mapped;
 
 	struct list_head list;
 };
@@ -183,6 +184,7 @@ struct zpool *zpool_create_pool(const char *type, const char *name, gfp_t gfp,
 	zpool->pool = driver->create(name, gfp, ops, zpool);
 	zpool->ops = ops;
 	zpool->evictable = driver->shrink && ops && ops->evict;
+	zpool->can_sleep_mapped = driver->sleep_mapped;
 
 	if (!zpool->pool) {
 		pr_err("couldn't create %s pool\n", type);
@@ -393,6 +395,17 @@ bool zpool_evictable(struct zpool *zpool)
 	return zpool->evictable;
 }
 
+/**
+ * zpool_can_sleep_mapped - Test if zpool can sleep when do mapped.
+ * @zpool:	The zpool to test
+ *
+ * Returns: true if zpool can sleep; false otherwise.
+ */
+bool zpool_can_sleep_mapped(struct zpool *zpool)
+{
+	return zpool->can_sleep_mapped;
+}
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>");
 MODULE_DESCRIPTION("Common API for compressed memory storage");
diff --git a/mm/zswap.c b/mm/zswap.c
index 1e41c28..6e0bb61 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -935,13 +935,20 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
 	struct scatterlist input, output;
 	struct crypto_acomp_ctx *acomp_ctx;
 
-	u8 *src;
+	u8 *src, *tmp;
 	unsigned int dlen;
 	int ret;
 	struct writeback_control wbc = {
 		.sync_mode = WB_SYNC_NONE,
 	};
 
+	if (!zpool_can_sleep_mapped(pool)) {
+
+		tmp = kmalloc(entry->length, GFP_ATOMIC);
+		if (!tmp)
+			return -ENOMEM;
+	}
+
 	/* extract swpentry from data */
 	zhdr = zpool_map_handle(pool, handle, ZPOOL_MM_RO);
 	swpentry = zhdr->swpentry; /* here */
@@ -979,6 +986,14 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
 		dlen = PAGE_SIZE;
 		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);
@@ -1033,7 +1048,11 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
 	spin_unlock(&tree->lock);
 
 end:
-	zpool_unmap_handle(pool, handle);
+	if (zpool_can_sleep_mapped(pool))
+		zpool_unmap_handle(pool, handle);
+	else
+		kfree(tmp);
+
 	return ret;
 }
 
@@ -1235,7 +1254,7 @@ static int zswap_frontswap_load(unsigned type, pgoff_t offset,
 	struct zswap_entry *entry;
 	struct scatterlist input, output;
 	struct crypto_acomp_ctx *acomp_ctx;
-	u8 *src, *dst;
+	u8 *src, *dst, *tmp;
 	unsigned int dlen;
 	int ret;
 
@@ -1256,12 +1275,29 @@ static int zswap_frontswap_load(unsigned type, pgoff_t offset,
 		goto freeentry;
 	}
 
+	if (!zpool_can_sleep_mapped(entry->pool->zpool)) {
+
+		tmp = kmalloc(entry->length, GFP_ATOMIC);
+		if (!tmp) {
+			ret = -ENOMEM;
+			goto freeentry;
+		}
+	}
+
 	/* decompress */
 	dlen = PAGE_SIZE;
 	src = zpool_map_handle(entry->pool->zpool, entry->handle, ZPOOL_MM_RO);
 	if (zpool_evictable(entry->pool->zpool))
 		src += sizeof(struct zswap_header);
 
+	if (!zpool_can_sleep_mapped(entry->pool->zpool)) {
+
+		memcpy(tmp, src, entry->length);
+		src = tmp;
+
+		zpool_unmap_handle(entry->pool->zpool, entry->handle);
+	}
+
 	acomp_ctx = raw_cpu_ptr(entry->pool->acomp_ctx);
 	mutex_lock(acomp_ctx->mutex);
 	sg_init_one(&input, src, entry->length);
@@ -1271,7 +1307,11 @@ static int zswap_frontswap_load(unsigned type, pgoff_t offset,
 	ret = crypto_wait_req(crypto_acomp_decompress(acomp_ctx->req), &acomp_ctx->wait);
 	mutex_unlock(acomp_ctx->mutex);
 
-	zpool_unmap_handle(entry->pool->zpool, entry->handle);
+	if (zpool_can_sleep_mapped(entry->pool->zpool))
+		zpool_unmap_handle(entry->pool->zpool, entry->handle);
+	else
+		kfree(tmp);
+
 	BUG_ON(ret);
 
 freeentry:
@@ -1279,7 +1319,7 @@ static int zswap_frontswap_load(unsigned type, pgoff_t offset,
 	zswap_entry_put(tree, entry);
 	spin_unlock(&tree->lock);
 
-	return 0;
+	return ret;
 }
 
 /* frees an entry in zswap */
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH mm/zswap 2/2] mm: set the sleep_mapped to true for zbud and z3fold
  2021-01-19  5:54 [PATCH mm/zswap 0/2] Fix the compatibility of zsmalloc and zswap Tian Tao
  2021-01-19  5:54 ` [PATCH mm/zswap 1/2] mm/zswap: add the flag can_sleep_mapped Tian Tao
@ 2021-01-19  5:54 ` Tian Tao
  1 sibling, 0 replies; 4+ messages in thread
From: Tian Tao @ 2021-01-19  5:54 UTC (permalink / raw)
  To: vitaly.wool, akpm, sjenning, ddstreet, efault, bigeasy, song.bao.hua
  Cc: linux-mm

zpool driver add a flag to indicates whether the zpool driver can enter
an atomic context after mapping, this patch set it true for z3fold and
zbud.

Signed-off-by: Tian Tao <tiantao6@hisilicon.com>
Reviewed-by: Vitaly Wool <vitaly.wool@konsulko.com>
Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reported-by: Mike Galbraith <efault@gmx.de>
---
 mm/z3fold.c | 1 +
 mm/zbud.c   | 1 +
 2 files changed, 2 insertions(+)

diff --git a/mm/z3fold.c b/mm/z3fold.c
index dacb0d7..234b46f 100644
--- a/mm/z3fold.c
+++ b/mm/z3fold.c
@@ -1778,6 +1778,7 @@ static u64 z3fold_zpool_total_size(void *pool)
 
 static struct zpool_driver z3fold_zpool_driver = {
 	.type =		"z3fold",
+	.sleep_mapped = true,
 	.owner =	THIS_MODULE,
 	.create =	z3fold_zpool_create,
 	.destroy =	z3fold_zpool_destroy,
diff --git a/mm/zbud.c b/mm/zbud.c
index c49966e..7ec5f27 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -203,6 +203,7 @@ static u64 zbud_zpool_total_size(void *pool)
 
 static struct zpool_driver zbud_zpool_driver = {
 	.type =		"zbud",
+	.sleep_mapped = true,
 	.owner =	THIS_MODULE,
 	.create =	zbud_zpool_create,
 	.destroy =	zbud_zpool_destroy,
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH mm/zswap 1/2] mm/zswap: add the flag can_sleep_mapped
  2021-01-19  5:54 ` [PATCH mm/zswap 1/2] mm/zswap: add the flag can_sleep_mapped Tian Tao
@ 2021-01-20 14:46   ` kernel test robot
  0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2021-01-20 14:46 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 14608 bytes --]

Hi Tian,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.11-rc4]
[cannot apply to hnaz-linux-mm/master next-20210120]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Tian-Tao/Fix-the-compatibility-of-zsmalloc-and-zswap/20210120-162712
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 45dfb8a5659ad286c28fa59008271dbc4e5e3f2d
config: s390-randconfig-r003-20210120 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 22b68440e1647e16b5ee24b924986207173c02d1)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/0day-ci/linux/commit/d2ad619ba5016be9cd273292ae5dc40d8402fe4e
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Tian-Tao/Fix-the-compatibility-of-zsmalloc-and-zswap/20210120-162712
        git checkout d2ad619ba5016be9cd273292ae5dc40d8402fe4e
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=s390 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

                              ^
   include/uapi/linux/swab.h:20:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x0000ff00UL) <<  8) |            \
                     ^
   In file included from mm/zswap.c:23:
   In file included from include/linux/frontswap.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:22:
   In file included from include/linux/writeback.h:14:
   In file included from include/linux/blk-cgroup.h:23:
   In file included from include/linux/blkdev.h:26:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:21:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x00ff0000UL) >>  8) |            \
                     ^
   In file included from mm/zswap.c:23:
   In file included from include/linux/frontswap.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:22:
   In file included from include/linux/writeback.h:14:
   In file included from include/linux/blk-cgroup.h:23:
   In file included from include/linux/blkdev.h:26:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:22:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
                     ^
   In file included from mm/zswap.c:23:
   In file included from include/linux/frontswap.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:22:
   In file included from include/linux/writeback.h:14:
   In file included from include/linux/blk-cgroup.h:23:
   In file included from include/linux/blkdev.h:26:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:120:12: note: expanded from macro '__swab32'
           __fswab32(x))
                     ^
   In file included from mm/zswap.c:23:
   In file included from include/linux/frontswap.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:22:
   In file included from include/linux/writeback.h:14:
   In file included from include/linux/blk-cgroup.h:23:
   In file included from include/linux/blkdev.h:26:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:609:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsb(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:617:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsw(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:625:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsl(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:634:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesb(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:643:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesw(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:652:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesl(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
>> mm/zswap.c:947:17: warning: variable 'entry' is uninitialized when used here [-Wuninitialized]
                   tmp = kmalloc(entry->length, GFP_ATOMIC);
                                 ^~~~~
   mm/zswap.c:933:27: note: initialize the variable 'entry' to silence this warning
           struct zswap_entry *entry;
                                    ^
                                     = NULL
>> mm/zswap.c:1271:6: warning: variable 'ret' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
           if (!entry->length) {
               ^~~~~~~~~~~~~~
   mm/zswap.c:1322:9: note: uninitialized use occurs here
           return ret;
                  ^~~
   mm/zswap.c:1271:2: note: remove the 'if' if its condition is always false
           if (!entry->length) {
           ^~~~~~~~~~~~~~~~~~~~~
   mm/zswap.c:1259:9: note: initialize the variable 'ret' to silence this warning
           int ret;
                  ^
                   = 0
   22 warnings generated.


vim +/entry +947 mm/zswap.c

   914	
   915	/*
   916	 * Attempts to free an entry by adding a page to the swap cache,
   917	 * decompressing the entry data into the page, and issuing a
   918	 * bio write to write the page back to the swap device.
   919	 *
   920	 * This can be thought of as a "resumed writeback" of the page
   921	 * to the swap device.  We are basically resuming the same swap
   922	 * writeback path that was intercepted with the frontswap_store()
   923	 * in the first place.  After the page has been decompressed into
   924	 * the swap cache, the compressed version stored by zswap can be
   925	 * freed.
   926	 */
   927	static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
   928	{
   929		struct zswap_header *zhdr;
   930		swp_entry_t swpentry;
   931		struct zswap_tree *tree;
   932		pgoff_t offset;
   933		struct zswap_entry *entry;
   934		struct page *page;
   935		struct scatterlist input, output;
   936		struct crypto_acomp_ctx *acomp_ctx;
   937	
   938		u8 *src, *tmp;
   939		unsigned int dlen;
   940		int ret;
   941		struct writeback_control wbc = {
   942			.sync_mode = WB_SYNC_NONE,
   943		};
   944	
   945		if (!zpool_can_sleep_mapped(pool)) {
   946	
 > 947			tmp = kmalloc(entry->length, GFP_ATOMIC);
   948			if (!tmp)
   949				return -ENOMEM;
   950		}
   951	
   952		/* extract swpentry from data */
   953		zhdr = zpool_map_handle(pool, handle, ZPOOL_MM_RO);
   954		swpentry = zhdr->swpentry; /* here */
   955		tree = zswap_trees[swp_type(swpentry)];
   956		offset = swp_offset(swpentry);
   957	
   958		/* find and ref zswap entry */
   959		spin_lock(&tree->lock);
   960		entry = zswap_entry_find_get(&tree->rbroot, offset);
   961		if (!entry) {
   962			/* entry was invalidated */
   963			spin_unlock(&tree->lock);
   964			zpool_unmap_handle(pool, handle);
   965			return 0;
   966		}
   967		spin_unlock(&tree->lock);
   968		BUG_ON(offset != entry->offset);
   969	
   970		/* try to allocate swap cache page */
   971		switch (zswap_get_swap_cache_page(swpentry, &page)) {
   972		case ZSWAP_SWAPCACHE_FAIL: /* no memory or invalidate happened */
   973			ret = -ENOMEM;
   974			goto fail;
   975	
   976		case ZSWAP_SWAPCACHE_EXIST:
   977			/* page is already in the swap cache, ignore for now */
   978			put_page(page);
   979			ret = -EEXIST;
   980			goto fail;
   981	
   982		case ZSWAP_SWAPCACHE_NEW: /* page is locked */
   983			/* decompress */
   984			acomp_ctx = raw_cpu_ptr(entry->pool->acomp_ctx);
   985	
   986			dlen = PAGE_SIZE;
   987			src = (u8 *)zhdr + sizeof(struct zswap_header);
   988	
   989			if (!zpool_can_sleep_mapped(pool)) {
   990	
   991				memcpy(tmp, src, entry->length);
   992				src = tmp;
   993	
   994				zpool_unmap_handle(pool, handle);
   995			}
   996	
   997			mutex_lock(acomp_ctx->mutex);
   998			sg_init_one(&input, src, entry->length);
   999			sg_init_table(&output, 1);
  1000			sg_set_page(&output, page, PAGE_SIZE, 0);
  1001			acomp_request_set_params(acomp_ctx->req, &input, &output, entry->length, dlen);
  1002			ret = crypto_wait_req(crypto_acomp_decompress(acomp_ctx->req), &acomp_ctx->wait);
  1003			dlen = acomp_ctx->req->dlen;
  1004			mutex_unlock(acomp_ctx->mutex);
  1005	
  1006			BUG_ON(ret);
  1007			BUG_ON(dlen != PAGE_SIZE);
  1008	
  1009			/* page is up to date */
  1010			SetPageUptodate(page);
  1011		}
  1012	
  1013		/* move it to the tail of the inactive list after end_writeback */
  1014		SetPageReclaim(page);
  1015	
  1016		/* start writeback */
  1017		__swap_writepage(page, &wbc, end_swap_bio_write);
  1018		put_page(page);
  1019		zswap_written_back_pages++;
  1020	
  1021		spin_lock(&tree->lock);
  1022		/* drop local reference */
  1023		zswap_entry_put(tree, entry);
  1024	
  1025		/*
  1026		* There are two possible situations for entry here:
  1027		* (1) refcount is 1(normal case),  entry is valid and on the tree
  1028		* (2) refcount is 0, entry is freed and not on the tree
  1029		*     because invalidate happened during writeback
  1030		*  search the tree and free the entry if find entry
  1031		*/
  1032		if (entry == zswap_rb_search(&tree->rbroot, offset))
  1033			zswap_entry_put(tree, entry);
  1034		spin_unlock(&tree->lock);
  1035	
  1036		goto end;
  1037	
  1038		/*
  1039		* if we get here due to ZSWAP_SWAPCACHE_EXIST
  1040		* a load may happening concurrently
  1041		* it is safe and okay to not free the entry
  1042		* if we free the entry in the following put
  1043		* it it either okay to return !0
  1044		*/
  1045	fail:
  1046		spin_lock(&tree->lock);
  1047		zswap_entry_put(tree, entry);
  1048		spin_unlock(&tree->lock);
  1049	
  1050	end:
  1051		if (zpool_can_sleep_mapped(pool))
  1052			zpool_unmap_handle(pool, handle);
  1053		else
  1054			kfree(tmp);
  1055	
  1056		return ret;
  1057	}
  1058	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 14752 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-01-20 14:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-19  5:54 [PATCH mm/zswap 0/2] Fix the compatibility of zsmalloc and zswap Tian Tao
2021-01-19  5:54 ` [PATCH mm/zswap 1/2] mm/zswap: add the flag can_sleep_mapped Tian Tao
2021-01-20 14:46   ` kernel test robot
2021-01-19  5:54 ` [PATCH mm/zswap 2/2] mm: set the sleep_mapped to true for zbud and z3fold Tian Tao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.