diff options
-rw-r--r-- | mm/rmap.c | 28 |
1 files changed, 20 insertions, 8 deletions
@@ -1684,6 +1684,24 @@ void __put_anon_vma(struct anon_vma *anon_vma) | |||
1684 | } | 1684 | } |
1685 | 1685 | ||
1686 | #ifdef CONFIG_MIGRATION | 1686 | #ifdef CONFIG_MIGRATION |
1687 | static struct anon_vma *rmap_walk_anon_lock(struct page *page) | ||
1688 | { | ||
1689 | struct anon_vma *anon_vma; | ||
1690 | |||
1691 | /* | ||
1692 | * Note: remove_migration_ptes() cannot use page_lock_anon_vma_read() | ||
1693 | * because that depends on page_mapped(); but not all its usages | ||
1694 | * are holding mmap_sem. Users without mmap_sem are required to | ||
1695 | * take a reference count to prevent the anon_vma disappearing | ||
1696 | */ | ||
1697 | anon_vma = page_anon_vma(page); | ||
1698 | if (!anon_vma) | ||
1699 | return NULL; | ||
1700 | |||
1701 | anon_vma_lock_read(anon_vma); | ||
1702 | return anon_vma; | ||
1703 | } | ||
1704 | |||
1687 | /* | 1705 | /* |
1688 | * rmap_walk() and its helpers rmap_walk_anon() and rmap_walk_file(): | 1706 | * rmap_walk() and its helpers rmap_walk_anon() and rmap_walk_file(): |
1689 | * Called by migrate.c to remove migration ptes, but might be used more later. | 1707 | * Called by migrate.c to remove migration ptes, but might be used more later. |
@@ -1696,16 +1714,10 @@ static int rmap_walk_anon(struct page *page, int (*rmap_one)(struct page *, | |||
1696 | struct anon_vma_chain *avc; | 1714 | struct anon_vma_chain *avc; |
1697 | int ret = SWAP_AGAIN; | 1715 | int ret = SWAP_AGAIN; |
1698 | 1716 | ||
1699 | /* | 1717 | anon_vma = rmap_walk_anon_lock(page); |
1700 | * Note: remove_migration_ptes() cannot use page_lock_anon_vma_read() | ||
1701 | * because that depends on page_mapped(); but not all its usages | ||
1702 | * are holding mmap_sem. Users without mmap_sem are required to | ||
1703 | * take a reference count to prevent the anon_vma disappearing | ||
1704 | */ | ||
1705 | anon_vma = page_anon_vma(page); | ||
1706 | if (!anon_vma) | 1718 | if (!anon_vma) |
1707 | return ret; | 1719 | return ret; |
1708 | anon_vma_lock_read(anon_vma); | 1720 | |
1709 | anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) { | 1721 | anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) { |
1710 | struct vm_area_struct *vma = avc->vma; | 1722 | struct vm_area_struct *vma = avc->vma; |
1711 | unsigned long address = vma_address(page, vma); | 1723 | unsigned long address = vma_address(page, vma); |