]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
thp: put_page: recheck PageHead after releasing the compound_lock
authorAndrea Arcangeli <aarcange@redhat.com>
Thu, 13 Jan 2011 23:46:33 +0000 (15:46 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Jan 2011 01:32:39 +0000 (17:32 -0800)
After releasing the compound_lock split_huge_page can still run and release the
page before put_page_testzero runs.

Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/swap.c

index 33f5292fe1325c388ee9db9de64b1b758f00036a..e0eeef940886084fb11297ed4580716a59425c27 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -131,8 +131,12 @@ static void put_compound_page(struct page *page)
                        atomic_dec(&page->_count);
                        VM_BUG_ON(atomic_read(&page_head->_count) <= 0);
                        compound_unlock_irqrestore(page_head, flags);
-                       if (put_page_testzero(page_head))
-                               __put_compound_page(page_head);
+                       if (put_page_testzero(page_head)) {
+                               if (PageHead(page_head))
+                                       __put_compound_page(page_head);
+                               else
+                                       __put_single_page(page_head);
+                       }
                } else {
                        /* page_head is a dangling pointer */
                        VM_BUG_ON(PageTail(page));