Allow zcache2 to be built/loaded as a module.  Note runtime dependency
disallows loading if cleancache/frontswap lazy initialization patches
are not present.  Zsmalloc support has not yet been merged into zcache2
but, once merged, could now easily be selected via a module_param.

If built-in (not built as a module), the original mechanism of enabling via
a kernel boot parameter is retained, but this should be considered deprecated.

Note that module unload is explicitly not yet supported.

Signed-off-by: Dan Magenheimer <dan.magenhei...@oracle.com>
---
 drivers/staging/ramster/Kconfig       |    6 ++--
 drivers/staging/ramster/Makefile      |   11 +++---
 drivers/staging/ramster/tmem.c        |    6 +++-
 drivers/staging/ramster/tmem.h        |    8 ++--
 drivers/staging/ramster/zcache-main.c |   61 ++++++++++++++++++++++++++++++--
 drivers/staging/ramster/zcache.h      |    2 +-
 6 files changed, 76 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig
index 843c541..fd3e767 100644
--- a/drivers/staging/ramster/Kconfig
+++ b/drivers/staging/ramster/Kconfig
@@ -1,5 +1,5 @@
 config ZCACHE2
-       bool "Dynamic compression of swap pages and clean pagecache pages"
+       tristate "Dynamic compression of swap pages and clean pagecache pages"
        depends on CRYPTO=y && SWAP=y && CLEANCACHE && FRONTSWAP && !ZCACHE 
        select CRYPTO_LZO
        default n
@@ -16,8 +16,8 @@ config ZCACHE2
          version of ramster.
 
 config RAMSTER
-       bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem"
-       depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE2=y
+       tristate "Cross-machine RAM capacity sharing, aka peer-to-peer tmem"
+       depends on CONFIGFS_FS && SYSFS && !HIGHMEM && ZCACHE2
        # must ensure struct page is 8-byte aligned
        select HAVE_ALIGNED_STRUCT_PAGE if !64_BIT
        default n
diff --git a/drivers/staging/ramster/Makefile b/drivers/staging/ramster/Makefile
index 2d8b9d0..fcb25cb 100644
--- a/drivers/staging/ramster/Makefile
+++ b/drivers/staging/ramster/Makefile
@@ -1,6 +1,7 @@
 zcache-y       :=              zcache-main.o tmem.o zbud.o
-zcache-$(CONFIG_RAMSTER)       +=      ramster/ramster.o ramster/r2net.o
-zcache-$(CONFIG_RAMSTER)       +=      ramster/nodemanager.o ramster/tcp.o
-zcache-$(CONFIG_RAMSTER)       +=      ramster/heartbeat.o ramster/masklog.o
-
-obj-$(CONFIG_ZCACHE2)  +=      zcache.o
+ifneq (,$(filter $(CONFIG_RAMSTER),y m))
+zcache-y       +=      ramster/ramster.o ramster/r2net.o
+zcache-y       +=      ramster/nodemanager.o ramster/tcp.o
+zcache-y       +=      ramster/heartbeat.o ramster/masklog.o
+endif
+obj-$(CONFIG_MODULES)  += zcache.o
diff --git a/drivers/staging/ramster/tmem.c b/drivers/staging/ramster/tmem.c
index a2b7e03..d7e51e4 100644
--- a/drivers/staging/ramster/tmem.c
+++ b/drivers/staging/ramster/tmem.c
@@ -35,7 +35,8 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/atomic.h>
-#ifdef CONFIG_RAMSTER
+#include <linux/export.h>
+#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE)
 #include <linux/delay.h>
 #endif
 
@@ -641,6 +642,7 @@ void *tmem_localify_get_pampd(struct tmem_pool *pool, 
struct tmem_oid *oidp,
        /* note, hashbucket remains locked */
        return pampd;
 }
+EXPORT_SYMBOL_GPL(tmem_localify_get_pampd);
 
 void tmem_localify_finish(struct tmem_obj *obj, uint32_t index,
                          void *pampd, void *saved_hb, bool delete)
@@ -658,6 +660,7 @@ void tmem_localify_finish(struct tmem_obj *obj, uint32_t 
index,
        }
        spin_unlock(&hb->lock);
 }
