diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/migrate.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/mm/migrate.c b/mm/migrate.c index 42a3d24d1107..b114635962dc 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -600,6 +600,17 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private, | |||
600 | if (PageAnon(page)) { | 600 | if (PageAnon(page)) { |
601 | rcu_read_lock(); | 601 | rcu_read_lock(); |
602 | rcu_locked = 1; | 602 | rcu_locked = 1; |
603 | |||
604 | /* | ||
605 | * If the page has no mappings any more, just bail. An | ||
606 | * unmapped anon page is likely to be freed soon but worse, | ||
607 | * it's possible its anon_vma disappeared between when | ||
608 | * the page was isolated and when we reached here while | ||
609 | * the RCU lock was not held | ||
610 | */ | ||
611 | if (!page_mapped(page)) | ||
612 | goto rcu_unlock; | ||
613 | |||
603 | anon_vma = page_anon_vma(page); | 614 | anon_vma = page_anon_vma(page); |
604 | atomic_inc(&anon_vma->external_refcount); | 615 | atomic_inc(&anon_vma->external_refcount); |
605 | } | 616 | } |