diff options
author | Konstantin Khlebnikov <khlebnikov@openvz.org> | 2011-05-24 20:12:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-25 11:39:23 -0400 |
commit | bd486285f24ac2fd1ff64688fb0729712c5712c4 (patch) | |
tree | d0fde80eb5c05893ba3b624b8219436b3efb274a /mm | |
parent | 700c2a46e88265326764197d5b8842490bae5569 (diff) |
mem-hwpoison: fix page refcount around isolate_lru_page()
Drop first page reference only after calling isolate_lru_page() to keep
page stable reference while isolating.
Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Lee Schermerhorn <lee.schermerhorn@hp.com>
Cc: Rik van Riel <riel@redhat.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/memory-failure.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 12178ec32ab5..369b80e81416 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -1440,16 +1440,12 @@ int soft_offline_page(struct page *page, int flags) | |||
1440 | */ | 1440 | */ |
1441 | ret = invalidate_inode_page(page); | 1441 | ret = invalidate_inode_page(page); |
1442 | unlock_page(page); | 1442 | unlock_page(page); |
1443 | |||
1444 | /* | 1443 | /* |
1445 | * Drop count because page migration doesn't like raised | ||
1446 | * counts. The page could get re-allocated, but if it becomes | ||
1447 | * LRU the isolation will just fail. | ||
1448 | * RED-PEN would be better to keep it isolated here, but we | 1444 | * RED-PEN would be better to keep it isolated here, but we |
1449 | * would need to fix isolation locking first. | 1445 | * would need to fix isolation locking first. |
1450 | */ | 1446 | */ |
1451 | put_page(page); | ||
1452 | if (ret == 1) { | 1447 | if (ret == 1) { |
1448 | put_page(page); | ||
1453 | ret = 0; | 1449 | ret = 0; |
1454 | pr_info("soft_offline: %#lx: invalidated\n", pfn); | 1450 | pr_info("soft_offline: %#lx: invalidated\n", pfn); |
1455 | goto done; | 1451 | goto done; |
@@ -1461,6 +1457,11 @@ int soft_offline_page(struct page *page, int flags) | |||
1461 | * handles a large number of cases for us. | 1457 | * handles a large number of cases for us. |
1462 | */ | 1458 | */ |
1463 | ret = isolate_lru_page(page); | 1459 | ret = isolate_lru_page(page); |
1460 | /* | ||
1461 | * Drop page reference which is came from get_any_page() | ||
1462 | * successful isolate_lru_page() already took another one. | ||
1463 | */ | ||
1464 | put_page(page); | ||
1464 | if (!ret) { | 1465 | if (!ret) { |
1465 | LIST_HEAD(pagelist); | 1466 | LIST_HEAD(pagelist); |
1466 | 1467 | ||