aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/internal.h3
-rw-r--r--mm/swap.c33
2 files changed, 29 insertions, 7 deletions
diff --git a/mm/internal.h b/mm/internal.h
index 684f7aa9692a..a85a3ab1f7ef 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -51,7 +51,8 @@ static inline void __get_page_tail_foll(struct page *page,
51 VM_BUG_ON(page_mapcount(page) < 0); 51 VM_BUG_ON(page_mapcount(page) < 0);
52 if (get_page_head) 52 if (get_page_head)
53 atomic_inc(&page->first_page->_count); 53 atomic_inc(&page->first_page->_count);
54 atomic_inc(&page->_mapcount); 54 if (compound_tail_refcounted(page->first_page))
55 atomic_inc(&page->_mapcount);
55} 56}
56 57
57/* 58/*
diff --git a/mm/swap.c b/mm/swap.c
index e2757fbb04ea..bba4aa5bf686 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -88,8 +88,9 @@ static void put_compound_page(struct page *page)
88 88
89 /* 89 /*
90 * THP can not break up slab pages so avoid taking 90 * THP can not break up slab pages so avoid taking
91 * compound_lock(). Slab performs non-atomic bit ops 91 * compound_lock() and skip the tail page refcounting
92 * on page->flags for better performance. In 92 * (in _mapcount) too. Slab performs non-atomic bit
93 * ops on page->flags for better performance. In
93 * particular slab_unlock() in slub used to be a hot 94 * particular slab_unlock() in slub used to be a hot
94 * path. It is still hot on arches that do not support 95 * path. It is still hot on arches that do not support
95 * this_cpu_cmpxchg_double(). 96 * this_cpu_cmpxchg_double().
@@ -102,7 +103,7 @@ static void put_compound_page(struct page *page)
102 * PageTail clear after smp_rmb() and we'll treat it 103 * PageTail clear after smp_rmb() and we'll treat it
103 * as a single page. 104 * as a single page.
104 */ 105 */
105 if (PageSlab(page_head) || PageHeadHuge(page_head)) { 106 if (!__compound_tail_refcounted(page_head)) {
106 /* 107 /*
107 * If "page" is a THP tail, we must read the tail page 108 * If "page" is a THP tail, we must read the tail page
108 * flags after the head page flags. The 109 * flags after the head page flags. The
@@ -117,10 +118,30 @@ static void put_compound_page(struct page *page)
117 * cannot race here. 118 * cannot race here.
118 */ 119 */
119 VM_BUG_ON(!PageHead(page_head)); 120 VM_BUG_ON(!PageHead(page_head));
120 VM_BUG_ON(page_mapcount(page) <= 0); 121 VM_BUG_ON(page_mapcount(page) != 0);
121 atomic_dec(&page->_mapcount); 122 if (put_page_testzero(page_head)) {
122 if (put_page_testzero(page_head)) 123 /*
124 * If this is the tail of a
125 * slab compound page, the
126 * tail pin must not be the
127 * last reference held on the
128 * page, because the PG_slab
129 * cannot be cleared before
130 * all tail pins (which skips
131 * the _mapcount tail
132 * refcounting) have been
133 * released. For hugetlbfs the
134 * tail pin may be the last
135 * reference on the page
136 * instead, because
137 * PageHeadHuge will not go
138 * away until the compound
139 * page enters the buddy
140 * allocator.
141 */
142 VM_BUG_ON(PageSlab(page_head));
123 __put_compound_page(page_head); 143 __put_compound_page(page_head);
144 }
124 return; 145 return;
125 } else 146 } else
126 /* 147 /*