aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2013-04-30 18:26:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-30 20:04:00 -0400
commit1e01c968db3d0aebd48e31db15f24516b03128df (patch)
tree6f8ebed201fdc426a6926b4a2235e8dd2538f025 /mm
parent905cd0e1bf9ffe82d6906a01fd974ea0f70be97a (diff)
frontswap: make frontswap_init use a pointer for the ops
This simplifies the code in the frontswap - we can get rid of the 'backend_registered' test and instead check against frontswap_ops. [v1: Rebase on top of 703ba7fe5e0 (ramster->zcache move] 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: Dan Magenheimer <dan.magenheimer@oracle.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>
Diffstat (limited to 'mm')
-rw-r--r--mm/frontswap.c38
1 files changed, 18 insertions, 20 deletions
diff --git a/mm/frontswap.c b/mm/frontswap.c
index cbd2b8af8129..e44c9cbd1443 100644
--- a/mm/frontswap.c
+++ b/mm/frontswap.c
@@ -24,7 +24,7 @@
24 * frontswap_ops is set by frontswap_register_ops to contain the pointers 24 * frontswap_ops is set by frontswap_register_ops to contain the pointers
25 * to the frontswap "backend" implementation functions. 25 * to the frontswap "backend" implementation functions.
26 */ 26 */
27static struct frontswap_ops frontswap_ops __read_mostly; 27static struct frontswap_ops *frontswap_ops __read_mostly;
28 28
29/* 29/*
30 * This global enablement flag reduces overhead on systems where frontswap_ops 30 * This global enablement flag reduces overhead on systems where frontswap_ops
@@ -108,41 +108,39 @@ static inline void inc_frontswap_invalidates(void) { }
108 * 108 *
109 * The time between the backend being registered and the swap file system 109 * The time between the backend being registered and the swap file system
110 * calling the backend (via the frontswap_* functions) is indeterminate as 110 * calling the backend (via the frontswap_* functions) is indeterminate as
111 * backend_registered is not atomic_t (or a value guarded by a spinlock). 111 * frontswap_ops is not atomic_t (or a value guarded by a spinlock).
112 * That is OK as we are comfortable missing some of these calls to the newly 112 * That is OK as we are comfortable missing some of these calls to the newly
113 * registered backend. 113 * registered backend.
114 * 114 *
115 * Obviously the opposite (unloading the backend) must be done after all 115 * Obviously the opposite (unloading the backend) must be done after all
116 * the frontswap_[store|load|invalidate_area|invalidate_page] start 116 * the frontswap_[store|load|invalidate_area|invalidate_page] start
117 * ignorning or failing the requests - at which point backend_registered 117 * ignorning or failing the requests - at which point frontswap_ops
118 * would have to be made in some fashion atomic. 118 * would have to be made in some fashion atomic.
119 */ 119 */
120static DECLARE_BITMAP(need_init, MAX_SWAPFILES); 120static DECLARE_BITMAP(need_init, MAX_SWAPFILES);
121static bool backend_registered __read_mostly;
122 121
123/* 122/*
124 * Register operations for frontswap, returning previous thus allowing 123 * Register operations for frontswap, returning previous thus allowing
125 * detection of multiple backends and possible nesting. 124 * detection of multiple backends and possible nesting.
126 */ 125 */
127struct frontswap_ops frontswap_register_ops(struct frontswap_ops *ops) 126struct frontswap_ops *frontswap_register_ops(struct frontswap_ops *ops)
128{ 127{
129 struct frontswap_ops old = frontswap_ops; 128 struct frontswap_ops *old = frontswap_ops;
130 int i; 129 int i;
131 130
132 frontswap_ops = *ops;
133 frontswap_enabled = true; 131 frontswap_enabled = true;
134 132
135 for (i = 0; i < MAX_SWAPFILES; i++) { 133 for (i = 0; i < MAX_SWAPFILES; i++) {
136 if (test_and_clear_bit(i, need_init)) 134 if (test_and_clear_bit(i, need_init))
137 (*frontswap_ops.init)(i); 135 ops->init(i);
138 } 136 }
139 /* 137 /*
140 * We MUST have backend_registered set _after_ the frontswap_init's 138 * We MUST have frontswap_ops set _after_ the frontswap_init's
141 * have been called. Otherwise __frontswap_store might fail. Hence 139 * have been called. Otherwise __frontswap_store might fail. Hence
142 * the barrier to make sure compiler does not re-order us. 140 * the barrier to make sure compiler does not re-order us.
143 */ 141 */
144 barrier(); 142 barrier();
145 backend_registered = true; 143 frontswap_ops = ops;
146 return old; 144 return old;
147} 145}
148EXPORT_SYMBOL(frontswap_register_ops); 146EXPORT_SYMBOL(frontswap_register_ops);
@@ -172,11 +170,11 @@ void __frontswap_init(unsigned type)
172{ 170{
173 struct swap_info_struct *sis = swap_info[type]; 171 struct swap_info_struct *sis = swap_info[type];
174 172
175 if (backend_registered) { 173 if (frontswap_ops) {
176 BUG_ON(sis == NULL); 174 BUG_ON(sis == NULL);
177 if (sis->frontswap_map == NULL) 175 if (sis->frontswap_map == NULL)
178 return; 176 return;
179 (*frontswap_ops.init)(type); 177 frontswap_ops->init(type);
180 } else { 178 } else {
181 BUG_ON(type > MAX_SWAPFILES); 179 BUG_ON(type > MAX_SWAPFILES);
182 set_bit(type, need_init); 180 set_bit(type, need_init);
@@ -206,7 +204,7 @@ int __frontswap_store(struct page *page)
206 struct swap_info_struct *sis = swap_info[type]; 204 struct swap_info_struct *sis = swap_info[type];
207 pgoff_t offset = swp_offset(entry); 205 pgoff_t offset = swp_offset(entry);
208 206
209 if (!backend_registered) { 207 if (!frontswap_ops) {
210 inc_frontswap_failed_stores(); 208 inc_frontswap_failed_stores();
211 return ret; 209 return ret;
212 } 210 }
@@ -215,7 +213,7 @@ int __frontswap_store(struct page *page)
215 BUG_ON(sis == NULL); 213 BUG_ON(sis == NULL);
216 if (frontswap_test(sis, offset)) 214 if (frontswap_test(sis, offset))
217 dup = 1; 215 dup = 1;
218 ret = frontswap_ops.store(type, offset, page); 216 ret = frontswap_ops->store(type, offset, page);
219 if (ret == 0) { 217 if (ret == 0) {
220 frontswap_set(sis, offset); 218 frontswap_set(sis, offset);
221 inc_frontswap_succ_stores(); 219 inc_frontswap_succ_stores();
@@ -250,13 +248,13 @@ int __frontswap_load(struct page *page)
250 struct swap_info_struct *sis = swap_info[type]; 248 struct swap_info_struct *sis = swap_info[type];
251 pgoff_t offset = swp_offset(entry); 249 pgoff_t offset = swp_offset(entry);
252 250
253 if (!backend_registered) 251 if (!frontswap_ops)
254 return ret; 252 return ret;
255 253
256 BUG_ON(!PageLocked(page)); 254 BUG_ON(!PageLocked(page));
257 BUG_ON(sis == NULL); 255 BUG_ON(sis == NULL);
258 if (frontswap_test(sis, offset)) 256 if (frontswap_test(sis, offset))
259 ret = frontswap_ops.load(type, offset, page); 257 ret = frontswap_ops->load(type, offset, page);
260 if (ret == 0) { 258 if (ret == 0) {
261 inc_frontswap_loads(); 259 inc_frontswap_loads();
262 if (frontswap_tmem_exclusive_gets_enabled) { 260 if (frontswap_tmem_exclusive_gets_enabled) {
@@ -276,12 +274,12 @@ void __frontswap_invalidate_page(unsigned type, pgoff_t offset)
276{ 274{
277 struct swap_info_struct *sis = swap_info[type]; 275 struct swap_info_struct *sis = swap_info[type];
278 276
279 if (!backend_registered) 277 if (!frontswap_ops)
280 return; 278 return;
281 279
282 BUG_ON(sis == NULL); 280 BUG_ON(sis == NULL);
283 if (frontswap_test(sis, offset)) { 281 if (frontswap_test(sis, offset)) {
284 frontswap_ops.invalidate_page(type, offset); 282 frontswap_ops->invalidate_page(type, offset);
285 __frontswap_clear(sis, offset); 283 __frontswap_clear(sis, offset);
286 inc_frontswap_invalidates(); 284 inc_frontswap_invalidates();
287 } 285 }
@@ -296,11 +294,11 @@ void __frontswap_invalidate_area(unsigned type)
296{ 294{
297 struct swap_info_struct *sis = swap_info[type]; 295 struct swap_info_struct *sis = swap_info[type];
298 296
299 if (backend_registered) { 297 if (frontswap_ops) {
300 BUG_ON(sis == NULL); 298 BUG_ON(sis == NULL);
301 if (sis->frontswap_map == NULL) 299 if (sis->frontswap_map == NULL)
302 return; 300 return;
303 (*frontswap_ops.invalidate_area)(type); 301 frontswap_ops->invalidate_area(type);
304 atomic_set(&sis->frontswap_pages, 0); 302 atomic_set(&sis->frontswap_pages, 0);
305 memset(sis->frontswap_map, 0, sis->max / sizeof(long)); 303 memset(sis->frontswap_map, 0, sis->max / sizeof(long));
306 } 304 }