]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
mm/migration: fix page corruption during hugepage migration
authorMinchan Kim <minchan.kim@gmail.com>
Tue, 1 Feb 2011 23:52:33 +0000 (15:52 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 Feb 2011 00:03:18 +0000 (16:03 -0800)
If migrate_huge_page by memory-failure fails , it calls put_page in itself
to decrease page reference and caller of migrate_huge_page also calls
putback_lru_pages.  It can do double free of page so it can make page
corruption on page holder.

In addtion, clean of pages on caller is consistent behavior with
migrate_pages by cf608ac19c ("mm: compaction: fix COMPACTPAGEFAILED
counting").

Signed-off-by: Minchan Kim <minchan.kim@gmail.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/memory-failure.c
mm/migrate.c

index 75398b0bfedeb98ea2d463f0e071ec3c37e89c1d..237aaa488f4eab4682be86800740c94e44191852 100644 (file)
@@ -1295,7 +1295,10 @@ static int soft_offline_huge_page(struct page *page, int flags)
        ret = migrate_huge_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, 0,
                                true);
        if (ret) {
-               putback_lru_pages(&pagelist);
+               struct page *page1, *page2;
+               list_for_each_entry_safe(page1, page2, &pagelist, lru)
+                       put_page(page1);
+
                pr_debug("soft offline: %#lx: migration failed %d, type %lx\n",
                         pfn, ret, page->flags);
                if (ret > 0)
index 155a2e9a8059c13249d93437589342349432e875..7661152538074ee8018be8b87e1600021be5dc27 100644 (file)
@@ -980,10 +980,6 @@ int migrate_huge_pages(struct list_head *from,
        }
        rc = 0;
 out:
-
-       list_for_each_entry_safe(page, page2, from, lru)
-               put_page(page);
-
        if (rc)
                return rc;