diff options
author | Dan Magenheimer <dan.magenheimer@oracle.com> | 2013-04-30 18:27:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-30 20:04:01 -0400 |
commit | 835f2f51608fd80e1aef5a8955dabcc36ea528a4 (patch) | |
tree | 6faea4b90d9c76ce7962ebcce0b5b98373e44f3c | |
parent | 1ac37bee81531cb62a9a64e78ffdad7da9b20ea2 (diff) |
staging: zcache: enable zcache to be built/loaded as a module
Allow zcache 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 zcache
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.magenheimer@oracle.com>
[v1: Rebased with different order of patches]
[v2: Removed [CLEANCACHE|FRONTSWAP]_HAS_LAZY_INIT ifdef]
[v3: Rebased on top of ramster->zcache move]
[v4: Redid the Makefile]
[v5: s/ZCACHE2/ZCACHE/]
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Bob Liu <lliubbo@gmail.com>
Cc: Wanpeng Li <liwanp@linux.vnet.ibm.com>
Cc: Andor Daam <andor.daam@googlemail.com>
Cc: Florian Schmaus <fschmaus@gmail.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Stefan Hengelein <ilendir@googlemail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/staging/zcache/Kconfig | 6 | ||||
-rw-r--r-- | drivers/staging/zcache/tmem.c | 6 | ||||
-rw-r--r-- | drivers/staging/zcache/tmem.h | 8 | ||||
-rw-r--r-- | drivers/staging/zcache/zcache-main.c | 45 | ||||
-rw-r--r-- | drivers/staging/zcache/zcache.h | 2 |
5 files changed, 55 insertions, 12 deletions
diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig index 05e87a1e5d93..2d7b2da3b9e0 100644 --- a/drivers/staging/zcache/Kconfig +++ b/drivers/staging/zcache/Kconfig | |||
@@ -1,5 +1,5 @@ | |||
1 | config ZCACHE | 1 | config ZCACHE |
2 | bool "Dynamic compression of swap pages and clean pagecache pages" | 2 | tristate "Dynamic compression of swap pages and clean pagecache pages" |
3 | depends on CRYPTO=y && SWAP=y && CLEANCACHE && FRONTSWAP | 3 | depends on CRYPTO=y && SWAP=y && CLEANCACHE && FRONTSWAP |
4 | select CRYPTO_LZO | 4 | select CRYPTO_LZO |
5 | default n | 5 | default n |
@@ -19,8 +19,8 @@ config ZCACHE_DEBUG | |||
19 | how zcache is doing. You probably want to set this to 'N'. | 19 | how zcache is doing. You probably want to set this to 'N'. |
20 | 20 | ||
21 | config RAMSTER | 21 | config RAMSTER |
22 | bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" | 22 | tristate "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" |
23 | depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE=y | 23 | depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE |
24 | depends on NET | 24 | depends on NET |
25 | # must ensure struct page is 8-byte aligned | 25 | # must ensure struct page is 8-byte aligned |
26 | select HAVE_ALIGNED_STRUCT_PAGE if !64BIT | 26 | select HAVE_ALIGNED_STRUCT_PAGE if !64BIT |
diff --git a/drivers/staging/zcache/tmem.c b/drivers/staging/zcache/tmem.c index a2b7e03b6062..d7e51e4152eb 100644 --- a/drivers/staging/zcache/tmem.c +++ b/drivers/staging/zcache/tmem.c | |||
@@ -35,7 +35,8 @@ | |||
35 | #include <linux/list.h> | 35 | #include <linux/list.h> |
36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/atomic.h> | 37 | #include <linux/atomic.h> |
38 | #ifdef CONFIG_RAMSTER | 38 | #include <linux/export.h> |
39 | #if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE) | ||
39 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
40 | #endif | 41 | #endif |
41 | 42 | ||
@@ -641,6 +642,7 @@ void *tmem_localify_get_pampd(struct tmem_pool *pool, struct tmem_oid *oidp, | |||
641 | /* note, hashbucket remains locked */ | 642 | /* note, hashbucket remains locked */ |
642 | return pampd; | 643 | return pampd; |
643 | } | 644 | } |
645 | EXPORT_SYMBOL_GPL(tmem_localify_get_pampd); | ||
644 | 646 | ||
645 | void tmem_localify_finish(struct tmem_obj *obj, uint32_t index, | 647 | void tmem_localify_finish(struct tmem_obj *obj, uint32_t index, |
646 | void *pampd, void *saved_hb, bool delete) | 648 | void *pampd, void *saved_hb, bool delete) |
@@ -658,6 +660,7 @@ void tmem_localify_finish(struct tmem_obj *obj, uint32_t index, | |||
658 | } | 660 | } |
659 | spin_unlock(&hb->lock); | 661 | spin_unlock(&hb->lock); |
660 | } | 662 | } |
663 | EXPORT_SYMBOL_GPL(tmem_localify_finish); | ||
661 | 664 | ||
662 | /* | 665 | /* |
663 | * For ramster only. Helper function to support asynchronous tmem_get. | 666 | * For ramster only. Helper function to support asynchronous tmem_get. |
@@ -719,6 +722,7 @@ out: | |||
719 | spin_unlock(&hb->lock); | 722 | spin_unlock(&hb->lock); |
720 | return ret; | 723 | return ret; |
721 | } | 724 | } |
725 | EXPORT_SYMBOL_GPL(tmem_replace); | ||
722 | #endif | 726 | #endif |
723 | 727 | ||
724 | /* | 728 | /* |
diff --git a/drivers/staging/zcache/tmem.h b/drivers/staging/zcache/tmem.h index adbe5a8f28aa..d128ce290f1f 100644 --- a/drivers/staging/zcache/tmem.h +++ b/drivers/staging/zcache/tmem.h | |||
@@ -126,7 +126,7 @@ static inline unsigned tmem_oid_hash(struct tmem_oid *oidp) | |||
126 | TMEM_HASH_BUCKET_BITS); | 126 | TMEM_HASH_BUCKET_BITS); |
127 | } | 127 | } |
128 | 128 | ||
129 | #ifdef CONFIG_RAMSTER | 129 | #if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE) |
130 | struct tmem_xhandle { | 130 | struct tmem_xhandle { |
131 | uint8_t client_id; | 131 | uint8_t client_id; |
132 | uint8_t xh_data_cksum; | 132 | uint8_t xh_data_cksum; |
@@ -171,7 +171,7 @@ struct tmem_obj { | |||
171 | unsigned int objnode_tree_height; | 171 | unsigned int objnode_tree_height; |
172 | unsigned long objnode_count; | 172 | unsigned long objnode_count; |
173 | long pampd_count; | 173 | long pampd_count; |
174 | #ifdef CONFIG_RAMSTER | 174 | #if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE) |
175 | /* | 175 | /* |
176 | * for current design of ramster, all pages belonging to | 176 | * for current design of ramster, all pages belonging to |
177 | * an object reside on the same remotenode and extra is | 177 | * an object reside on the same remotenode and extra is |
@@ -215,7 +215,7 @@ struct tmem_pamops { | |||
215 | uint32_t); | 215 | uint32_t); |
216 | void (*free)(void *, struct tmem_pool *, | 216 | void (*free)(void *, struct tmem_pool *, |
217 | struct tmem_oid *, uint32_t, bool); | 217 | struct tmem_oid *, uint32_t, bool); |
218 | #ifdef CONFIG_RAMSTER | 218 | #if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE) |
219 | void (*new_obj)(struct tmem_obj *); | 219 | void (*new_obj)(struct tmem_obj *); |
220 | void (*free_obj)(struct tmem_pool *, struct tmem_obj *, bool); | 220 | void (*free_obj)(struct tmem_pool *, struct tmem_obj *, bool); |
221 | void *(*repatriate_preload)(void *, struct tmem_pool *, | 221 | void *(*repatriate_preload)(void *, struct tmem_pool *, |
@@ -247,7 +247,7 @@ extern int tmem_flush_page(struct tmem_pool *, struct tmem_oid *, | |||
247 | extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *); | 247 | extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *); |
248 | extern int tmem_destroy_pool(struct tmem_pool *); | 248 | extern int tmem_destroy_pool(struct tmem_pool *); |
249 | extern void tmem_new_pool(struct tmem_pool *, uint32_t); | 249 | extern void tmem_new_pool(struct tmem_pool *, uint32_t); |
250 | #ifdef CONFIG_RAMSTER | 250 | #if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE) |
251 | extern int tmem_replace(struct tmem_pool *, struct tmem_oid *, uint32_t index, | 251 | extern int tmem_replace(struct tmem_pool *, struct tmem_oid *, uint32_t index, |
252 | void *); | 252 | void *); |
253 | extern void *tmem_localify_get_pampd(struct tmem_pool *, struct tmem_oid *, | 253 | extern void *tmem_localify_get_pampd(struct tmem_pool *, struct tmem_oid *, |
diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 326c2ea17c38..522cb8e55142 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c | |||
@@ -37,8 +37,10 @@ | |||
37 | #include "debug.h" | 37 | #include "debug.h" |
38 | #ifdef CONFIG_RAMSTER | 38 | #ifdef CONFIG_RAMSTER |
39 | static bool ramster_enabled __read_mostly; | 39 | static bool ramster_enabled __read_mostly; |
40 | static int disable_frontswap_selfshrink; | ||
40 | #else | 41 | #else |
41 | #define ramster_enabled false | 42 | #define ramster_enabled false |
43 | #define disable_frontswap_selfshrink 0 | ||
42 | #endif | 44 | #endif |
43 | 45 | ||
44 | #ifndef __PG_WAS_ACTIVE | 46 | #ifndef __PG_WAS_ACTIVE |
@@ -81,8 +83,12 @@ static char *namestr __read_mostly = "zcache"; | |||
81 | (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) | 83 | (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) |
82 | 84 | ||
83 | /* crypto API for zcache */ | 85 | /* crypto API for zcache */ |
86 | #ifdef CONFIG_ZCACHE_MODULE | ||
87 | static char *zcache_comp_name = "lzo"; | ||
88 | #else | ||
84 | #define ZCACHE_COMP_NAME_SZ CRYPTO_MAX_ALG_NAME | 89 | #define ZCACHE_COMP_NAME_SZ CRYPTO_MAX_ALG_NAME |
85 | static char zcache_comp_name[ZCACHE_COMP_NAME_SZ] __read_mostly; | 90 | static char zcache_comp_name[ZCACHE_COMP_NAME_SZ] __read_mostly; |
91 | #endif | ||
86 | static struct crypto_comp * __percpu *zcache_comp_pcpu_tfms __read_mostly; | 92 | static struct crypto_comp * __percpu *zcache_comp_pcpu_tfms __read_mostly; |
87 | 93 | ||
88 | enum comp_op { | 94 | enum comp_op { |
@@ -1721,6 +1727,7 @@ struct frontswap_ops *zcache_frontswap_register_ops(void) | |||
1721 | * OR NOTHING HAPPENS! | 1727 | * OR NOTHING HAPPENS! |
1722 | */ | 1728 | */ |
1723 | 1729 | ||
1730 | #ifndef CONFIG_ZCACHE_MODULE | ||
1724 | static int __init enable_zcache(char *s) | 1731 | static int __init enable_zcache(char *s) |
1725 | { | 1732 | { |
1726 | zcache_enabled = true; | 1733 | zcache_enabled = true; |
@@ -1787,18 +1794,27 @@ static int __init enable_zcache_compressor(char *s) | |||
1787 | return 1; | 1794 | return 1; |
1788 | } | 1795 | } |
1789 | __setup("zcache=", enable_zcache_compressor); | 1796 | __setup("zcache=", enable_zcache_compressor); |
1797 | #endif | ||
1790 | 1798 | ||
1791 | 1799 | ||
1792 | static int __init zcache_comp_init(void) | 1800 | static int zcache_comp_init(void) |
1793 | { | 1801 | { |
1794 | int ret = 0; | 1802 | int ret = 0; |
1795 | 1803 | ||
1796 | /* check crypto algorithm */ | 1804 | /* check crypto algorithm */ |
1805 | #ifdef CONFIG_ZCACHE_MODULE | ||
1806 | ret = crypto_has_comp(zcache_comp_name, 0, 0); | ||
1807 | if (!ret) { | ||
1808 | ret = -1; | ||
1809 | goto out; | ||
1810 | } | ||
1811 | #else | ||
1797 | if (*zcache_comp_name != '\0') { | 1812 | if (*zcache_comp_name != '\0') { |
1798 | ret = crypto_has_comp(zcache_comp_name, 0, 0); | 1813 | ret = crypto_has_comp(zcache_comp_name, 0, 0); |
1799 | if (!ret) | 1814 | if (!ret) |
1800 | pr_info("zcache: %s not supported\n", | 1815 | pr_info("zcache: %s not supported\n", |
1801 | zcache_comp_name); | 1816 | zcache_comp_name); |
1817 | goto out; | ||
1802 | } | 1818 | } |
1803 | if (!ret) | 1819 | if (!ret) |
1804 | strcpy(zcache_comp_name, "lzo"); | 1820 | strcpy(zcache_comp_name, "lzo"); |
@@ -1807,6 +1823,7 @@ static int __init zcache_comp_init(void) | |||
1807 | ret = 1; | 1823 | ret = 1; |
1808 | goto out; | 1824 | goto out; |
1809 | } | 1825 | } |
1826 | #endif | ||
1810 | pr_info("zcache: using %s compressor\n", zcache_comp_name); | 1827 | pr_info("zcache: using %s compressor\n", zcache_comp_name); |
1811 | 1828 | ||
1812 | /* alloc percpu transforms */ | 1829 | /* alloc percpu transforms */ |
@@ -1818,10 +1835,13 @@ out: | |||
1818 | return ret; | 1835 | return ret; |
1819 | } | 1836 | } |
1820 | 1837 | ||
1821 | static int __init zcache_init(void) | 1838 | static int zcache_init(void) |
1822 | { | 1839 | { |
1823 | int ret = 0; | 1840 | int ret = 0; |
1824 | 1841 | ||
1842 | #ifdef CONFIG_ZCACHE_MODULE | ||
1843 | zcache_enabled = 1; | ||
1844 | #endif | ||
1825 | if (ramster_enabled) { | 1845 | if (ramster_enabled) { |
1826 | namestr = "ramster"; | 1846 | namestr = "ramster"; |
1827 | ramster_register_pamops(&zcache_pamops); | 1847 | ramster_register_pamops(&zcache_pamops); |
@@ -1894,9 +1914,28 @@ static int __init zcache_init(void) | |||
1894 | } | 1914 | } |
1895 | if (ramster_enabled) | 1915 | if (ramster_enabled) |
1896 | ramster_init(!disable_cleancache, !disable_frontswap, | 1916 | ramster_init(!disable_cleancache, !disable_frontswap, |
1897 | frontswap_has_exclusive_gets, false); | 1917 | frontswap_has_exclusive_gets, |
1918 | !disable_frontswap_selfshrink); | ||
1898 | out: | 1919 | out: |
1899 | return ret; | 1920 | return ret; |
1900 | } | 1921 | } |
1901 | 1922 | ||
1923 | #ifdef CONFIG_ZCACHE_MODULE | ||
1924 | #ifdef CONFIG_RAMSTER | ||
1925 | module_param(ramster_enabled, int, S_IRUGO); | ||
1926 | module_param(disable_frontswap_selfshrink, int, S_IRUGO); | ||
1927 | #endif | ||
1928 | module_param(disable_cleancache, int, S_IRUGO); | ||
1929 | module_param(disable_frontswap, int, S_IRUGO); | ||
1930 | #ifdef FRONTSWAP_HAS_EXCLUSIVE_GETS | ||
1931 | module_param(frontswap_has_exclusive_gets, bool, S_IRUGO); | ||
1932 | #endif | ||
1933 | module_param(disable_frontswap_ignore_nonactive, int, S_IRUGO); | ||
1934 | module_param(zcache_comp_name, charp, S_IRUGO); | ||
1935 | module_init(zcache_init); | ||
1936 | MODULE_LICENSE("GPL"); | ||
1937 | MODULE_AUTHOR("Dan Magenheimer <dan.magenheimer@oracle.com>"); | ||
1938 | MODULE_DESCRIPTION("In-kernel compression of cleancache/frontswap pages"); | ||
1939 | #else | ||
1902 | late_initcall(zcache_init); | 1940 | late_initcall(zcache_init); |
1941 | #endif | ||
diff --git a/drivers/staging/zcache/zcache.h b/drivers/staging/zcache/zcache.h index 81722b33b087..849120095e79 100644 --- a/drivers/staging/zcache/zcache.h +++ b/drivers/staging/zcache/zcache.h | |||
@@ -39,7 +39,7 @@ extern int zcache_flush_page(int, int, struct tmem_oid *, uint32_t); | |||
39 | extern int zcache_flush_object(int, int, struct tmem_oid *); | 39 | extern int zcache_flush_object(int, int, struct tmem_oid *); |
40 | extern void zcache_decompress_to_page(char *, unsigned int, struct page *); | 40 | extern void zcache_decompress_to_page(char *, unsigned int, struct page *); |
41 | 41 | ||
42 | #ifdef CONFIG_RAMSTER | 42 | #if defined(CONFIG_RAMSTER) || defined(CONFIG_RAMSTER_MODULE) |
43 | extern void *zcache_pampd_create(char *, unsigned int, bool, int, | 43 | extern void *zcache_pampd_create(char *, unsigned int, bool, int, |
44 | struct tmem_handle *); | 44 | struct tmem_handle *); |
45 | int zcache_autocreate_pool(unsigned int cli_id, unsigned int pool_id, bool eph); | 45 | int zcache_autocreate_pool(unsigned int cli_id, unsigned int pool_id, bool eph); |