All of lore.kernel.org
 help / color / mirror / Atom feed
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.