diff for duplicates of <20121114162540.GA28650@localhost.localdomain> diff --git a/a/1.txt b/N1/1.txt index ce8433b..ef0b2cc 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -199,3 +199,160 @@ I think we are OK. The .bss is set to zero so that means backend_registered is by default zero. The end result would look like this (I had not compiled tested it yet): + +>From a13ed2c85b220c62035ab7ac79ad8a62f9f29c13 Mon Sep 17 00:00:00 2001 +From: Dan Magenheimer <dan.magenheimer@oracle.com> +Date: Wed, 31 Oct 2012 08:07:51 -0700 +Subject: [PATCH] mm: frontswap: lazy initialization to allow tmem backends to + build/run as modules + +With the goal of allowing tmem backends (zcache, ramster, Xen tmem) to be +built/loaded as modules rather than built-in and enabled by a boot parameter, +this patch provides "lazy initialization", allowing backends to register to +frontswap even after swapon was run. Before a backend registers all calls +to init are recorded and the creation of tmem_pools delayed until a backend +registers or until a frontswap put is attempted. + +Signed-off-by: Stefan Hengelein <ilendir@googlemail.com> +Signed-off-by: Florian Schmaus <fschmaus@gmail.com> +Signed-off-by: Andor Daam <andor.daam@googlemail.com> +Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com> +[v1: Fixes per Seth Jennings suggestions] +[v2: Removed FRONTSWAP_HAS_.. ] +[v3: Fix up per Bob Liu <lliubbo@gmail.com> recommendations] +Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +--- + mm/frontswap.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++-------- + 1 files changed, 56 insertions(+), 10 deletions(-) + +diff --git a/mm/frontswap.c b/mm/frontswap.c +index 2890e67..db90736 100644 +--- a/mm/frontswap.c ++++ b/mm/frontswap.c +@@ -80,6 +80,18 @@ static inline void inc_frontswap_succ_stores(void) { } + static inline void inc_frontswap_failed_stores(void) { } + static inline void inc_frontswap_invalidates(void) { } + #endif ++ ++/* ++ * When no backend is registered all calls to init are registered and ++ * remembered but fail to create tmem_pools. When a backend registers with ++ * frontswap the previous calls to init are executed to create tmem_pools ++ * and set the respective poolids. ++ * While no backend is registered all "puts", "gets" and "flushes" are ++ * ignored or fail. ++ */ ++static DECLARE_BITMAP(need_init, MAX_SWAPFILES); ++static bool backend_registered __read_mostly; ++ + /* + * Register operations for frontswap, returning previous thus allowing + * detection of multiple backends and possible nesting. +@@ -87,9 +99,19 @@ static inline void inc_frontswap_invalidates(void) { } + struct frontswap_ops frontswap_register_ops(struct frontswap_ops *ops) + { + struct frontswap_ops old = frontswap_ops; ++ int i; + + frontswap_ops = *ops; + frontswap_enabled = true; ++ ++ for (i = 0; i < MAX_SWAPFILES; i++) { ++ if (test_and_clear_bit(i, need_init)) ++ (*frontswap_ops.init)(i); ++ } ++ /* We MUST have backend_registered called _after_ the frontswap_init's ++ * have been called. Otherwise __frontswap_store might fail. */ ++ barrier(); ++ backend_registered = true; + return old; + } + EXPORT_SYMBOL(frontswap_register_ops); +@@ -119,10 +141,17 @@ void __frontswap_init(unsigned type) + { + struct swap_info_struct *sis = swap_info[type]; + +- BUG_ON(sis == NULL); +- if (sis->frontswap_map == NULL) +- return; +- frontswap_ops.init(type); ++ if (backend_registered) { ++ BUG_ON(sis == NULL); ++ if (sis->frontswap_map == NULL) ++ return; ++ (*frontswap_ops.init)(type); ++ } ++ else { ++ BUG_ON(type > MAX_SWAPFILES); ++ set_bit(type, need_init); ++ } ++ + } + EXPORT_SYMBOL(__frontswap_init); + +@@ -147,6 +176,11 @@ int __frontswap_store(struct page *page) + struct swap_info_struct *sis = swap_info[type]; + pgoff_t offset = swp_offset(entry); + ++ if (!backend_registered) { ++ inc_frontswap_failed_stores(); ++ return ret; ++ } ++ + BUG_ON(!PageLocked(page)); + BUG_ON(sis == NULL); + if (frontswap_test(sis, offset)) +@@ -186,6 +220,9 @@ int __frontswap_load(struct page *page) + struct swap_info_struct *sis = swap_info[type]; + pgoff_t offset = swp_offset(entry); + ++ if (!backend_registered) ++ return ret; ++ + BUG_ON(!PageLocked(page)); + BUG_ON(sis == NULL); + if (frontswap_test(sis, offset)) +@@ -209,6 +246,9 @@ void __frontswap_invalidate_page(unsigned type, pgoff_t offset) + { + struct swap_info_struct *sis = swap_info[type]; + ++ if (!backend_registered) ++ return; ++ + BUG_ON(sis == NULL); + if (frontswap_test(sis, offset)) { + frontswap_ops.invalidate_page(type, offset); +@@ -226,12 +266,15 @@ void __frontswap_invalidate_area(unsigned type) + { + struct swap_info_struct *sis = swap_info[type]; + +- BUG_ON(sis == NULL); +- if (sis->frontswap_map == NULL) +- return; +- frontswap_ops.invalidate_area(type); +- atomic_set(&sis->frontswap_pages, 0); +- memset(sis->frontswap_map, 0, sis->max / sizeof(long)); ++ if (backend_registered) { ++ BUG_ON(sis == NULL); ++ if (sis->frontswap_map == NULL) ++ return; ++ (*frontswap_ops.invalidate_area)(type); ++ atomic_set(&sis->frontswap_pages, 0); ++ memset(sis->frontswap_map, 0, sis->max / sizeof(long)); ++ } ++ clear_bit(need_init, MAX_SWAPFILES); + } + EXPORT_SYMBOL(__frontswap_invalidate_area); + +@@ -364,6 +407,9 @@ static int __init init_frontswap(void) + debugfs_create_u64("invalidates", S_IRUGO, + root, &frontswap_invalidates); + #endif ++ bitmap_zero(need_init, MAX_SWAPFILES); ++ ++ frontswap_enabled = 1; + return 0; + } + +-- +1.7.7.6 diff --git a/a/content_digest b/N1/content_digest index 2972361..e05ed4a 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -222,6 +222,163 @@ "I think we are OK. The .bss is set to zero so that means\n" "backend_registered is by default zero.\n" "\n" - The end result would look like this (I had not compiled tested it yet): + "The end result would look like this (I had not compiled tested it yet):\n" + "\n" + ">From a13ed2c85b220c62035ab7ac79ad8a62f9f29c13 Mon Sep 17 00:00:00 2001\n" + "From: Dan Magenheimer <dan.magenheimer@oracle.com>\n" + "Date: Wed, 31 Oct 2012 08:07:51 -0700\n" + "Subject: [PATCH] mm: frontswap: lazy initialization to allow tmem backends to\n" + " build/run as modules\n" + "\n" + "With the goal of allowing tmem backends (zcache, ramster, Xen tmem) to be\n" + "built/loaded as modules rather than built-in and enabled by a boot parameter,\n" + "this patch provides \"lazy initialization\", allowing backends to register to\n" + "frontswap even after swapon was run. Before a backend registers all calls\n" + "to init are recorded and the creation of tmem_pools delayed until a backend\n" + "registers or until a frontswap put is attempted.\n" + "\n" + "Signed-off-by: Stefan Hengelein <ilendir@googlemail.com>\n" + "Signed-off-by: Florian Schmaus <fschmaus@gmail.com>\n" + "Signed-off-by: Andor Daam <andor.daam@googlemail.com>\n" + "Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com>\n" + "[v1: Fixes per Seth Jennings suggestions]\n" + "[v2: Removed FRONTSWAP_HAS_.. ]\n" + "[v3: Fix up per Bob Liu <lliubbo@gmail.com> recommendations]\n" + "Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>\n" + "---\n" + " mm/frontswap.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++--------\n" + " 1 files changed, 56 insertions(+), 10 deletions(-)\n" + "\n" + "diff --git a/mm/frontswap.c b/mm/frontswap.c\n" + "index 2890e67..db90736 100644\n" + "--- a/mm/frontswap.c\n" + "+++ b/mm/frontswap.c\n" + "@@ -80,6 +80,18 @@ static inline void inc_frontswap_succ_stores(void) { }\n" + " static inline void inc_frontswap_failed_stores(void) { }\n" + " static inline void inc_frontswap_invalidates(void) { }\n" + " #endif\n" + "+\n" + "+/*\n" + "+ * When no backend is registered all calls to init are registered and\n" + "+ * remembered but fail to create tmem_pools. When a backend registers with\n" + "+ * frontswap the previous calls to init are executed to create tmem_pools\n" + "+ * and set the respective poolids.\n" + "+ * While no backend is registered all \"puts\", \"gets\" and \"flushes\" are\n" + "+ * ignored or fail.\n" + "+ */\n" + "+static DECLARE_BITMAP(need_init, MAX_SWAPFILES);\n" + "+static bool backend_registered __read_mostly;\n" + "+\n" + " /*\n" + " * Register operations for frontswap, returning previous thus allowing\n" + " * detection of multiple backends and possible nesting.\n" + "@@ -87,9 +99,19 @@ static inline void inc_frontswap_invalidates(void) { }\n" + " struct frontswap_ops frontswap_register_ops(struct frontswap_ops *ops)\n" + " {\n" + " \tstruct frontswap_ops old = frontswap_ops;\n" + "+\tint i;\n" + " \n" + " \tfrontswap_ops = *ops;\n" + " \tfrontswap_enabled = true;\n" + "+\n" + "+\tfor (i = 0; i < MAX_SWAPFILES; i++) {\n" + "+\t\tif (test_and_clear_bit(i, need_init))\n" + "+\t\t\t(*frontswap_ops.init)(i);\n" + "+\t}\n" + "+\t/* We MUST have backend_registered called _after_ the frontswap_init's\n" + "+ \t * have been called. Otherwise __frontswap_store might fail. */\n" + "+\tbarrier();\n" + "+\tbackend_registered = true;\n" + " \treturn old;\n" + " }\n" + " EXPORT_SYMBOL(frontswap_register_ops);\n" + "@@ -119,10 +141,17 @@ void __frontswap_init(unsigned type)\n" + " {\n" + " \tstruct swap_info_struct *sis = swap_info[type];\n" + " \n" + "-\tBUG_ON(sis == NULL);\n" + "-\tif (sis->frontswap_map == NULL)\n" + "-\t\treturn;\n" + "-\tfrontswap_ops.init(type);\n" + "+\tif (backend_registered) {\n" + "+\t\tBUG_ON(sis == NULL);\n" + "+\t\tif (sis->frontswap_map == NULL)\n" + "+\t\t\treturn;\n" + "+\t\t(*frontswap_ops.init)(type);\n" + "+\t}\n" + "+\telse {\n" + "+\t\tBUG_ON(type > MAX_SWAPFILES);\n" + "+\t\tset_bit(type, need_init);\n" + "+\t}\n" + "+\n" + " }\n" + " EXPORT_SYMBOL(__frontswap_init);\n" + " \n" + "@@ -147,6 +176,11 @@ int __frontswap_store(struct page *page)\n" + " \tstruct swap_info_struct *sis = swap_info[type];\n" + " \tpgoff_t offset = swp_offset(entry);\n" + " \n" + "+\tif (!backend_registered) {\n" + "+\t\tinc_frontswap_failed_stores();\n" + "+\t\treturn ret;\n" + "+\t}\n" + "+\n" + " \tBUG_ON(!PageLocked(page));\n" + " \tBUG_ON(sis == NULL);\n" + " \tif (frontswap_test(sis, offset))\n" + "@@ -186,6 +220,9 @@ int __frontswap_load(struct page *page)\n" + " \tstruct swap_info_struct *sis = swap_info[type];\n" + " \tpgoff_t offset = swp_offset(entry);\n" + " \n" + "+\tif (!backend_registered)\n" + "+\t\treturn ret;\n" + "+\n" + " \tBUG_ON(!PageLocked(page));\n" + " \tBUG_ON(sis == NULL);\n" + " \tif (frontswap_test(sis, offset))\n" + "@@ -209,6 +246,9 @@ void __frontswap_invalidate_page(unsigned type, pgoff_t offset)\n" + " {\n" + " \tstruct swap_info_struct *sis = swap_info[type];\n" + " \n" + "+\tif (!backend_registered)\n" + "+\t\treturn;\n" + "+\n" + " \tBUG_ON(sis == NULL);\n" + " \tif (frontswap_test(sis, offset)) {\n" + " \t\tfrontswap_ops.invalidate_page(type, offset);\n" + "@@ -226,12 +266,15 @@ void __frontswap_invalidate_area(unsigned type)\n" + " {\n" + " \tstruct swap_info_struct *sis = swap_info[type];\n" + " \n" + "-\tBUG_ON(sis == NULL);\n" + "-\tif (sis->frontswap_map == NULL)\n" + "-\t\treturn;\n" + "-\tfrontswap_ops.invalidate_area(type);\n" + "-\tatomic_set(&sis->frontswap_pages, 0);\n" + "-\tmemset(sis->frontswap_map, 0, sis->max / sizeof(long));\n" + "+\tif (backend_registered) {\n" + "+\t\tBUG_ON(sis == NULL);\n" + "+\t\tif (sis->frontswap_map == NULL)\n" + "+\t\t\treturn;\n" + "+\t\t(*frontswap_ops.invalidate_area)(type);\n" + "+\t\tatomic_set(&sis->frontswap_pages, 0);\n" + "+\t\tmemset(sis->frontswap_map, 0, sis->max / sizeof(long));\n" + "+\t}\n" + "+\tclear_bit(need_init, MAX_SWAPFILES);\n" + " }\n" + " EXPORT_SYMBOL(__frontswap_invalidate_area);\n" + " \n" + "@@ -364,6 +407,9 @@ static int __init init_frontswap(void)\n" + " \tdebugfs_create_u64(\"invalidates\", S_IRUGO,\n" + " \t\t\t\troot, &frontswap_invalidates);\n" + " #endif\n" + "+\tbitmap_zero(need_init, MAX_SWAPFILES);\n" + "+\n" + "+\tfrontswap_enabled = 1;\n" + " \treturn 0;\n" + " }\n" + " \n" + "-- \n" + 1.7.7.6 -7b46d5b4abf5a4d8f16792aaa9e6a05c8653b7ec399001f25e1852fc03176561 +9a24ba4c75def75dea45c7c8a3101e9d99b482246137ecce26ce84ea7f0da599
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.