+EXPORT_SYMBOL_GPL(tmem_localify_finish);
 
 /*
  * For ramster only.  Helper function to support asynchronous tmem_get.
@@ -719,6 +722,7 @@ out:
        spin_unlock(&hb->lock);
        return ret;
 }
+EXPORT_SYMBOL_GPL(tmem_replace);
 #endif
 
 /*
diff --git a/drivers/staging/ramster/tmem.h b/drivers/staging/ramster/tmem.h
index adbe5a8..d128ce2 100644
--- a/drivers/staging/ramster/tmem.h
+++ b/drivers/staging/ramster/tmem.h
@@ -126,7 +126,7 @@ static inline unsigned tmem_oid_hash(struct tmem_oid *oidp)
                                TMEM_HASH_BUCKET_BITS);
 }
 
-#ifdef CONFIG_RAMSTER
+#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE)
 struct tmem_xhandle {
        uint8_t client_id;
        uint8_t xh_data_cksum;
@@ -171,7 +171,7 @@ struct tmem_obj {
        unsigned int objnode_tree_height;
        unsigned long objnode_count;
        long pampd_count;
-#ifdef CONFIG_RAMSTER
+#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE)
        /*
         * for current design of ramster, all pages belonging to
         * an object reside on the same remotenode and extra is
@@ -215,7 +215,7 @@ struct tmem_pamops {
                                uint32_t);
        void (*free)(void *, struct tmem_pool *,
                                struct tmem_oid *, uint32_t, bool);
-#ifdef CONFIG_RAMSTER
+#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE)
        void (*new_obj)(struct tmem_obj *);
        void (*free_obj)(struct tmem_pool *, struct tmem_obj *, bool);
        void *(*repatriate_preload)(void *, struct tmem_pool *,
@@ -247,7 +247,7 @@ extern int tmem_flush_page(struct tmem_pool *, struct 
tmem_oid *,
 extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *);
 extern int tmem_destroy_pool(struct tmem_pool *);
 extern void tmem_new_pool(struct tmem_pool *, uint32_t);
-#ifdef CONFIG_RAMSTER
+#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE)
 extern int tmem_replace(struct tmem_pool *, struct tmem_oid *, uint32_t index,
                        void *);
 extern void *tmem_localify_get_pampd(struct tmem_pool *, struct tmem_oid *,
diff --git a/drivers/staging/ramster/zcache-main.c 
b/drivers/staging/ramster/zcache-main.c
index a09dd5c..956d16d 100644
--- a/drivers/staging/ramster/zcache-main.c
+++ b/drivers/staging/ramster/zcache-main.c
@@ -31,8 +31,10 @@
 #include "ramster.h"
 #ifdef CONFIG_RAMSTER
 static int ramster_enabled;
+static int disable_frontswap_selfshrink;
 #else
 #define ramster_enabled 0
+#define disable_frontswap_selfshrink 0
 #endif
 
 #ifndef __PG_WAS_ACTIVE
@@ -68,8 +70,12 @@ static char *namestr __read_mostly = "zcache";
 MODULE_LICENSE("GPL");
 
 /* crypto API for zcache  */
+#ifdef CONFIG_ZCACHE2_MODULE
+static char *zcache_comp_name = "lzo";
+#else
 #define ZCACHE_COMP_NAME_SZ CRYPTO_MAX_ALG_NAME
 static char zcache_comp_name[ZCACHE_COMP_NAME_SZ] __read_mostly;
