Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm: zswap: remove shrink from zpool interface

Now that all three zswap backends have removed their shrink code, it is
no longer necessary for the zpool interface to include shrink/writeback
endpoints.

Link: https://lkml.kernel.org/r/20230612093815.133504-6-cerasuolodomenico@gmail.com
Signed-off-by: Domenico Cerasuolo <cerasuolodomenico@gmail.com>
Reviewed-by: Yosry Ahmed <yosryahmed@google.com>
Acked-by: Nhat Pham <nphamcs@gmail.com>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Dan Streetman <ddstreet@ieee.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Seth Jennings <sjenning@redhat.com>
Cc: Vitaly Wool <vitaly.wool@konsulko.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Domenico Cerasuolo and committed by
Andrew Morton
35499e2b b3067742

+14 -93
+2 -18
include/linux/zpool.h
··· 14 14 15 15 struct zpool; 16 16 17 - struct zpool_ops { 18 - int (*evict)(struct zpool *pool, unsigned long handle); 19 - }; 20 - 21 17 /* 22 18 * Control how a handle is mapped. It will be ignored if the 23 19 * implementation does not support it. Its use is optional. ··· 35 39 36 40 bool zpool_has_pool(char *type); 37 41 38 - struct zpool *zpool_create_pool(const char *type, const char *name, 39 - gfp_t gfp, const struct zpool_ops *ops); 42 + struct zpool *zpool_create_pool(const char *type, const char *name, gfp_t gfp); 40 43 41 44 const char *zpool_get_type(struct zpool *pool); 42 45 ··· 47 52 unsigned long *handle); 48 53 49 54 void zpool_free(struct zpool *pool, unsigned long handle); 50 - 51 - int zpool_shrink(struct zpool *pool, unsigned int pages, 52 - unsigned int *reclaimed); 53 55 54 56 void *zpool_map_handle(struct zpool *pool, unsigned long handle, 55 57 enum zpool_mapmode mm); ··· 64 72 * @destroy: destroy a pool. 65 73 * @malloc: allocate mem from a pool. 66 74 * @free: free mem from a pool. 67 - * @shrink: shrink the pool. 68 75 * @sleep_mapped: whether zpool driver can sleep during map. 69 76 * @map: map a handle. 70 77 * @unmap: unmap a handle. ··· 78 87 atomic_t refcount; 79 88 struct list_head list; 80 89 81 - void *(*create)(const char *name, 82 - gfp_t gfp, 83 - const struct zpool_ops *ops, 84 - struct zpool *zpool); 90 + void *(*create)(const char *name, gfp_t gfp); 85 91 void (*destroy)(void *pool); 86 92 87 93 bool malloc_support_movable; 88 94 int (*malloc)(void *pool, size_t size, gfp_t gfp, 89 95 unsigned long *handle); 90 96 void (*free)(void *pool, unsigned long handle); 91 - 92 - int (*shrink)(void *pool, unsigned int pages, 93 - unsigned int *reclaimed); 94 97 95 98 bool sleep_mapped; 96 99 void *(*map)(void *pool, unsigned long handle, ··· 98 113 99 114 int zpool_unregister_driver(struct zpool_driver *driver); 100 115 101 - bool zpool_evictable(struct zpool *pool); 102 116 bool zpool_can_sleep_mapped(struct zpool *pool); 103 117 104 118 #endif
+1 -3
mm/z3fold.c
··· 1364 1364 * zpool 1365 1365 ****************/ 1366 1366 1367 - static void *z3fold_zpool_create(const char *name, gfp_t gfp, 1368 - const struct zpool_ops *zpool_ops, 1369 - struct zpool *zpool) 1367 + static void *z3fold_zpool_create(const char *name, gfp_t gfp) 1370 1368 { 1371 1369 return z3fold_create_pool(name, gfp); 1372 1370 }
+1 -3
mm/zbud.c
··· 380 380 * zpool 381 381 ****************/ 382 382 383 - static void *zbud_zpool_create(const char *name, gfp_t gfp, 384 - const struct zpool_ops *zpool_ops, 385 - struct zpool *zpool) 383 + static void *zbud_zpool_create(const char *name, gfp_t gfp) 386 384 { 387 385 return zbud_create_pool(gfp); 388 386 }
+2 -46
mm/zpool.c
··· 133 133 * @type: The type of the zpool to create (e.g. zbud, zsmalloc) 134 134 * @name: The name of the zpool (e.g. zram0, zswap) 135 135 * @gfp: The GFP flags to use when allocating the pool. 136 - * @ops: The optional ops callback. 137 136 * 138 137 * This creates a new zpool of the specified type. The gfp flags will be 139 138 * used when allocating memory, if the implementation supports it. If the ··· 144 145 * 145 146 * Returns: New zpool on success, NULL on failure. 146 147 */ 147 - struct zpool *zpool_create_pool(const char *type, const char *name, gfp_t gfp, 148 - const struct zpool_ops *ops) 148 + struct zpool *zpool_create_pool(const char *type, const char *name, gfp_t gfp) 149 149 { 150 150 struct zpool_driver *driver; 151 151 struct zpool *zpool; ··· 171 173 } 172 174 173 175 zpool->driver = driver; 174 - zpool->pool = driver->create(name, gfp, ops, zpool); 176 + zpool->pool = driver->create(name, gfp); 175 177 176 178 if (!zpool->pool) { 177 179 pr_err("couldn't create %s pool\n", type); ··· 278 280 } 279 281 280 282 /** 281 - * zpool_shrink() - Shrink the pool size 282 - * @zpool: The zpool to shrink. 283 - * @pages: The number of pages to shrink the pool. 284 - * @reclaimed: The number of pages successfully evicted. 285 - * 286 - * This attempts to shrink the actual memory size of the pool 287 - * by evicting currently used handle(s). If the pool was 288 - * created with no zpool_ops, or the evict call fails for any 289 - * of the handles, this will fail. If non-NULL, the @reclaimed 290 - * parameter will be set to the number of pages reclaimed, 291 - * which may be more than the number of pages requested. 292 - * 293 - * Implementations must guarantee this to be thread-safe. 294 - * 295 - * Returns: 0 on success, negative value on error/failure. 296 - */ 297 - int zpool_shrink(struct zpool *zpool, unsigned int pages, 298 - unsigned int *reclaimed) 299 - { 300 - return zpool->driver->shrink ? 301 - zpool->driver->shrink(zpool->pool, pages, reclaimed) : -EINVAL; 302 - } 303 - 304 - /** 305 283 * zpool_map_handle() - Map a previously allocated handle into memory 306 284 * @zpool: The zpool that the handle was allocated from 307 285 * @handle: The handle to map ··· 331 357 u64 zpool_get_total_size(struct zpool *zpool) 332 358 { 333 359 return zpool->driver->total_size(zpool->pool); 334 - } 335 - 336 - /** 337 - * zpool_evictable() - Test if zpool is potentially evictable 338 - * @zpool: The zpool to test 339 - * 340 - * Zpool is only potentially evictable when it's created with struct 341 - * zpool_ops.evict and its driver implements struct zpool_driver.shrink. 342 - * 343 - * However, it doesn't necessarily mean driver will use zpool_ops.evict 344 - * in its implementation of zpool_driver.shrink. It could do internal 345 - * defragmentation instead. 346 - * 347 - * Returns: true if potentially evictable; false otherwise. 348 - */ 349 - bool zpool_evictable(struct zpool *zpool) 350 - { 351 - return zpool->driver->shrink; 352 360 } 353 361 354 362 /**
+1 -3
mm/zsmalloc.c
··· 351 351 352 352 #ifdef CONFIG_ZPOOL 353 353 354 - static void *zs_zpool_create(const char *name, gfp_t gfp, 355 - const struct zpool_ops *zpool_ops, 356 - struct zpool *zpool) 354 + static void *zs_zpool_create(const char *name, gfp_t gfp) 357 355 { 358 356 /* 359 357 * Ignore global gfp flags: zs_malloc() may be invoked from
+7 -20
mm/zswap.c
··· 258 258 static int zswap_pool_get(struct zswap_pool *pool); 259 259 static void zswap_pool_put(struct zswap_pool *pool); 260 260 261 - static const struct zpool_ops zswap_zpool_ops = { 262 - .evict = zswap_writeback_entry 263 - }; 264 - 265 261 static bool zswap_is_full(void) 266 262 { 267 263 return totalram_pages() * zswap_max_pool_percent / 100 < ··· 375 379 if (!entry->length) 376 380 atomic_dec(&zswap_same_filled_pages); 377 381 else { 378 - /* zpool_evictable will be removed once all 3 backends have migrated */ 379 - if (!zpool_evictable(entry->pool->zpool)) { 380 - spin_lock(&entry->pool->lru_lock); 381 - list_del(&entry->lru); 382 - spin_unlock(&entry->pool->lru_lock); 383 - } 382 + spin_lock(&entry->pool->lru_lock); 383 + list_del(&entry->lru); 384 + spin_unlock(&entry->pool->lru_lock); 384 385 zpool_free(entry->pool->zpool, entry->handle); 385 386 zswap_pool_put(entry->pool); 386 387 } ··· 658 665 shrink_work); 659 666 int ret, failures = 0; 660 667 661 - /* zpool_evictable will be removed once all 3 backends have migrated */ 662 668 do { 663 - if (zpool_evictable(pool->zpool)) 664 - ret = zpool_shrink(pool->zpool, 1, NULL); 665 - else 666 - ret = zswap_reclaim_entry(pool); 669 + ret = zswap_reclaim_entry(pool); 667 670 if (ret) { 668 671 zswap_reject_reclaim_fail++; 669 672 if (ret != -EAGAIN) ··· 697 708 /* unique name for each pool specifically required by zsmalloc */ 698 709 snprintf(name, 38, "zswap%x", atomic_inc_return(&zswap_pools_count)); 699 710 700 - pool->zpool = zpool_create_pool(type, name, gfp, &zswap_zpool_ops); 711 + pool->zpool = zpool_create_pool(type, name, gfp); 701 712 if (!pool->zpool) { 702 713 pr_err("%s zpool not available\n", type); 703 714 goto error; ··· 1383 1394 zswap_entry_put(tree, dupentry); 1384 1395 } 1385 1396 } while (ret == -EEXIST); 1386 - /* zpool_evictable will be removed once all 3 backends have migrated */ 1387 - if (entry->length && !zpool_evictable(entry->pool->zpool)) { 1397 + if (entry->length) { 1388 1398 spin_lock(&entry->pool->lru_lock); 1389 1399 list_add(&entry->lru, &entry->pool->lru); 1390 1400 spin_unlock(&entry->pool->lru_lock); ··· 1502 1514 if (!ret && zswap_exclusive_loads_enabled) { 1503 1515 zswap_invalidate_entry(tree, entry); 1504 1516 *exclusive = true; 1505 - } else if (entry->length && !zpool_evictable(entry->pool->zpool)) { 1506 - /* zpool_evictable will be removed once all 3 backends have migrated */ 1517 + } else if (entry->length) { 1507 1518 spin_lock(&entry->pool->lru_lock); 1508 1519 list_move(&entry->lru, &entry->pool->lru); 1509 1520 spin_unlock(&entry->pool->lru_lock);