diff options
author | Sasha Levin <levinsasha928@gmail.com> | 2012-06-10 06:51:03 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-06-11 15:31:33 -0400 |
commit | 69217b4cd044671b6dddcd9d33c8e4fdfd295ae3 (patch) | |
tree | d13dab9972d7541cca1b2fd81efcb332e3d4900d /mm/frontswap.c | |
parent | f116695a500cdd84cbeac68bc373e98ae729c24b (diff) |
mm: frontswap: split frontswap_shrink further to simplify locking
Split frontswap_shrink to simplify the locking in the original code.
Also, assert that the function that was split still runs under the
swap spinlock.
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'mm/frontswap.c')
-rw-r--r-- | mm/frontswap.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/mm/frontswap.c b/mm/frontswap.c index faa43b7eea6f..e6353d9151ee 100644 --- a/mm/frontswap.c +++ b/mm/frontswap.c | |||
@@ -265,6 +265,24 @@ static int __frontswap_unuse_pages(unsigned long total, unsigned long *unused, | |||
265 | return ret; | 265 | return ret; |
266 | } | 266 | } |
267 | 267 | ||
268 | static int __frontswap_shrink(unsigned long target_pages, | ||
269 | unsigned long *pages_to_unuse, | ||
270 | int *type) | ||
271 | { | ||
272 | unsigned long total_pages = 0, total_pages_to_unuse; | ||
273 | |||
274 | assert_spin_locked(&swap_lock); | ||
275 | |||
276 | total_pages = __frontswap_curr_pages(); | ||
277 | if (total_pages <= target_pages) { | ||
278 | /* Nothing to do */ | ||
279 | *pages_to_unuse = 0; | ||
280 | return 0; | ||
281 | } | ||
282 | total_pages_to_unuse = total_pages - target_pages; | ||
283 | return __frontswap_unuse_pages(total_pages_to_unuse, pages_to_unuse, type); | ||
284 | } | ||
285 | |||
268 | /* | 286 | /* |
269 | * Frontswap, like a true swap device, may unnecessarily retain pages | 287 | * Frontswap, like a true swap device, may unnecessarily retain pages |
270 | * under certain circumstances; "shrink" frontswap is essentially a | 288 | * under certain circumstances; "shrink" frontswap is essentially a |
@@ -275,10 +293,8 @@ static int __frontswap_unuse_pages(unsigned long total, unsigned long *unused, | |||
275 | */ | 293 | */ |
276 | void frontswap_shrink(unsigned long target_pages) | 294 | void frontswap_shrink(unsigned long target_pages) |
277 | { | 295 | { |
278 | unsigned long total_pages = 0, total_pages_to_unuse; | ||
279 | unsigned long pages_to_unuse = 0; | 296 | unsigned long pages_to_unuse = 0; |
280 | int type, ret; | 297 | int type, ret; |
281 | bool locked = false; | ||
282 | 298 | ||
283 | /* | 299 | /* |
284 | * we don't want to hold swap_lock while doing a very | 300 | * we don't want to hold swap_lock while doing a very |
@@ -286,20 +302,10 @@ void frontswap_shrink(unsigned long target_pages) | |||
286 | * so restart scan from swap_list.head each time | 302 | * so restart scan from swap_list.head each time |
287 | */ | 303 | */ |
288 | spin_lock(&swap_lock); | 304 | spin_lock(&swap_lock); |
289 | locked = true; | 305 | ret = __frontswap_shrink(target_pages, &pages_to_unuse, &type); |
290 | total_pages = __frontswap_curr_pages(); | ||
291 | if (total_pages <= target_pages) | ||
292 | goto out; | ||
293 | total_pages_to_unuse = total_pages - target_pages; | ||
294 | ret = __frontswap_unuse_pages(total_pages_to_unuse, &pages_to_unuse, &type); | ||
295 | if (ret < 0) | ||
296 | goto out; | ||
297 | locked = false; | ||
298 | spin_unlock(&swap_lock); | 306 | spin_unlock(&swap_lock); |
299 | try_to_unuse(type, true, pages_to_unuse); | 307 | if (ret == 0 && pages_to_unuse) |
300 | out: | 308 | try_to_unuse(type, true, pages_to_unuse); |
301 | if (locked) | ||
302 | spin_unlock(&swap_lock); | ||
303 | return; | 309 | return; |
304 | } | 310 | } |
305 | EXPORT_SYMBOL(frontswap_shrink); | 311 | EXPORT_SYMBOL(frontswap_shrink); |