Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * zswap.c - zswap driver file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * zswap is a backend for frontswap that takes pages that are in the process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * of being swapped out and attempts to compress and store them in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * RAM-based memory pool.  This can result in a significant I/O reduction on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * the swap device and, in the case where decompressing from RAM is faster
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * than reading from the swap device, can also improve workload performance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * Copyright (C) 2012  Seth Jennings <sjenning@linux.vnet.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/frontswap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/rbtree.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/swap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/crypto.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/mempool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/zpool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/mm_types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/page-flags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/swapops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/writeback.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) * statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) /* Total bytes used by the compressed storage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) static u64 zswap_pool_total_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) /* The number of compressed pages currently stored in zswap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) static atomic_t zswap_stored_pages = ATOMIC_INIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) /* The number of same-value filled pages currently stored in zswap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) static atomic_t zswap_same_filled_pages = ATOMIC_INIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48)  * The statistics below are not protected from concurrent access for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49)  * performance reasons so they may not be a 100% accurate.  However,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50)  * they do provide useful information on roughly how many times a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51)  * certain event is occurring.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) /* Pool limit was hit (see zswap_max_pool_percent) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) static u64 zswap_pool_limit_hit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) /* Pages written back when pool limit was reached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) static u64 zswap_written_back_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) /* Store failed due to a reclaim failure after pool limit was reached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) static u64 zswap_reject_reclaim_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) /* Compressed page was too big for the allocator to (optimally) store */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) static u64 zswap_reject_compress_poor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) /* Store failed because underlying allocator could not get memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) static u64 zswap_reject_alloc_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) /* Store failed because the entry metadata could not be allocated (rare) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) static u64 zswap_reject_kmemcache_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) /* Duplicate store was encountered (rare) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) static u64 zswap_duplicate_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) /* Shrinker work queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) static struct workqueue_struct *shrink_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) /* Pool limit was hit, we need to calm down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) static bool zswap_pool_reached_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) * tunables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define ZSWAP_PARAM_UNSET ""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) /* Enable/disable zswap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) static bool zswap_enabled = IS_ENABLED(CONFIG_ZSWAP_DEFAULT_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) static int zswap_enabled_param_set(const char *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 				   const struct kernel_param *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) static struct kernel_param_ops zswap_enabled_param_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	.set =		zswap_enabled_param_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	.get =		param_get_bool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) module_param_cb(enabled, &zswap_enabled_param_ops, &zswap_enabled, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) /* Crypto compressor to use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) static char *zswap_compressor = CONFIG_ZSWAP_COMPRESSOR_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) static int zswap_compressor_param_set(const char *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 				      const struct kernel_param *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) static struct kernel_param_ops zswap_compressor_param_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	.set =		zswap_compressor_param_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	.get =		param_get_charp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	.free =		param_free_charp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) module_param_cb(compressor, &zswap_compressor_param_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 		&zswap_compressor, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) /* Compressed storage zpool to use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) static char *zswap_zpool_type = CONFIG_ZSWAP_ZPOOL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) static int zswap_zpool_param_set(const char *, const struct kernel_param *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) static struct kernel_param_ops zswap_zpool_param_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	.set =		zswap_zpool_param_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	.get =		param_get_charp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	.free =		param_free_charp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) module_param_cb(zpool, &zswap_zpool_param_ops, &zswap_zpool_type, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) /* The maximum percentage of memory that the compressed pool can occupy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) static unsigned int zswap_max_pool_percent = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) module_param_named(max_pool_percent, zswap_max_pool_percent, uint, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) /* The threshold for accepting new pages after the max_pool_percent was hit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) static unsigned int zswap_accept_thr_percent = 90; /* of max pool size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) module_param_named(accept_threshold_percent, zswap_accept_thr_percent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		   uint, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) /* Enable/disable handling same-value filled pages (enabled by default) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) static bool zswap_same_filled_pages_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) module_param_named(same_filled_pages_enabled, zswap_same_filled_pages_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 		   bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) * data structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) struct zswap_pool {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	struct zpool *zpool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	struct crypto_comp * __percpu *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	struct kref kref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	struct work_struct release_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	struct work_struct shrink_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	struct hlist_node node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	char tfm_name[CRYPTO_MAX_ALG_NAME];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142)  * struct zswap_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144)  * This structure contains the metadata for tracking a single compressed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145)  * page within zswap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147)  * rbnode - links the entry into red-black tree for the appropriate swap type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148)  * offset - the swap offset for the entry.  Index into the red-black tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149)  * refcount - the number of outstanding reference to the entry. This is needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150)  *            to protect against premature freeing of the entry by code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151)  *            concurrent calls to load, invalidate, and writeback.  The lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152)  *            for the zswap_tree structure that contains the entry must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153)  *            be held while changing the refcount.  Since the lock must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154)  *            be held, there is no reason to also make refcount atomic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155)  * length - the length in bytes of the compressed page data.  Needed during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156)  *          decompression. For a same value filled page length is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)  * pool - the zswap_pool the entry's data is in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158)  * handle - zpool allocation handle that stores the compressed page data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159)  * value - value of the same-value filled pages which have same content
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) struct zswap_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	struct rb_node rbnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	pgoff_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	int refcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	unsigned int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	struct zswap_pool *pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		unsigned long handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 		unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) struct zswap_header {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	swp_entry_t swpentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178)  * The tree lock in the zswap_tree struct protects a few things:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179)  * - the rbtree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180)  * - the refcount field of each entry in the tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) struct zswap_tree {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	struct rb_root rbroot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) static struct zswap_tree *zswap_trees[MAX_SWAPFILES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) /* RCU-protected iteration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) static LIST_HEAD(zswap_pools);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) /* protects zswap_pools list modification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) static DEFINE_SPINLOCK(zswap_pools_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) /* pool counter to provide unique names to zpool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) static atomic_t zswap_pools_count = ATOMIC_INIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) /* used by param callback function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) static bool zswap_init_started;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) /* fatal error during init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) static bool zswap_init_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) /* init completed, but couldn't create the initial pool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) static bool zswap_has_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) * helpers and fwd declarations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) #define zswap_pool_debug(msg, p)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	pr_debug("%s pool %s/%s\n", msg, (p)->tfm_name,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		 zpool_get_type((p)->zpool))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) static int zswap_writeback_entry(struct zpool *pool, unsigned long handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) static int zswap_pool_get(struct zswap_pool *pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) static void zswap_pool_put(struct zswap_pool *pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) static const struct zpool_ops zswap_zpool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	.evict = zswap_writeback_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) static bool zswap_is_full(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	return totalram_pages() * zswap_max_pool_percent / 100 <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 			DIV_ROUND_UP(zswap_pool_total_size, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) static bool zswap_can_accept(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	return totalram_pages() * zswap_accept_thr_percent / 100 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 				zswap_max_pool_percent / 100 >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 			DIV_ROUND_UP(zswap_pool_total_size, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) static void zswap_update_total_size(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	struct zswap_pool *pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	u64 total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	list_for_each_entry_rcu(pool, &zswap_pools, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		total += zpool_get_total_size(pool->zpool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	zswap_pool_total_size = total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) * zswap entry functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) static struct kmem_cache *zswap_entry_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) static int __init zswap_entry_cache_create(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	zswap_entry_cache = KMEM_CACHE(zswap_entry, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	return zswap_entry_cache == NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) static void __init zswap_entry_cache_destroy(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	kmem_cache_destroy(zswap_entry_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) static struct zswap_entry *zswap_entry_cache_alloc(gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	struct zswap_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	entry = kmem_cache_alloc(zswap_entry_cache, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	if (!entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	entry->refcount = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	RB_CLEAR_NODE(&entry->rbnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) static void zswap_entry_cache_free(struct zswap_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	kmem_cache_free(zswap_entry_cache, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) * rbtree functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) static struct zswap_entry *zswap_rb_search(struct rb_root *root, pgoff_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	struct rb_node *node = root->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	struct zswap_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	while (node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		entry = rb_entry(node, struct zswap_entry, rbnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		if (entry->offset > offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			node = node->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		else if (entry->offset < offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 			node = node->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 			return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302)  * In the case that a entry with the same offset is found, a pointer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303)  * the existing entry is stored in dupentry and the function returns -EEXIST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) static int zswap_rb_insert(struct rb_root *root, struct zswap_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 			struct zswap_entry **dupentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	struct rb_node **link = &root->rb_node, *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	struct zswap_entry *myentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	while (*link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		parent = *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		myentry = rb_entry(parent, struct zswap_entry, rbnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		if (myentry->offset > entry->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 			link = &(*link)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		else if (myentry->offset < entry->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 			link = &(*link)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 			*dupentry = myentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 			return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	rb_link_node(&entry->rbnode, parent, link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	rb_insert_color(&entry->rbnode, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) static void zswap_rb_erase(struct rb_root *root, struct zswap_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	if (!RB_EMPTY_NODE(&entry->rbnode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		rb_erase(&entry->rbnode, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		RB_CLEAR_NODE(&entry->rbnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337)  * Carries out the common pattern of freeing and entry's zpool allocation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338)  * freeing the entry itself, and decrementing the number of stored pages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) static void zswap_free_entry(struct zswap_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	if (!entry->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		atomic_dec(&zswap_same_filled_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		zpool_free(entry->pool->zpool, entry->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		zswap_pool_put(entry->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	zswap_entry_cache_free(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	atomic_dec(&zswap_stored_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	zswap_update_total_size();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) /* caller must hold the tree lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) static void zswap_entry_get(struct zswap_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	entry->refcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) /* caller must hold the tree lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) * remove from the tree and free it, if nobody reference the entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) static void zswap_entry_put(struct zswap_tree *tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 			struct zswap_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	int refcount = --entry->refcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	BUG_ON(refcount < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	if (refcount == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		zswap_rb_erase(&tree->rbroot, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		zswap_free_entry(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) /* caller must hold the tree lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) static struct zswap_entry *zswap_entry_find_get(struct rb_root *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 				pgoff_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	struct zswap_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	entry = zswap_rb_search(root, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	if (entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		zswap_entry_get(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) * per-cpu code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) static DEFINE_PER_CPU(u8 *, zswap_dstmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) static int zswap_dstmem_prepare(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	u8 *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	dst = kmalloc_node(PAGE_SIZE * 2, GFP_KERNEL, cpu_to_node(cpu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	if (!dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	per_cpu(zswap_dstmem, cpu) = dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) static int zswap_dstmem_dead(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	u8 *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	dst = per_cpu(zswap_dstmem, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	kfree(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	per_cpu(zswap_dstmem, cpu) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) static int zswap_cpu_comp_prepare(unsigned int cpu, struct hlist_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	struct zswap_pool *pool = hlist_entry(node, struct zswap_pool, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	struct crypto_comp *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	if (WARN_ON(*per_cpu_ptr(pool->tfm, cpu)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	tfm = crypto_alloc_comp(pool->tfm_name, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	if (IS_ERR_OR_NULL(tfm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		pr_err("could not alloc crypto comp %s : %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		       pool->tfm_name, PTR_ERR(tfm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	*per_cpu_ptr(pool->tfm, cpu) = tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) static int zswap_cpu_comp_dead(unsigned int cpu, struct hlist_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	struct zswap_pool *pool = hlist_entry(node, struct zswap_pool, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	struct crypto_comp *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	tfm = *per_cpu_ptr(pool->tfm, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	if (!IS_ERR_OR_NULL(tfm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		crypto_free_comp(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	*per_cpu_ptr(pool->tfm, cpu) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) * pool functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) static struct zswap_pool *__zswap_pool_current(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	struct zswap_pool *pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	pool = list_first_or_null_rcu(&zswap_pools, typeof(*pool), list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	WARN_ONCE(!pool && zswap_has_pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		  "%s: no page storage pool!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	return pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) static struct zswap_pool *zswap_pool_current(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	assert_spin_locked(&zswap_pools_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	return __zswap_pool_current();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) static struct zswap_pool *zswap_pool_current_get(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	struct zswap_pool *pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	pool = __zswap_pool_current();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	if (!zswap_pool_get(pool))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		pool = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	return pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) static struct zswap_pool *zswap_pool_last_get(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	struct zswap_pool *pool, *last = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	list_for_each_entry_rcu(pool, &zswap_pools, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		last = pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	WARN_ONCE(!last && zswap_has_pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 		  "%s: no page storage pool!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	if (!zswap_pool_get(last))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		last = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	return last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) /* type and compressor must be null-terminated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) static struct zswap_pool *zswap_pool_find_get(char *type, char *compressor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	struct zswap_pool *pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	assert_spin_locked(&zswap_pools_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	list_for_each_entry_rcu(pool, &zswap_pools, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 		if (strcmp(pool->tfm_name, compressor))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		if (strcmp(zpool_get_type(pool->zpool), type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		/* if we can't get it, it's about to be destroyed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		if (!zswap_pool_get(pool))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		return pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) static void shrink_worker(struct work_struct *w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	struct zswap_pool *pool = container_of(w, typeof(*pool),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 						shrink_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	if (zpool_shrink(pool->zpool, 1, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		zswap_reject_reclaim_fail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	zswap_pool_put(pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) static struct zswap_pool *zswap_pool_create(char *type, char *compressor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	struct zswap_pool *pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	char name[38]; /* 'zswap' + 32 char (max) num + \0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	gfp_t gfp = __GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	if (!zswap_has_pool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		/* if either are unset, pool initialization failed, and we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		 * need both params to be set correctly before trying to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 		 * create a pool.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		if (!strcmp(type, ZSWAP_PARAM_UNSET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		if (!strcmp(compressor, ZSWAP_PARAM_UNSET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	if (!pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	/* unique name for each pool specifically required by zsmalloc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	snprintf(name, 38, "zswap%x", atomic_inc_return(&zswap_pools_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	pool->zpool = zpool_create_pool(type, name, gfp, &zswap_zpool_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	if (!pool->zpool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		pr_err("%s zpool not available\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	pr_debug("using %s zpool\n", zpool_get_type(pool->zpool));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	strlcpy(pool->tfm_name, compressor, sizeof(pool->tfm_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	pool->tfm = alloc_percpu(struct crypto_comp *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	if (!pool->tfm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		pr_err("percpu alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	ret = cpuhp_state_add_instance(CPUHP_MM_ZSWP_POOL_PREPARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 				       &pool->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	pr_debug("using %s compressor\n", pool->tfm_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	/* being the current pool takes 1 ref; this func expects the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	 * caller to always add the new pool as the current pool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	kref_init(&pool->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	INIT_LIST_HEAD(&pool->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	INIT_WORK(&pool->shrink_work, shrink_worker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	zswap_pool_debug("created", pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	return pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	free_percpu(pool->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	if (pool->zpool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		zpool_destroy_pool(pool->zpool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	kfree(pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) static __init struct zswap_pool *__zswap_pool_create_fallback(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	bool has_comp, has_zpool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	has_comp = crypto_has_comp(zswap_compressor, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	if (!has_comp && strcmp(zswap_compressor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 				CONFIG_ZSWAP_COMPRESSOR_DEFAULT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		pr_err("compressor %s not available, using default %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		       zswap_compressor, CONFIG_ZSWAP_COMPRESSOR_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		param_free_charp(&zswap_compressor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		zswap_compressor = CONFIG_ZSWAP_COMPRESSOR_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		has_comp = crypto_has_comp(zswap_compressor, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	if (!has_comp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		pr_err("default compressor %s not available\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		       zswap_compressor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		param_free_charp(&zswap_compressor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		zswap_compressor = ZSWAP_PARAM_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	has_zpool = zpool_has_pool(zswap_zpool_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	if (!has_zpool && strcmp(zswap_zpool_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 				 CONFIG_ZSWAP_ZPOOL_DEFAULT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		pr_err("zpool %s not available, using default %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 		       zswap_zpool_type, CONFIG_ZSWAP_ZPOOL_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		param_free_charp(&zswap_zpool_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		zswap_zpool_type = CONFIG_ZSWAP_ZPOOL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		has_zpool = zpool_has_pool(zswap_zpool_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	if (!has_zpool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		pr_err("default zpool %s not available\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		       zswap_zpool_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		param_free_charp(&zswap_zpool_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		zswap_zpool_type = ZSWAP_PARAM_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	if (!has_comp || !has_zpool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	return zswap_pool_create(zswap_zpool_type, zswap_compressor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) static void zswap_pool_destroy(struct zswap_pool *pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	zswap_pool_debug("destroying", pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	cpuhp_state_remove_instance(CPUHP_MM_ZSWP_POOL_PREPARE, &pool->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	free_percpu(pool->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	zpool_destroy_pool(pool->zpool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	kfree(pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) static int __must_check zswap_pool_get(struct zswap_pool *pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	if (!pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	return kref_get_unless_zero(&pool->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) static void __zswap_pool_release(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	struct zswap_pool *pool = container_of(work, typeof(*pool),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 						release_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	/* nobody should have been able to get a kref... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	WARN_ON(kref_get_unless_zero(&pool->kref));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	/* pool is now off zswap_pools list and has no references. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	zswap_pool_destroy(pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) static void __zswap_pool_empty(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	struct zswap_pool *pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	pool = container_of(kref, typeof(*pool), kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	spin_lock(&zswap_pools_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	WARN_ON(pool == zswap_pool_current());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	list_del_rcu(&pool->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	INIT_WORK(&pool->release_work, __zswap_pool_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	schedule_work(&pool->release_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	spin_unlock(&zswap_pools_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) static void zswap_pool_put(struct zswap_pool *pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	kref_put(&pool->kref, __zswap_pool_empty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) * param callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) /* val must be a null-terminated string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) static int __zswap_param_set(const char *val, const struct kernel_param *kp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 			     char *type, char *compressor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	struct zswap_pool *pool, *put_pool = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	char *s = strstrip((char *)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	if (zswap_init_failed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		pr_err("can't set param, initialization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	/* no change required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	if (!strcmp(s, *(char **)kp->arg) && zswap_has_pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	/* if this is load-time (pre-init) param setting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	 * don't create a pool; that's done during init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	if (!zswap_init_started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		return param_set_charp(s, kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	if (!type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		if (!zpool_has_pool(s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 			pr_err("zpool %s not available\n", s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		type = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	} else if (!compressor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		if (!crypto_has_comp(s, 0, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 			pr_err("compressor %s not available\n", s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		compressor = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	spin_lock(&zswap_pools_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	pool = zswap_pool_find_get(type, compressor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	if (pool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		zswap_pool_debug("using existing", pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		WARN_ON(pool == zswap_pool_current());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		list_del_rcu(&pool->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	spin_unlock(&zswap_pools_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	if (!pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		pool = zswap_pool_create(type, compressor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	if (pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		ret = param_set_charp(s, kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	spin_lock(&zswap_pools_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		put_pool = zswap_pool_current();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		list_add_rcu(&pool->list, &zswap_pools);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		zswap_has_pool = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	} else if (pool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		/* add the possibly pre-existing pool to the end of the pools
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		 * list; if it's new (and empty) then it'll be removed and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		 * destroyed by the put after we drop the lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		list_add_tail_rcu(&pool->list, &zswap_pools);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		put_pool = pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	spin_unlock(&zswap_pools_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	if (!zswap_has_pool && !pool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		/* if initial pool creation failed, and this pool creation also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		 * failed, maybe both compressor and zpool params were bad.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		 * Allow changing this param, so pool creation will succeed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		 * when the other param is changed. We already verified this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		 * param is ok in the zpool_has_pool() or crypto_has_comp()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		 * checks above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		ret = param_set_charp(s, kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	/* drop the ref from either the old current pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	 * or the new pool we failed to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	if (put_pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		zswap_pool_put(put_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) static int zswap_compressor_param_set(const char *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 				      const struct kernel_param *kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	return __zswap_param_set(val, kp, zswap_zpool_type, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) static int zswap_zpool_param_set(const char *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 				 const struct kernel_param *kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	return __zswap_param_set(val, kp, NULL, zswap_compressor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) static int zswap_enabled_param_set(const char *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 				   const struct kernel_param *kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	if (zswap_init_failed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		pr_err("can't enable, initialization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	if (!zswap_has_pool && zswap_init_started) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		pr_err("can't enable, no pool configured\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	return param_set_bool(val, kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) * writeback code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) /* return enum for zswap_get_swap_cache_page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) enum zswap_get_swap_ret {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	ZSWAP_SWAPCACHE_NEW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	ZSWAP_SWAPCACHE_EXIST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	ZSWAP_SWAPCACHE_FAIL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830)  * zswap_get_swap_cache_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832)  * This is an adaption of read_swap_cache_async()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834)  * This function tries to find a page with the given swap entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835)  * in the swapper_space address space (the swap cache).  If the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836)  * is found, it is returned in retpage.  Otherwise, a page is allocated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837)  * added to the swap cache, and returned in retpage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839)  * If success, the swap cache page is returned in retpage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840)  * Returns ZSWAP_SWAPCACHE_EXIST if page was already in the swap cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841)  * Returns ZSWAP_SWAPCACHE_NEW if the new page needs to be populated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842)  *     the new page is added to swapcache and locked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843)  * Returns ZSWAP_SWAPCACHE_FAIL on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) static int zswap_get_swap_cache_page(swp_entry_t entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 				struct page **retpage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	bool page_was_allocated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	*retpage = __read_swap_cache_async(entry, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 			NULL, 0, &page_was_allocated);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	if (page_was_allocated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		return ZSWAP_SWAPCACHE_NEW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	if (!*retpage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		return ZSWAP_SWAPCACHE_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	return ZSWAP_SWAPCACHE_EXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860)  * Attempts to free an entry by adding a page to the swap cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861)  * decompressing the entry data into the page, and issuing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862)  * bio write to write the page back to the swap device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864)  * This can be thought of as a "resumed writeback" of the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865)  * to the swap device.  We are basically resuming the same swap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866)  * writeback path that was intercepted with the frontswap_store()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867)  * in the first place.  After the page has been decompressed into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868)  * the swap cache, the compressed version stored by zswap can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869)  * freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	struct zswap_header *zhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	swp_entry_t swpentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	struct zswap_tree *tree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	pgoff_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	struct zswap_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	struct crypto_comp *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	u8 *src, *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	unsigned int dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	struct writeback_control wbc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		.sync_mode = WB_SYNC_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	/* extract swpentry from data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	zhdr = zpool_map_handle(pool, handle, ZPOOL_MM_RO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	swpentry = zhdr->swpentry; /* here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	tree = zswap_trees[swp_type(swpentry)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	offset = swp_offset(swpentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	/* find and ref zswap entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	spin_lock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	entry = zswap_entry_find_get(&tree->rbroot, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	if (!entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		/* entry was invalidated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		spin_unlock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		zpool_unmap_handle(pool, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	spin_unlock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	BUG_ON(offset != entry->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	/* try to allocate swap cache page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	switch (zswap_get_swap_cache_page(swpentry, &page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	case ZSWAP_SWAPCACHE_FAIL: /* no memory or invalidate happened */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	case ZSWAP_SWAPCACHE_EXIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		/* page is already in the swap cache, ignore for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	case ZSWAP_SWAPCACHE_NEW: /* page is locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		/* decompress */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		dlen = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		src = (u8 *)zhdr + sizeof(struct zswap_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		dst = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		tfm = *get_cpu_ptr(entry->pool->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		ret = crypto_comp_decompress(tfm, src, entry->length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 					     dst, &dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		put_cpu_ptr(entry->pool->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		kunmap_atomic(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		BUG_ON(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		BUG_ON(dlen != PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		/* page is up to date */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	/* move it to the tail of the inactive list after end_writeback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	SetPageReclaim(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	/* start writeback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	__swap_writepage(page, &wbc, end_swap_bio_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	zswap_written_back_pages++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	spin_lock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	/* drop local reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	zswap_entry_put(tree, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	* There are two possible situations for entry here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	* (1) refcount is 1(normal case),  entry is valid and on the tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	* (2) refcount is 0, entry is freed and not on the tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	*     because invalidate happened during writeback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	*  search the tree and free the entry if find entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	if (entry == zswap_rb_search(&tree->rbroot, offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		zswap_entry_put(tree, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	spin_unlock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	* if we get here due to ZSWAP_SWAPCACHE_EXIST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	* a load may happening concurrently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	* it is safe and okay to not free the entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	* if we free the entry in the following put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	* it it either okay to return !0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	spin_lock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	zswap_entry_put(tree, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	spin_unlock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	zpool_unmap_handle(pool, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) static int zswap_is_page_same_filled(void *ptr, unsigned long *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	unsigned int pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	unsigned long *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	page = (unsigned long *)ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	for (pos = 1; pos < PAGE_SIZE / sizeof(*page); pos++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		if (page[pos] != page[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	*value = page[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) static void zswap_fill_page(void *ptr, unsigned long value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	unsigned long *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	page = (unsigned long *)ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	memset_l(page, value, PAGE_SIZE / sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) * frontswap hooks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /* attempts to compress and store an single page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static int zswap_frontswap_store(unsigned type, pgoff_t offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 				struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	struct zswap_tree *tree = zswap_trees[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	struct zswap_entry *entry, *dupentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	struct crypto_comp *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	unsigned int hlen, dlen = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	unsigned long handle, value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	u8 *src, *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	struct zswap_header zhdr = { .swpentry = swp_entry(type, offset) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	gfp_t gfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	/* THP isn't supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	if (PageTransHuge(page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	if (!zswap_enabled || !tree) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	/* reclaim space if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	if (zswap_is_full()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		struct zswap_pool *pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		zswap_pool_limit_hit++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		zswap_pool_reached_full = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		pool = zswap_pool_last_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		if (pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 			queue_work(shrink_wq, &pool->shrink_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	if (zswap_pool_reached_full) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	       if (!zswap_can_accept()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 			goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			zswap_pool_reached_full = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	/* allocate entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	entry = zswap_entry_cache_alloc(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	if (!entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		zswap_reject_kmemcache_fail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	if (zswap_same_filled_pages_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		src = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		if (zswap_is_page_same_filled(src, &value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 			kunmap_atomic(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 			entry->offset = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 			entry->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 			entry->value = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 			atomic_inc(&zswap_same_filled_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 			goto insert_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		kunmap_atomic(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	/* if entry is successfully added, it keeps the reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	entry->pool = zswap_pool_current_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	if (!entry->pool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		goto freepage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	/* compress */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	dst = get_cpu_var(zswap_dstmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	tfm = *get_cpu_ptr(entry->pool->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	src = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	ret = crypto_comp_compress(tfm, src, PAGE_SIZE, dst, &dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	kunmap_atomic(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	put_cpu_ptr(entry->pool->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		goto put_dstmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	/* store */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	hlen = zpool_evictable(entry->pool->zpool) ? sizeof(zhdr) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	gfp = __GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	if (zpool_malloc_support_movable(entry->pool->zpool))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		gfp |= __GFP_HIGHMEM | __GFP_MOVABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	ret = zpool_malloc(entry->pool->zpool, hlen + dlen, gfp, &handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	if (ret == -ENOSPC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		zswap_reject_compress_poor++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		goto put_dstmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		zswap_reject_alloc_fail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		goto put_dstmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	buf = zpool_map_handle(entry->pool->zpool, handle, ZPOOL_MM_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	memcpy(buf, &zhdr, hlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	memcpy(buf + hlen, dst, dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	zpool_unmap_handle(entry->pool->zpool, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	put_cpu_var(zswap_dstmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	/* populate entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	entry->offset = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	entry->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	entry->length = dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) insert_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	/* map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	spin_lock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		ret = zswap_rb_insert(&tree->rbroot, entry, &dupentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		if (ret == -EEXIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 			zswap_duplicate_entry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 			/* remove from rbtree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			zswap_rb_erase(&tree->rbroot, dupentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 			zswap_entry_put(tree, dupentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	} while (ret == -EEXIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	spin_unlock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	/* update stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	atomic_inc(&zswap_stored_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	zswap_update_total_size();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) put_dstmem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	put_cpu_var(zswap_dstmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	zswap_pool_put(entry->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) freepage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	zswap_entry_cache_free(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) reject:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)  * returns 0 if the page was successfully decompressed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)  * return -1 on entry not found or error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) static int zswap_frontswap_load(unsigned type, pgoff_t offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 				struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	struct zswap_tree *tree = zswap_trees[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	struct zswap_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	struct crypto_comp *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	u8 *src, *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	unsigned int dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	/* find */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	spin_lock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	entry = zswap_entry_find_get(&tree->rbroot, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	if (!entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		/* entry was written back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		spin_unlock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	spin_unlock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	if (!entry->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		dst = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		zswap_fill_page(dst, entry->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		kunmap_atomic(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		goto freeentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	/* decompress */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	dlen = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	src = zpool_map_handle(entry->pool->zpool, entry->handle, ZPOOL_MM_RO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	if (zpool_evictable(entry->pool->zpool))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 		src += sizeof(struct zswap_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	dst = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	tfm = *get_cpu_ptr(entry->pool->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	ret = crypto_comp_decompress(tfm, src, entry->length, dst, &dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	put_cpu_ptr(entry->pool->tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	kunmap_atomic(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	zpool_unmap_handle(entry->pool->zpool, entry->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	BUG_ON(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) freeentry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	spin_lock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	zswap_entry_put(tree, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	spin_unlock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /* frees an entry in zswap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static void zswap_frontswap_invalidate_page(unsigned type, pgoff_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	struct zswap_tree *tree = zswap_trees[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	struct zswap_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	/* find */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	spin_lock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	entry = zswap_rb_search(&tree->rbroot, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	if (!entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		/* entry was written back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		spin_unlock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	/* remove from rbtree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	zswap_rb_erase(&tree->rbroot, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	/* drop the initial reference from entry creation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	zswap_entry_put(tree, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	spin_unlock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) /* frees all zswap entries for the given swap type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static void zswap_frontswap_invalidate_area(unsigned type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	struct zswap_tree *tree = zswap_trees[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	struct zswap_entry *entry, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	if (!tree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	/* walk the tree and free everything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	spin_lock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	rbtree_postorder_for_each_entry_safe(entry, n, &tree->rbroot, rbnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 		zswap_free_entry(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	tree->rbroot = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	spin_unlock(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	kfree(tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	zswap_trees[type] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static void zswap_frontswap_init(unsigned type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	struct zswap_tree *tree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	tree = kzalloc(sizeof(*tree), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	if (!tree) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		pr_err("alloc failed, zswap disabled for swap type %d\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	tree->rbroot = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	spin_lock_init(&tree->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	zswap_trees[type] = tree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) static struct frontswap_ops zswap_frontswap_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	.store = zswap_frontswap_store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	.load = zswap_frontswap_load,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	.invalidate_page = zswap_frontswap_invalidate_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	.invalidate_area = zswap_frontswap_invalidate_area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	.init = zswap_frontswap_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) * debugfs functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) static struct dentry *zswap_debugfs_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) static int __init zswap_debugfs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	if (!debugfs_initialized())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	zswap_debugfs_root = debugfs_create_dir("zswap", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	debugfs_create_u64("pool_limit_hit", 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 			   zswap_debugfs_root, &zswap_pool_limit_hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	debugfs_create_u64("reject_reclaim_fail", 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 			   zswap_debugfs_root, &zswap_reject_reclaim_fail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	debugfs_create_u64("reject_alloc_fail", 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 			   zswap_debugfs_root, &zswap_reject_alloc_fail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	debugfs_create_u64("reject_kmemcache_fail", 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 			   zswap_debugfs_root, &zswap_reject_kmemcache_fail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	debugfs_create_u64("reject_compress_poor", 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 			   zswap_debugfs_root, &zswap_reject_compress_poor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	debugfs_create_u64("written_back_pages", 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 			   zswap_debugfs_root, &zswap_written_back_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	debugfs_create_u64("duplicate_entry", 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 			   zswap_debugfs_root, &zswap_duplicate_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	debugfs_create_u64("pool_total_size", 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 			   zswap_debugfs_root, &zswap_pool_total_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	debugfs_create_atomic_t("stored_pages", 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 				zswap_debugfs_root, &zswap_stored_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	debugfs_create_atomic_t("same_filled_pages", 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 				zswap_debugfs_root, &zswap_same_filled_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) static void __exit zswap_debugfs_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	debugfs_remove_recursive(zswap_debugfs_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) static int __init zswap_debugfs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static void __exit zswap_debugfs_exit(void) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) /*********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) * module init and exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) **********************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) static int __init init_zswap(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	struct zswap_pool *pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	zswap_init_started = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	if (zswap_entry_cache_create()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 		pr_err("entry cache creation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 		goto cache_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	ret = cpuhp_setup_state(CPUHP_MM_ZSWP_MEM_PREPARE, "mm/zswap:prepare",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 				zswap_dstmem_prepare, zswap_dstmem_dead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 		pr_err("dstmem alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 		goto dstmem_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	ret = cpuhp_setup_state_multi(CPUHP_MM_ZSWP_POOL_PREPARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 				      "mm/zswap_pool:prepare",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 				      zswap_cpu_comp_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 				      zswap_cpu_comp_dead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 		goto hp_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	pool = __zswap_pool_create_fallback();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	if (pool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		pr_info("loaded using pool %s/%s\n", pool->tfm_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 			zpool_get_type(pool->zpool));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 		list_add(&pool->list, &zswap_pools);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 		zswap_has_pool = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		pr_err("pool creation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 		zswap_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	shrink_wq = create_workqueue("zswap-shrink");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	if (!shrink_wq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 		goto fallback_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	frontswap_register_ops(&zswap_frontswap_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	if (zswap_debugfs_init())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 		pr_warn("debugfs initialization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) fallback_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	if (pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 		zswap_pool_destroy(pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) hp_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	cpuhp_remove_state(CPUHP_MM_ZSWP_MEM_PREPARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) dstmem_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	zswap_entry_cache_destroy();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) cache_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	/* if built-in, we aren't unloaded on failure; don't allow use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	zswap_init_failed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	zswap_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) /* must be late so crypto has time to come up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) late_initcall(init_zswap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) MODULE_AUTHOR("Seth Jennings <sjennings@variantweb.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) MODULE_DESCRIPTION("Compressed cache for swap pages");