LCOV - code coverage report
Current view: top level - mm - zswap.c (source / functions) Hit Total Coverage
Test: Real Lines: 36 403 8.9 %
Date: 2020-10-17 15:46:43 Functions: 0 36 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

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

Generated by: LCOV version 1.14