+#endif
 static struct crypto_comp * __percpu *zcache_comp_pcpu_tfms __read_mostly;
 
 enum comp_op {
@@ -1346,7 +1352,7 @@ static int zcache_local_new_pool(uint32_t flags)
 int zcache_autocreate_pool(unsigned int cli_id, unsigned int pool_id, bool eph)
 {
        struct tmem_pool *pool;
-       struct zcache_client *cli;
+       struct zcache_client *cli = NULL;
        uint32_t flags = eph ? 0 : TMEM_POOL_PERSIST;
        int ret = -1;
 
@@ -1640,6 +1646,7 @@ struct frontswap_ops zcache_frontswap_register_ops(void)
  * OR NOTHING HAPPENS!
  */
 
+#ifndef CONFIG_ZCACHE2_MODULE
 static int __init enable_zcache(char *s)
 {
        zcache_enabled = 1;
@@ -1706,18 +1713,27 @@ static int __init enable_zcache_compressor(char *s)
        return 1;
 }
 __setup("zcache=", enable_zcache_compressor);
+#endif
 
 
-static int __init zcache_comp_init(void)
+static int zcache_comp_init(void)
 {
        int ret = 0;
 
        /* check crypto algorithm */
+#ifdef CONFIG_ZCACHE2_MODULE
+       ret = crypto_has_comp(zcache_comp_name, 0, 0);
+       if (!ret) {
+               ret = -1;
+               goto out;
+       }
+#else
        if (*zcache_comp_name != '\0') {
                ret = crypto_has_comp(zcache_comp_name, 0, 0);
                if (!ret)
                        pr_info("zcache: %s not supported\n",
                                        zcache_comp_name);
+               goto out;
        }
        if (!ret)
                strcpy(zcache_comp_name, "lzo");
@@ -1726,6 +1742,7 @@ static int __init zcache_comp_init(void)
                ret = 1;
                goto out;
        }
+#endif
        pr_info("zcache: using %s compressor\n", zcache_comp_name);
 
        /* alloc percpu transforms */
@@ -1737,10 +1754,27 @@ out:
        return ret;
 }
 
-static int __init zcache_init(void)
+static int zcache_init(void)
 {
        int ret = 0;
 
+#ifdef CONFIG_ZCACHE2_MODULE
+#if defined(CONFIG_FRONTSWAP) && !defined(FRONTSWAP_HAS_LAZY_INIT)
+       /* This ifdef can be removed when frontswap lazy init is merged */
+       if (!disable_frontswap) {
+               pr_err("zcache module requires frontswap lazy init\n");
+               return -EINVAL;
+       }
+#endif
+#if defined(CONFIG_CLEANCACHE) && !defined(CLEANCACHE_HAS_LAZY_INIT)
+       /* This ifdef can be removed when cleancache lazy init is merged */
+       if (!disable_cleancache) {
+               pr_err("zcache module requires cleancache lazy init\n");
+               return -EINVAL;
+       }
+#endif
+       zcache_enabled = 1;
+#endif
        if (ramster_enabled) {
                namestr = "ramster";
                ramster_register_pamops(&zcache_pamops);
@@ -1812,9 +1846,28 @@ static int __init zcache_init(void)
        }
        if (ramster_enabled)
                ramster_init(!disable_cleancache, !disable_frontswap,
-                               frontswap_has_exclusive_gets);
+                               frontswap_has_exclusive_gets,
+                               !disable_frontswap_selfshrink);
 out:
        return ret;
 }
 
+#ifdef CONFIG_ZCACHE2_MODULE
+#ifdef CONFIG_RAMSTER
+module_param(ramster_enabled, int, S_IRUGO);
+module_param(disable_frontswap_selfshrink, int, S_IRUGO);
+#endif
+module_param(disable_cleancache, int, S_IRUGO);
+module_param(disable_frontswap, int, S_IRUGO);
+#ifdef FRONTSWAP_HAS_EXCLUSIVE_GETS
+module_param(frontswap_has_exclusive_gets, bool, S_IRUGO);
+#endif
+module_param(disable_frontswap_ignore_nonactive, int, S_IRUGO);
+module_param(zcache_comp_name, charp, S_IRUGO);
+module_init(zcache_init);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dan Magenheimer <dan.magenhei...@oracle.com>");
+MODULE_DESCRIPTION("In-kernel compression of cleancache/frontswap pages");
+#else
 late_initcall(zcache_init);
+#endif
diff --git a/drivers/staging/ramster/zcache.h b/drivers/staging/ramster/zcache.h
index 81722b3..8491200 100644
--- a/drivers/staging/ramster/zcache.h
+++ b/drivers/staging/ramster/zcache.h
@@ -39,7 +39,7 @@ extern int zcache_flush_page(int, int, struct tmem_oid *, 
uint32_t);
 extern int zcache_flush_object(int, int, struct tmem_oid *);
 extern void zcache_decompress_to_page(char *, unsigned int, struct page *);
 
-#ifdef CONFIG_RAMSTER
+#if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE)
 extern void *zcache_pampd_create(char *, unsigned int, bool, int,
                                struct tmem_handle *);
 int zcache_autocreate_pool(unsigned int cli_id, unsigned int pool_id, bool 
eph);
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to