Commit e8788c0c authored by Christoph Lameter's avatar Christoph Lameter Committed by Linus Torvalds

[PATCH] remove_from_swap: fix locking

remove_from_swap() currently attempts to use page_lock_anon_vma to obtain
an anon_vma lock.  That is not working since the page may have been
remapped via swap ptes in order to move the page.

However, do_migrate_pages() obtain the mmap_sem lock and therefore there is
a guarantee that the anonymous vma will not vanish from under us.  There is
therefore no need to use page_lock_anon_vma.
Signed-off-by: default avatarChristoph Lameter <clameter@sgi.com>
Acked-by: default avatarHugh Dickins <hugh@veritas.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 6af6aab3
...@@ -212,25 +212,33 @@ out: ...@@ -212,25 +212,33 @@ out:
* through real pte's pointing to valid pages and then releasing * through real pte's pointing to valid pages and then releasing
* the page from the swap cache. * the page from the swap cache.
* *
* Must hold page lock on page. * Must hold page lock on page and mmap_sem of one vma that contains
* the page.
*/ */
void remove_from_swap(struct page *page) void remove_from_swap(struct page *page)
{ {
struct anon_vma *anon_vma; struct anon_vma *anon_vma;
struct vm_area_struct *vma; struct vm_area_struct *vma;
unsigned long mapping;
if (!PageAnon(page) || !PageSwapCache(page)) if (!PageSwapCache(page))
return; return;
anon_vma = page_lock_anon_vma(page); mapping = (unsigned long)page->mapping;
if (!anon_vma)
if (!mapping || (mapping & PAGE_MAPPING_ANON) == 0)
return; return;
/*
* We hold the mmap_sem lock. So no need to call page_lock_anon_vma.
*/
anon_vma = (struct anon_vma *) (mapping - PAGE_MAPPING_ANON);
spin_lock(&anon_vma->lock);
list_for_each_entry(vma, &anon_vma->head, anon_vma_node) list_for_each_entry(vma, &anon_vma->head, anon_vma_node)
remove_vma_swap(vma, page); remove_vma_swap(vma, page);
spin_unlock(&anon_vma->lock); spin_unlock(&anon_vma->lock);
delete_from_swap_cache(page); delete_from_swap_cache(page);
} }
EXPORT_SYMBOL(remove_from_swap); EXPORT_SYMBOL(remove_from_swap);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment