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 : 404 : static int __init zswap_entry_cache_create(void)
238 : : {
239 : 404 : zswap_entry_cache = KMEM_CACHE(zswap_entry, 0);
240 : 404 : 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 : 1616 : 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 [ + - ]: 1616 : if (!dst)
381 : : return -ENOMEM;
382 : :
383 : 1616 : per_cpu(zswap_dstmem, cpu) = dst;
384 : 1616 : 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 : 404 : static void zswap_frontswap_init(unsigned type)
1237 : : {
1238 : : struct zswap_tree *tree;
1239 : :
1240 : 404 : tree = kzalloc(sizeof(*tree), GFP_KERNEL);
1241 [ - + ]: 404 : if (!tree) {
1242 : 0 : pr_err("alloc failed, zswap disabled for swap type %d\n", type);
1243 : 404 : return;
1244 : : }
1245 : :
1246 : 404 : tree->rbroot = RB_ROOT;
1247 : 404 : spin_lock_init(&tree->lock);
1248 : 404 : 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 : 404 : static int __init zswap_debugfs_init(void)
1268 : : {
1269 [ + - ]: 404 : if (!debugfs_initialized())
1270 : : return -ENODEV;
1271 : :
1272 : 404 : zswap_debugfs_root = debugfs_create_dir("zswap", NULL);
1273 : :
1274 : 404 : debugfs_create_u64("pool_limit_hit", 0444,
1275 : : zswap_debugfs_root, &zswap_pool_limit_hit);
1276 : 404 : debugfs_create_u64("reject_reclaim_fail", 0444,
1277 : : zswap_debugfs_root, &zswap_reject_reclaim_fail);
1278 : 404 : debugfs_create_u64("reject_alloc_fail", 0444,
1279 : : zswap_debugfs_root, &zswap_reject_alloc_fail);
1280 : 404 : debugfs_create_u64("reject_kmemcache_fail", 0444,
1281 : : zswap_debugfs_root, &zswap_reject_kmemcache_fail);
1282 : 404 : debugfs_create_u64("reject_compress_poor", 0444,
1283 : : zswap_debugfs_root, &zswap_reject_compress_poor);
1284 : 404 : debugfs_create_u64("written_back_pages", 0444,
1285 : : zswap_debugfs_root, &zswap_written_back_pages);
1286 : 404 : debugfs_create_u64("duplicate_entry", 0444,
1287 : : zswap_debugfs_root, &zswap_duplicate_entry);
1288 : 404 : debugfs_create_u64("pool_total_size", 0444,
1289 : : zswap_debugfs_root, &zswap_pool_total_size);
1290 : 404 : debugfs_create_atomic_t("stored_pages", 0444,
1291 : : zswap_debugfs_root, &zswap_stored_pages);
1292 : 404 : debugfs_create_atomic_t("same_filled_pages", 0444,
1293 : : zswap_debugfs_root, &zswap_same_filled_pages);
1294 : :
1295 : 404 : 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 : 404 : static int __init init_zswap(void)
1315 : : {
1316 : : int ret;
1317 : :
1318 : 404 : zswap_init_started = true;
1319 : :
1320 [ - + ]: 404 : 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 [ - + ]: 404 : 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 [ + - ]: 404 : if (ret)
1337 : : goto hp_fail;
1338 : :
1339 : 404 : frontswap_register_ops(&zswap_frontswap_ops);
1340 [ - + ]: 404 : if (zswap_debugfs_init())
1341 : 0 : pr_warn("debugfs initialization failed\n");
1342 : :
1343 [ - + ]: 404 : 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");
|