@@ -50,12 +50,22 @@ static int decompress_842(struct zcomp_params *params, struct zcomp_ctx *ctx,
return sw842_decompress(req->src, req->src_len, req->dst, &dlen);
}
-const struct zcomp_ops backend_842 = {
+static void destroy_ops_842(struct zcomp_ops *backend_842)
+{
+}
+
+struct zcomp_ops backend_842 = {
.compress = compress_842,
.decompress = decompress_842,
.create_ctx = create_842,
.destroy_ctx = destroy_842,
.setup_params = setup_params_842,
.release_params = release_params_842,
+ .destroy = destroy_ops_842,
.name = "842",
};
+
+struct zcomp_ops *get_backend_842(void)
+{
+ return &backend_842;
+}
@@ -5,6 +5,6 @@
#include "zcomp.h"
-extern const struct zcomp_ops backend_842;
+struct zcomp_ops *get_backend_842(void);
#endif /* __BACKEND_842_H__ */
@@ -136,12 +136,22 @@ static int deflate_decompress(struct zcomp_params *params,
return 0;
}
-const struct zcomp_ops backend_deflate = {
+static void deflate_destroy_ops(struct zcomp_ops *backend_delfate)
+{
+}
+
+struct zcomp_ops backend_deflate = {
.compress = deflate_compress,
.decompress = deflate_decompress,
.create_ctx = deflate_create,
.destroy_ctx = deflate_destroy,
.setup_params = deflate_setup_params,
.release_params = deflate_release_params,
+ .destroy = deflate_destroy_ops,
.name = "deflate",
};
+
+struct zcomp_ops *get_backend_deflate(void)
+{
+ return &backend_deflate;
+}
@@ -5,6 +5,6 @@
#include "zcomp.h"
-extern const struct zcomp_ops backend_deflate;
+struct zcomp_ops *get_backend_deflate(void);
#endif /* __BACKEND_DEFLATE_H__ */
@@ -117,12 +117,22 @@ static int lz4_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
return 0;
}
-const struct zcomp_ops backend_lz4 = {
+static void lz4_destroy_ops(struct zcomp_ops *backend_lz4)
+{
+}
+
+struct zcomp_ops backend_lz4 = {
.compress = lz4_compress,
.decompress = lz4_decompress,
.create_ctx = lz4_create,
.destroy_ctx = lz4_destroy,
.setup_params = lz4_setup_params,
.release_params = lz4_release_params,
+ .destroy = lz4_destroy_ops,
.name = "lz4",
};
+
+struct zcomp_ops *get_backend_lz4(void)
+{
+ return &backend_lz4;
+}
@@ -5,6 +5,6 @@
#include "zcomp.h"
-extern const struct zcomp_ops backend_lz4;
+struct zcomp_ops *get_backend_lz4(void);
#endif /* __BACKEND_LZ4_H__ */
@@ -118,12 +118,22 @@ static int lz4hc_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
return 0;
}
-const struct zcomp_ops backend_lz4hc = {
+static void lz4hc_destroy_ops(struct zcomp_ops *backend_lz4hc)
+{
+}
+
+struct zcomp_ops backend_lz4hc = {
.compress = lz4hc_compress,
.decompress = lz4hc_decompress,
.create_ctx = lz4hc_create,
.destroy_ctx = lz4hc_destroy,
.setup_params = lz4hc_setup_params,
.release_params = lz4hc_release_params,
+ .destroy = lz4hc_destroy_ops,
.name = "lz4hc",
};
+
+struct zcomp_ops *get_backend_lz4hc(void)
+{
+ return &backend_lz4hc;
+}
@@ -5,6 +5,6 @@
#include "zcomp.h"
-extern const struct zcomp_ops backend_lz4hc;
+struct zcomp_ops *get_backend_lz4hc(void);
#endif /* __BACKEND_LZ4HC_H__ */
@@ -48,12 +48,22 @@ static int lzo_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
return ret == LZO_E_OK ? 0 : ret;
}
-const struct zcomp_ops backend_lzo = {
+static void lzo_destroy_ops(struct zcomp_ops *backend_lzo)
+{
+}
+
+struct zcomp_ops backend_lzo = {
.compress = lzo_compress,
.decompress = lzo_decompress,
.create_ctx = lzo_create,
.destroy_ctx = lzo_destroy,
.setup_params = lzo_setup_params,
.release_params = lzo_release_params,
+ .destroy = lzo_destroy_ops,
.name = "lzo",
};
+
+struct zcomp_ops *get_backend_lzo(void)
+{
+ return &backend_lzo;
+}
@@ -5,6 +5,6 @@
#include "zcomp.h"
-extern const struct zcomp_ops backend_lzo;
+struct zcomp_ops *get_backend_lzo(void);
#endif /* __BACKEND_LZO_H__ */
@@ -48,12 +48,22 @@ static int lzorle_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
return ret == LZO_E_OK ? 0 : ret;
}
-const struct zcomp_ops backend_lzorle = {
+static void lzorle_destroy_ops(struct zcomp_ops *backend_lzorle)
+{
+}
+
+struct zcomp_ops backend_lzorle = {
.compress = lzorle_compress,
.decompress = lzorle_decompress,
.create_ctx = lzorle_create,
.destroy_ctx = lzorle_destroy,
.setup_params = lzorle_setup_params,
.release_params = lzorle_release_params,
+ .destroy = lzorle_destroy_ops,
.name = "lzo-rle",
};
+
+struct zcomp_ops *get_backend_lzorle(void)
+{
+ return &backend_lzorle;
+}
@@ -5,6 +5,6 @@
#include "zcomp.h"
-extern const struct zcomp_ops backend_lzorle;
+struct zcomp_ops *get_backend_lzorle(void);
#endif /* __BACKEND_LZORLE_H__ */
@@ -216,12 +216,22 @@ static int zstd_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
return 0;
}
-const struct zcomp_ops backend_zstd = {
+static void zstd_destroy_ops(struct zcomp_ops *backend_zstd)
+{
+}
+
+struct zcomp_ops backend_zstd = {
.compress = zstd_compress,
.decompress = zstd_decompress,
.create_ctx = zstd_create,
.destroy_ctx = zstd_destroy,
.setup_params = zstd_setup_params,
.release_params = zstd_release_params,
+ .destroy = zstd_destroy_ops,
.name = "zstd",
};
+
+struct zcomp_ops *get_backend_zstd(void)
+{
+ return &backend_zstd;
+}
@@ -5,6 +5,6 @@
#include "zcomp.h"
-extern const struct zcomp_ops backend_zstd;
+struct zcomp_ops *get_backend_zstd(void);
#endif /* __BACKEND_ZSTD_H__ */
@@ -9,6 +9,7 @@
#include <linux/cpu.h>
#include <linux/crypto.h>
#include <linux/vmalloc.h>
+#include <linux/list.h>
#include "zcomp.h"
@@ -20,28 +21,7 @@
#include "backend_deflate.h"
#include "backend_842.h"
-static const struct zcomp_ops *backends[] = {
-#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZO)
- &backend_lzorle,
- &backend_lzo,
-#endif
-#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZ4)
- &backend_lz4,
-#endif
-#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZ4HC)
- &backend_lz4hc,
-#endif
-#if IS_ENABLED(CONFIG_ZRAM_BACKEND_ZSTD)
- &backend_zstd,
-#endif
-#if IS_ENABLED(CONFIG_ZRAM_BACKEND_DEFLATE)
- &backend_deflate,
-#endif
-#if IS_ENABLED(CONFIG_ZRAM_BACKEND_842)
- &backend_842,
-#endif
- NULL
-};
+static LIST_HEAD(backends);
static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm)
{
@@ -72,14 +52,13 @@ static int zcomp_strm_init(struct zcomp *comp, struct zcomp_strm *zstrm)
static const struct zcomp_ops *lookup_backend_ops(const char *comp)
{
- int i = 0;
+ struct zcomp_ops *backend;
- while (backends[i]) {
- if (sysfs_streq(comp, backends[i]->name))
- break;
- i++;
- }
- return backends[i];
+ list_for_each_entry(backend, &backends, list)
+ if (sysfs_streq(comp, backend->name))
+ return backend;
+
+ return NULL;
}
bool zcomp_available_algorithm(const char *comp)
@@ -91,15 +70,15 @@ bool zcomp_available_algorithm(const char *comp)
ssize_t zcomp_available_show(const char *comp, char *buf)
{
ssize_t sz = 0;
- int i;
+ struct zcomp_ops *backend;
- for (i = 0; i < ARRAY_SIZE(backends) - 1; i++) {
- if (!strcmp(comp, backends[i]->name)) {
+ list_for_each_entry(backend, &backends, list) {
+ if (!strcmp(comp, backend->name)) {
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
- "[%s] ", backends[i]->name);
+ "[%s] ", backend->name);
} else {
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
- "%s ", backends[i]->name);
+ "%s ", backend->name);
}
}
@@ -211,14 +190,6 @@ struct zcomp *zcomp_create(const char *alg, struct zcomp_params *params)
struct zcomp *comp;
int error;
- /*
- * The backends array has a sentinel NULL value, so the minimum
- * size is 1. In order to be valid the array, apart from the
- * sentinel NULL element, should have at least one compression
- * backend selected.
- */
- BUILD_BUG_ON(ARRAY_SIZE(backends) <= 1);
-
comp = kzalloc(sizeof(struct zcomp), GFP_KERNEL);
if (!comp)
return ERR_PTR(-ENOMEM);
@@ -236,3 +207,72 @@ struct zcomp *zcomp_create(const char *alg, struct zcomp_params *params)
}
return comp;
}
+
+void clean_zcomp_backends(void)
+{
+ struct zcomp_ops *backend;
+
+ list_for_each_entry(backend, &backends, list)
+ backend->destroy(backend);
+}
+
+int init_zcomp_backends(void)
+{
+ struct zcomp_ops *ops;
+
+#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZO)
+ ops = get_backend_lzorle();
+ if (IS_ERR_OR_NULL(ops))
+ goto err;
+
+ list_add(&ops->list, &backends);
+
+ ops = get_backend_lzo();
+ if (IS_ERR_OR_NULL(ops))
+ goto err;
+
+ list_add(&ops->list, &backends);
+#endif
+#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZ4)
+ ops = get_backend_lz4();
+ if (IS_ERR_OR_NULL(ops))
+ goto err;
+
+ list_add(&ops->list, &backends);
+#endif
+#if IS_ENABLED(CONFIG_ZRAM_BACKEND_LZ4HC)
+ ops = get_backend_lz4hc();
+ if (IS_ERR_OR_NULL(ops))
+ goto err;
+
+ list_add(&ops->list, &backends);
+#endif
+#if IS_ENABLED(CONFIG_ZRAM_BACKEND_ZSTD)
+ ops = get_backend_zstd();
+ if (IS_ERR_OR_NULL(ops))
+ goto err;
+
+ list_add(&ops->list, &backends);
+#endif
+#if IS_ENABLED(CONFIG_ZRAM_BACKEND_DEFLATE)
+ ops = get_backend_deflate();
+ if (IS_ERR_OR_NULL(ops))
+ goto err;
+
+ list_add(&ops->list, &backends);
+#endif
+#if IS_ENABLED(CONFIG_ZRAM_BACKEND_842)
+ ops = get_backend_842();
+ if (IS_ERR_OR_NULL(ops))
+ goto err;
+
+ list_add(&ops->list, &backends);
+#endif
+
+ return 0;
+
+err:
+ clean_zcomp_backends();
+
+ return PTR_ERR(ops);
+}
@@ -59,7 +59,11 @@ struct zcomp_ops {
int (*setup_params)(struct zcomp_params *params);
void (*release_params)(struct zcomp_params *params);
+ void (*destroy)(struct zcomp_ops *ops);
+
const char *name;
+
+ struct list_head list;
};
/* dynamic per-device compression frontend */
@@ -86,4 +90,7 @@ int zcomp_compress(struct zcomp *comp, struct zcomp_strm *zstrm,
int zcomp_decompress(struct zcomp *comp, struct zcomp_strm *zstrm,
const void *src, unsigned int src_len, void *dst);
+void clean_zcomp_backends(void);
+int init_zcomp_backends(void);
+
#endif /* _ZCOMP_H_ */
@@ -2726,6 +2726,7 @@ static void destroy_devices(void)
idr_destroy(&zram_index_idr);
unregister_blkdev(zram_major, "zram");
cpuhp_remove_multi_state(CPUHP_ZCOMP_PREPARE);
+ clean_zcomp_backends();
}
static int __init zram_init(void)
@@ -2765,6 +2766,12 @@ static int __init zram_init(void)
num_devices--;
}
+ ret = init_zcomp_backends();
+ if (ret) {
+ pr_err("Unable to create zcomp devices\n");
+ goto out_error;
+ }
+
return 0;
out_error:
This approach allows us to add backends in runtime. We will use this in next patches. Signed-off-by: Alexey Romanov <avromanov@salutedevices.com> --- drivers/block/zram/backend_842.c | 12 ++- drivers/block/zram/backend_842.h | 2 +- drivers/block/zram/backend_deflate.c | 12 ++- drivers/block/zram/backend_deflate.h | 2 +- drivers/block/zram/backend_lz4.c | 12 ++- drivers/block/zram/backend_lz4.h | 2 +- drivers/block/zram/backend_lz4hc.c | 12 ++- drivers/block/zram/backend_lz4hc.h | 2 +- drivers/block/zram/backend_lzo.c | 12 ++- drivers/block/zram/backend_lzo.h | 2 +- drivers/block/zram/backend_lzorle.c | 12 ++- drivers/block/zram/backend_lzorle.h | 2 +- drivers/block/zram/backend_zstd.c | 12 ++- drivers/block/zram/backend_zstd.h | 2 +- drivers/block/zram/zcomp.c | 124 ++++++++++++++++++--------- drivers/block/zram/zcomp.h | 7 ++ drivers/block/zram/zram_drv.c | 7 ++ 17 files changed, 180 insertions(+), 56 deletions(-)