mm/swap.c: split put_compound_page()
[firefly-linux-kernel-4.4.55.git] / mm / swap.c
index 54f3ae4aaf4122b42724171e4ca2f90601c56a69..d089c5a0cf9831bb6dca8489e15e56acc6a0a66a 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -225,6 +225,11 @@ static void put_compound_page(struct page *page)
 {
        struct page *page_head;
 
+       /*
+        * We see the PageCompound set and PageTail not set, so @page maybe:
+        *  1. hugetlbfs head page, or
+        *  2. THP head page.
+        */
        if (likely(!PageTail(page))) {
                if (put_page_testzero(page)) {
                        /*
@@ -239,135 +244,20 @@ static void put_compound_page(struct page *page)
                return;
        }
 
-       /* __split_huge_page_refcount can run under us */
-       page_head = compound_head(page);
-
        /*
-        * THP can not break up slab pages so avoid taking
-        * compound_lock() and skip the tail page refcounting (in
-        * _mapcount) too. Slab performs non-atomic bit ops on
-        * page->flags for better performance. In particular
-        * slab_unlock() in slub used to be a hot path. It is still
-        * hot on arches that do not support
-        * this_cpu_cmpxchg_double().
+        * We see the PageCompound set and PageTail set, so @page maybe:
+        *  1. a tail hugetlbfs page, or
+        *  2. a tail THP page, or
+        *  3. a split THP page.
         *
-        * If "page" is part of a slab or hugetlbfs page it cannot be
-        * splitted and the head page cannot change from under us. And
-        * if "page" is part of a THP page under splitting, if the
-        * head page pointed by the THP tail isn't a THP head anymore,
-        * we'll find PageTail clear after smp_rmb() and we'll treat
-        * it as a single page.
+        *  Case 3 is possible, as we may race with
+        *  __split_huge_page_refcount tearing down a THP page.
         */
-       if (!__compound_tail_refcounted(page_head)) {
-               /*
-                * If "page" is a THP tail, we must read the tail page
-                * flags after the head page flags. The
-                * split_huge_page side enforces write memory barriers
-                * between clearing PageTail and before the head page
-                * can be freed and reallocated.
-                */
-               smp_rmb();
-               if (likely(PageTail(page))) {
-                       /*
-                        * __split_huge_page_refcount cannot race
-                        * here.
-                        */
-                       VM_BUG_ON_PAGE(!PageHead(page_head), page_head);
-                       VM_BUG_ON_PAGE(page_mapcount(page) != 0, page);
-                       if (put_page_testzero(page_head)) {
-                               /*
-                                * If this is the tail of a slab
-                                * compound page, the tail pin must
-                                * not be the last reference held on
-                                * the page, because the PG_slab
-                                * cannot be cleared before all tail
-                                * pins (which skips the _mapcount
-                                * tail refcounting) have been
-                                * released. For hugetlbfs the tail
-                                * pin may be the last reference on
-                                * the page instead, because
-                                * PageHeadHuge will not go away until
-                                * the compound page enters the buddy
-                                * allocator.
-                                */
-                               VM_BUG_ON_PAGE(PageSlab(page_head), page_head);
-                               __put_compound_page(page_head);
-                       }
-                       return;
-               } else
-                       /*
-                        * __split_huge_page_refcount run before us,
-                        * "page" was a THP tail. The split page_head
-                        * has been freed and reallocated as slab or
-                        * hugetlbfs page of smaller order (only
-                        * possible if reallocated as slab on x86).
-                        */
-                       goto out_put_single;
-       }
-
-       if (likely(page != page_head && get_page_unless_zero(page_head))) {
-               unsigned long flags;
-
-               /*
-                * page_head wasn't a dangling pointer but it may not
-                * be a head page anymore by the time we obtain the
-                * lock. That is ok as long as it can't be freed from
-                * under us.
-                */
-               flags = compound_lock_irqsave(page_head);
-               if (unlikely(!PageTail(page))) {
-                       /* __split_huge_page_refcount run before us */
-                       compound_unlock_irqrestore(page_head, flags);
-                       if (put_page_testzero(page_head)) {
-                               /*
-                                * The head page may have been freed
-                                * and reallocated as a compound page
-                                * of smaller order and then freed
-                                * again.  All we know is that it
-                                * cannot have become: a THP page, a
-                                * compound page of higher order, a
-                                * tail page.  That is because we
-                                * still hold the refcount of the
-                                * split THP tail and page_head was
-                                * the THP head before the split.
-                                */
-                               if (PageHead(page_head))
-                                       __put_compound_page(page_head);
-                               else
-                                       __put_single_page(page_head);
-                       }
-out_put_single:
-                       if (put_page_testzero(page))
-                               __put_single_page(page);
-                       return;
-               }
-               VM_BUG_ON_PAGE(page_head != page->first_page, page);
-               /*
-                * We can release the refcount taken by
-                * get_page_unless_zero() now that
-                * __split_huge_page_refcount() is blocked on the
-                * compound_lock.
-                */
-               if (put_page_testzero(page_head))
-                       VM_BUG_ON_PAGE(1, page_head);
-               /* __split_huge_page_refcount will wait now */
-               VM_BUG_ON_PAGE(page_mapcount(page) <= 0, page);
-               atomic_dec(&page->_mapcount);
-               VM_BUG_ON_PAGE(atomic_read(&page_head->_count) <= 0, page_head);
-               VM_BUG_ON_PAGE(atomic_read(&page->_count) != 0, page);
-               compound_unlock_irqrestore(page_head, flags);
-
-               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_PAGE(PageTail(page), page);
-               goto out_put_single;
-       }
+       page_head = compound_head(page);
+       if (!__compound_tail_refcounted(page_head))
+               put_unrefcounted_compound_page(page_head, page);
+       else
+               put_refcounted_compound_page(page_head, page);
 }
 
 void put_page(struct page *page)