162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * zpool memory storage api 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2014 Dan Streetman 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * This is a common frontend for memory storage pool implementations. 862306a36Sopenharmony_ci * Typically, this is used to store compressed memory. 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/list.h> 1462306a36Sopenharmony_ci#include <linux/types.h> 1562306a36Sopenharmony_ci#include <linux/mm.h> 1662306a36Sopenharmony_ci#include <linux/slab.h> 1762306a36Sopenharmony_ci#include <linux/spinlock.h> 1862306a36Sopenharmony_ci#include <linux/module.h> 1962306a36Sopenharmony_ci#include <linux/zpool.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistruct zpool { 2262306a36Sopenharmony_ci struct zpool_driver *driver; 2362306a36Sopenharmony_ci void *pool; 2462306a36Sopenharmony_ci}; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cistatic LIST_HEAD(drivers_head); 2762306a36Sopenharmony_cistatic DEFINE_SPINLOCK(drivers_lock); 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/** 3062306a36Sopenharmony_ci * zpool_register_driver() - register a zpool implementation. 3162306a36Sopenharmony_ci * @driver: driver to register 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_civoid zpool_register_driver(struct zpool_driver *driver) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci spin_lock(&drivers_lock); 3662306a36Sopenharmony_ci atomic_set(&driver->refcount, 0); 3762306a36Sopenharmony_ci list_add(&driver->list, &drivers_head); 3862306a36Sopenharmony_ci spin_unlock(&drivers_lock); 3962306a36Sopenharmony_ci} 4062306a36Sopenharmony_ciEXPORT_SYMBOL(zpool_register_driver); 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/** 4362306a36Sopenharmony_ci * zpool_unregister_driver() - unregister a zpool implementation. 4462306a36Sopenharmony_ci * @driver: driver to unregister. 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * Module usage counting is used to prevent using a driver 4762306a36Sopenharmony_ci * while/after unloading, so if this is called from module 4862306a36Sopenharmony_ci * exit function, this should never fail; if called from 4962306a36Sopenharmony_ci * other than the module exit function, and this returns 5062306a36Sopenharmony_ci * failure, the driver is in use and must remain available. 5162306a36Sopenharmony_ci */ 5262306a36Sopenharmony_ciint zpool_unregister_driver(struct zpool_driver *driver) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci int ret = 0, refcount; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci spin_lock(&drivers_lock); 5762306a36Sopenharmony_ci refcount = atomic_read(&driver->refcount); 5862306a36Sopenharmony_ci WARN_ON(refcount < 0); 5962306a36Sopenharmony_ci if (refcount > 0) 6062306a36Sopenharmony_ci ret = -EBUSY; 6162306a36Sopenharmony_ci else 6262306a36Sopenharmony_ci list_del(&driver->list); 6362306a36Sopenharmony_ci spin_unlock(&drivers_lock); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci return ret; 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ciEXPORT_SYMBOL(zpool_unregister_driver); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/* this assumes @type is null-terminated. */ 7062306a36Sopenharmony_cistatic struct zpool_driver *zpool_get_driver(const char *type) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci struct zpool_driver *driver; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci spin_lock(&drivers_lock); 7562306a36Sopenharmony_ci list_for_each_entry(driver, &drivers_head, list) { 7662306a36Sopenharmony_ci if (!strcmp(driver->type, type)) { 7762306a36Sopenharmony_ci bool got = try_module_get(driver->owner); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci if (got) 8062306a36Sopenharmony_ci atomic_inc(&driver->refcount); 8162306a36Sopenharmony_ci spin_unlock(&drivers_lock); 8262306a36Sopenharmony_ci return got ? driver : NULL; 8362306a36Sopenharmony_ci } 8462306a36Sopenharmony_ci } 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci spin_unlock(&drivers_lock); 8762306a36Sopenharmony_ci return NULL; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic void zpool_put_driver(struct zpool_driver *driver) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci atomic_dec(&driver->refcount); 9362306a36Sopenharmony_ci module_put(driver->owner); 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/** 9762306a36Sopenharmony_ci * zpool_has_pool() - Check if the pool driver is available 9862306a36Sopenharmony_ci * @type: The type of the zpool to check (e.g. zbud, zsmalloc) 9962306a36Sopenharmony_ci * 10062306a36Sopenharmony_ci * This checks if the @type pool driver is available. This will try to load 10162306a36Sopenharmony_ci * the requested module, if needed, but there is no guarantee the module will 10262306a36Sopenharmony_ci * still be loaded and available immediately after calling. If this returns 10362306a36Sopenharmony_ci * true, the caller should assume the pool is available, but must be prepared 10462306a36Sopenharmony_ci * to handle the @zpool_create_pool() returning failure. However if this 10562306a36Sopenharmony_ci * returns false, the caller should assume the requested pool type is not 10662306a36Sopenharmony_ci * available; either the requested pool type module does not exist, or could 10762306a36Sopenharmony_ci * not be loaded, and calling @zpool_create_pool() with the pool type will 10862306a36Sopenharmony_ci * fail. 10962306a36Sopenharmony_ci * 11062306a36Sopenharmony_ci * The @type string must be null-terminated. 11162306a36Sopenharmony_ci * 11262306a36Sopenharmony_ci * Returns: true if @type pool is available, false if not 11362306a36Sopenharmony_ci */ 11462306a36Sopenharmony_cibool zpool_has_pool(char *type) 11562306a36Sopenharmony_ci{ 11662306a36Sopenharmony_ci struct zpool_driver *driver = zpool_get_driver(type); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci if (!driver) { 11962306a36Sopenharmony_ci request_module("zpool-%s", type); 12062306a36Sopenharmony_ci driver = zpool_get_driver(type); 12162306a36Sopenharmony_ci } 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci if (!driver) 12462306a36Sopenharmony_ci return false; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci zpool_put_driver(driver); 12762306a36Sopenharmony_ci return true; 12862306a36Sopenharmony_ci} 12962306a36Sopenharmony_ciEXPORT_SYMBOL(zpool_has_pool); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci/** 13262306a36Sopenharmony_ci * zpool_create_pool() - Create a new zpool 13362306a36Sopenharmony_ci * @type: The type of the zpool to create (e.g. zbud, zsmalloc) 13462306a36Sopenharmony_ci * @name: The name of the zpool (e.g. zram0, zswap) 13562306a36Sopenharmony_ci * @gfp: The GFP flags to use when allocating the pool. 13662306a36Sopenharmony_ci * 13762306a36Sopenharmony_ci * This creates a new zpool of the specified type. The gfp flags will be 13862306a36Sopenharmony_ci * used when allocating memory, if the implementation supports it. If the 13962306a36Sopenharmony_ci * ops param is NULL, then the created zpool will not be evictable. 14062306a36Sopenharmony_ci * 14162306a36Sopenharmony_ci * Implementations must guarantee this to be thread-safe. 14262306a36Sopenharmony_ci * 14362306a36Sopenharmony_ci * The @type and @name strings must be null-terminated. 14462306a36Sopenharmony_ci * 14562306a36Sopenharmony_ci * Returns: New zpool on success, NULL on failure. 14662306a36Sopenharmony_ci */ 14762306a36Sopenharmony_cistruct zpool *zpool_create_pool(const char *type, const char *name, gfp_t gfp) 14862306a36Sopenharmony_ci{ 14962306a36Sopenharmony_ci struct zpool_driver *driver; 15062306a36Sopenharmony_ci struct zpool *zpool; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci pr_debug("creating pool type %s\n", type); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci driver = zpool_get_driver(type); 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci if (!driver) { 15762306a36Sopenharmony_ci request_module("zpool-%s", type); 15862306a36Sopenharmony_ci driver = zpool_get_driver(type); 15962306a36Sopenharmony_ci } 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci if (!driver) { 16262306a36Sopenharmony_ci pr_err("no driver for type %s\n", type); 16362306a36Sopenharmony_ci return NULL; 16462306a36Sopenharmony_ci } 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci zpool = kmalloc(sizeof(*zpool), gfp); 16762306a36Sopenharmony_ci if (!zpool) { 16862306a36Sopenharmony_ci pr_err("couldn't create zpool - out of memory\n"); 16962306a36Sopenharmony_ci zpool_put_driver(driver); 17062306a36Sopenharmony_ci return NULL; 17162306a36Sopenharmony_ci } 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci zpool->driver = driver; 17462306a36Sopenharmony_ci zpool->pool = driver->create(name, gfp); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci if (!zpool->pool) { 17762306a36Sopenharmony_ci pr_err("couldn't create %s pool\n", type); 17862306a36Sopenharmony_ci zpool_put_driver(driver); 17962306a36Sopenharmony_ci kfree(zpool); 18062306a36Sopenharmony_ci return NULL; 18162306a36Sopenharmony_ci } 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci pr_debug("created pool type %s\n", type); 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci return zpool; 18662306a36Sopenharmony_ci} 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci/** 18962306a36Sopenharmony_ci * zpool_destroy_pool() - Destroy a zpool 19062306a36Sopenharmony_ci * @zpool: The zpool to destroy. 19162306a36Sopenharmony_ci * 19262306a36Sopenharmony_ci * Implementations must guarantee this to be thread-safe, 19362306a36Sopenharmony_ci * however only when destroying different pools. The same 19462306a36Sopenharmony_ci * pool should only be destroyed once, and should not be used 19562306a36Sopenharmony_ci * after it is destroyed. 19662306a36Sopenharmony_ci * 19762306a36Sopenharmony_ci * This destroys an existing zpool. The zpool should not be in use. 19862306a36Sopenharmony_ci */ 19962306a36Sopenharmony_civoid zpool_destroy_pool(struct zpool *zpool) 20062306a36Sopenharmony_ci{ 20162306a36Sopenharmony_ci pr_debug("destroying pool type %s\n", zpool->driver->type); 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci zpool->driver->destroy(zpool->pool); 20462306a36Sopenharmony_ci zpool_put_driver(zpool->driver); 20562306a36Sopenharmony_ci kfree(zpool); 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci/** 20962306a36Sopenharmony_ci * zpool_get_type() - Get the type of the zpool 21062306a36Sopenharmony_ci * @zpool: The zpool to check 21162306a36Sopenharmony_ci * 21262306a36Sopenharmony_ci * This returns the type of the pool. 21362306a36Sopenharmony_ci * 21462306a36Sopenharmony_ci * Implementations must guarantee this to be thread-safe. 21562306a36Sopenharmony_ci * 21662306a36Sopenharmony_ci * Returns: The type of zpool. 21762306a36Sopenharmony_ci */ 21862306a36Sopenharmony_ciconst char *zpool_get_type(struct zpool *zpool) 21962306a36Sopenharmony_ci{ 22062306a36Sopenharmony_ci return zpool->driver->type; 22162306a36Sopenharmony_ci} 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci/** 22462306a36Sopenharmony_ci * zpool_malloc_support_movable() - Check if the zpool supports 22562306a36Sopenharmony_ci * allocating movable memory 22662306a36Sopenharmony_ci * @zpool: The zpool to check 22762306a36Sopenharmony_ci * 22862306a36Sopenharmony_ci * This returns if the zpool supports allocating movable memory. 22962306a36Sopenharmony_ci * 23062306a36Sopenharmony_ci * Implementations must guarantee this to be thread-safe. 23162306a36Sopenharmony_ci * 23262306a36Sopenharmony_ci * Returns: true if the zpool supports allocating movable memory, false if not 23362306a36Sopenharmony_ci */ 23462306a36Sopenharmony_cibool zpool_malloc_support_movable(struct zpool *zpool) 23562306a36Sopenharmony_ci{ 23662306a36Sopenharmony_ci return zpool->driver->malloc_support_movable; 23762306a36Sopenharmony_ci} 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci/** 24062306a36Sopenharmony_ci * zpool_malloc() - Allocate memory 24162306a36Sopenharmony_ci * @zpool: The zpool to allocate from. 24262306a36Sopenharmony_ci * @size: The amount of memory to allocate. 24362306a36Sopenharmony_ci * @gfp: The GFP flags to use when allocating memory. 24462306a36Sopenharmony_ci * @handle: Pointer to the handle to set 24562306a36Sopenharmony_ci * 24662306a36Sopenharmony_ci * This allocates the requested amount of memory from the pool. 24762306a36Sopenharmony_ci * The gfp flags will be used when allocating memory, if the 24862306a36Sopenharmony_ci * implementation supports it. The provided @handle will be 24962306a36Sopenharmony_ci * set to the allocated object handle. 25062306a36Sopenharmony_ci * 25162306a36Sopenharmony_ci * Implementations must guarantee this to be thread-safe. 25262306a36Sopenharmony_ci * 25362306a36Sopenharmony_ci * Returns: 0 on success, negative value on error. 25462306a36Sopenharmony_ci */ 25562306a36Sopenharmony_ciint zpool_malloc(struct zpool *zpool, size_t size, gfp_t gfp, 25662306a36Sopenharmony_ci unsigned long *handle) 25762306a36Sopenharmony_ci{ 25862306a36Sopenharmony_ci return zpool->driver->malloc(zpool->pool, size, gfp, handle); 25962306a36Sopenharmony_ci} 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci/** 26262306a36Sopenharmony_ci * zpool_free() - Free previously allocated memory 26362306a36Sopenharmony_ci * @zpool: The zpool that allocated the memory. 26462306a36Sopenharmony_ci * @handle: The handle to the memory to free. 26562306a36Sopenharmony_ci * 26662306a36Sopenharmony_ci * This frees previously allocated memory. This does not guarantee 26762306a36Sopenharmony_ci * that the pool will actually free memory, only that the memory 26862306a36Sopenharmony_ci * in the pool will become available for use by the pool. 26962306a36Sopenharmony_ci * 27062306a36Sopenharmony_ci * Implementations must guarantee this to be thread-safe, 27162306a36Sopenharmony_ci * however only when freeing different handles. The same 27262306a36Sopenharmony_ci * handle should only be freed once, and should not be used 27362306a36Sopenharmony_ci * after freeing. 27462306a36Sopenharmony_ci */ 27562306a36Sopenharmony_civoid zpool_free(struct zpool *zpool, unsigned long handle) 27662306a36Sopenharmony_ci{ 27762306a36Sopenharmony_ci zpool->driver->free(zpool->pool, handle); 27862306a36Sopenharmony_ci} 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci/** 28162306a36Sopenharmony_ci * zpool_map_handle() - Map a previously allocated handle into memory 28262306a36Sopenharmony_ci * @zpool: The zpool that the handle was allocated from 28362306a36Sopenharmony_ci * @handle: The handle to map 28462306a36Sopenharmony_ci * @mapmode: How the memory should be mapped 28562306a36Sopenharmony_ci * 28662306a36Sopenharmony_ci * This maps a previously allocated handle into memory. The @mapmode 28762306a36Sopenharmony_ci * param indicates to the implementation how the memory will be 28862306a36Sopenharmony_ci * used, i.e. read-only, write-only, read-write. If the 28962306a36Sopenharmony_ci * implementation does not support it, the memory will be treated 29062306a36Sopenharmony_ci * as read-write. 29162306a36Sopenharmony_ci * 29262306a36Sopenharmony_ci * This may hold locks, disable interrupts, and/or preemption, 29362306a36Sopenharmony_ci * and the zpool_unmap_handle() must be called to undo those 29462306a36Sopenharmony_ci * actions. The code that uses the mapped handle should complete 29562306a36Sopenharmony_ci * its operations on the mapped handle memory quickly and unmap 29662306a36Sopenharmony_ci * as soon as possible. As the implementation may use per-cpu 29762306a36Sopenharmony_ci * data, multiple handles should not be mapped concurrently on 29862306a36Sopenharmony_ci * any cpu. 29962306a36Sopenharmony_ci * 30062306a36Sopenharmony_ci * Returns: A pointer to the handle's mapped memory area. 30162306a36Sopenharmony_ci */ 30262306a36Sopenharmony_civoid *zpool_map_handle(struct zpool *zpool, unsigned long handle, 30362306a36Sopenharmony_ci enum zpool_mapmode mapmode) 30462306a36Sopenharmony_ci{ 30562306a36Sopenharmony_ci return zpool->driver->map(zpool->pool, handle, mapmode); 30662306a36Sopenharmony_ci} 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci/** 30962306a36Sopenharmony_ci * zpool_unmap_handle() - Unmap a previously mapped handle 31062306a36Sopenharmony_ci * @zpool: The zpool that the handle was allocated from 31162306a36Sopenharmony_ci * @handle: The handle to unmap 31262306a36Sopenharmony_ci * 31362306a36Sopenharmony_ci * This unmaps a previously mapped handle. Any locks or other 31462306a36Sopenharmony_ci * actions that the implementation took in zpool_map_handle() 31562306a36Sopenharmony_ci * will be undone here. The memory area returned from 31662306a36Sopenharmony_ci * zpool_map_handle() should no longer be used after this. 31762306a36Sopenharmony_ci */ 31862306a36Sopenharmony_civoid zpool_unmap_handle(struct zpool *zpool, unsigned long handle) 31962306a36Sopenharmony_ci{ 32062306a36Sopenharmony_ci zpool->driver->unmap(zpool->pool, handle); 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci/** 32462306a36Sopenharmony_ci * zpool_get_total_size() - The total size of the pool 32562306a36Sopenharmony_ci * @zpool: The zpool to check 32662306a36Sopenharmony_ci * 32762306a36Sopenharmony_ci * This returns the total size in bytes of the pool. 32862306a36Sopenharmony_ci * 32962306a36Sopenharmony_ci * Returns: Total size of the zpool in bytes. 33062306a36Sopenharmony_ci */ 33162306a36Sopenharmony_ciu64 zpool_get_total_size(struct zpool *zpool) 33262306a36Sopenharmony_ci{ 33362306a36Sopenharmony_ci return zpool->driver->total_size(zpool->pool); 33462306a36Sopenharmony_ci} 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci/** 33762306a36Sopenharmony_ci * zpool_can_sleep_mapped - Test if zpool can sleep when do mapped. 33862306a36Sopenharmony_ci * @zpool: The zpool to test 33962306a36Sopenharmony_ci * 34062306a36Sopenharmony_ci * Some allocators enter non-preemptible context in ->map() callback (e.g. 34162306a36Sopenharmony_ci * disable pagefaults) and exit that context in ->unmap(), which limits what 34262306a36Sopenharmony_ci * we can do with the mapped object. For instance, we cannot wait for 34362306a36Sopenharmony_ci * asynchronous crypto API to decompress such an object or take mutexes 34462306a36Sopenharmony_ci * since those will call into the scheduler. This function tells us whether 34562306a36Sopenharmony_ci * we use such an allocator. 34662306a36Sopenharmony_ci * 34762306a36Sopenharmony_ci * Returns: true if zpool can sleep; false otherwise. 34862306a36Sopenharmony_ci */ 34962306a36Sopenharmony_cibool zpool_can_sleep_mapped(struct zpool *zpool) 35062306a36Sopenharmony_ci{ 35162306a36Sopenharmony_ci return zpool->driver->sleep_mapped; 35262306a36Sopenharmony_ci} 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ciMODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>"); 35562306a36Sopenharmony_ciMODULE_DESCRIPTION("Common API for compressed memory storage"); 356