aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Morton <akpm@linux-foundation.org>2014-01-21 18:48:59 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-21 19:19:43 -0500
commit26296ad2dfb4059f840e46cd7af38d0025a9d8d7 (patch)
tree0e7291ca3f14efdb2badaaaded4b6360ddd4b5fa
parent758f66a29ccc6383353fd395aa04be15e8dea445 (diff)
mm/swap.c: reorganize put_compound_page()
Tweak it so save a tab stop, make code layout slightly less nutty. Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Cc: Khalid Aziz <khalid.aziz@oracle.com> Cc: Pravin Shelar <pshelar@nicira.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Ben Hutchings <bhutchings@solarflare.com> Cc: Christoph Lameter <cl@linux.com> Cc: Johannes Weiner <jweiner@redhat.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Rik van Riel <riel@redhat.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Minchan Kim <minchan@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/swap.c254
1 files changed, 125 insertions, 129 deletions
diff --git a/mm/swap.c b/mm/swap.c
index 7434e3619c14..d1100b619e61 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -81,154 +81,150 @@ static void __put_compound_page(struct page *page)
81 81
82static void put_compound_page(struct page *page) 82static void put_compound_page(struct page *page)
83{ 83{
84 if (unlikely(PageTail(page))) { 84 struct page *page_head;
85 /* __split_huge_page_refcount can run under us */
86 struct page *page_head = compound_trans_head(page);
87 85
88 /* 86 if (likely(!PageTail(page))) {
89 * THP can not break up slab pages so avoid taking 87 if (put_page_testzero(page)) {
90 * compound_lock() and skip the tail page refcounting
91 * (in _mapcount) too. Slab performs non-atomic bit
92 * ops on page->flags for better performance. In
93 * particular slab_unlock() in slub used to be a hot
94 * path. It is still hot on arches that do not support
95 * this_cpu_cmpxchg_double().
96 *
97 * If "page" is part of a slab or hugetlbfs page it
98 * cannot be splitted and the head page cannot change
99 * from under us. And if "page" is part of a THP page
100 * under splitting, if the head page pointed by the
101 * THP tail isn't a THP head anymore, we'll find
102 * PageTail clear after smp_rmb() and we'll treat it
103 * as a single page.
104 */
105 if (!__compound_tail_refcounted(page_head)) {
106 /* 88 /*
107 * If "page" is a THP tail, we must read the tail page 89 * By the time all refcounts have been released
108 * flags after the head page flags. The 90 * split_huge_page cannot run anymore from under us.
109 * split_huge_page side enforces write memory
110 * barriers between clearing PageTail and before the
111 * head page can be freed and reallocated.
112 */ 91 */
113 smp_rmb(); 92 if (PageHead(page))
114 if (likely(PageTail(page))) { 93 __put_compound_page(page);
115 /* 94 else
116 * __split_huge_page_refcount 95 __put_single_page(page);
117 * cannot race here.
118 */
119 VM_BUG_ON(!PageHead(page_head));
120 VM_BUG_ON(page_mapcount(page) != 0);
121 if (put_page_testzero(page_head)) {
122 /*
123 * If this is the tail of a
124 * slab compound page, the
125 * tail pin must not be the
126 * last reference held on the
127 * page, because the PG_slab
128 * cannot be cleared before
129 * all tail pins (which skips
130 * the _mapcount tail
131 * refcounting) have been
132 * released. For hugetlbfs the
133 * tail pin may be the last
134 * reference on the page
135 * instead, because
136 * PageHeadHuge will not go
137 * away until the compound
138 * page enters the buddy
139 * allocator.
140 */
141 VM_BUG_ON(PageSlab(page_head));
142 __put_compound_page(page_head);
143 }
144 return;
145 } else
146 /*
147 * __split_huge_page_refcount
148 * run before us, "page" was a
149 * THP tail. The split
150 * page_head has been freed
151 * and reallocated as slab or
152 * hugetlbfs page of smaller
153 * order (only possible if
154 * reallocated as slab on
155 * x86).
156 */
157 goto out_put_single;
158 } 96 }
97 return;
98 }
159 99
160 if (likely(page != page_head && 100 /* __split_huge_page_refcount can run under us */
161 get_page_unless_zero(page_head))) { 101 page_head = compound_trans_head(page);
162 unsigned long flags;
163 102
103 /*
104 * THP can not break up slab pages so avoid taking
105 * compound_lock() and skip the tail page refcounting (in
106 * _mapcount) too. Slab performs non-atomic bit ops on
107 * page->flags for better performance. In particular
108 * slab_unlock() in slub used to be a hot path. It is still
109 * hot on arches that do not support
110 * this_cpu_cmpxchg_double().
111 *
112 * If "page" is part of a slab or hugetlbfs page it cannot be
113 * splitted and the head page cannot change from under us. And
114 * if "page" is part of a THP page under splitting, if the
115 * head page pointed by the THP tail isn't a THP head anymore,
116 * we'll find PageTail clear after smp_rmb() and we'll treat
117 * it as a single page.
118 */
119 if (!__compound_tail_refcounted(page_head)) {
120 /*
121 * If "page" is a THP tail, we must read the tail page
122 * flags after the head page flags. The
123 * split_huge_page side enforces write memory barriers
124 * between clearing PageTail and before the head page
125 * can be freed and reallocated.
126 */
127 smp_rmb();
128 if (likely(PageTail(page))) {
164 /* 129 /*
165 * page_head wasn't a dangling pointer but it 130 * __split_huge_page_refcount cannot race
166 * may not be a head page anymore by the time 131 * here.
167 * we obtain the lock. That is ok as long as it
168 * can't be freed from under us.
169 */ 132 */
170 flags = compound_lock_irqsave(page_head); 133 VM_BUG_ON(!PageHead(page_head));
171 if (unlikely(!PageTail(page))) { 134 VM_BUG_ON(page_mapcount(page) != 0);
172 /* __split_huge_page_refcount run before us */ 135 if (put_page_testzero(page_head)) {
173 compound_unlock_irqrestore(page_head, flags); 136 /*
174 if (put_page_testzero(page_head)) { 137 * If this is the tail of a slab
175 /* 138 * compound page, the tail pin must
176 * The head page may have been 139 * not be the last reference held on
177 * freed and reallocated as a 140 * the page, because the PG_slab
178 * compound page of smaller 141 * cannot be cleared before all tail
179 * order and then freed again. 142 * pins (which skips the _mapcount
180 * All we know is that it 143 * tail refcounting) have been
181 * cannot have become: a THP 144 * released. For hugetlbfs the tail
182 * page, a compound page of 145 * pin may be the last reference on
183 * higher order, a tail page. 146 * the page instead, because
184 * That is because we still 147 * PageHeadHuge will not go away until
185 * hold the refcount of the 148 * the compound page enters the buddy
186 * split THP tail and 149 * allocator.
187 * page_head was the THP head 150 */
188 * before the split. 151 VM_BUG_ON(PageSlab(page_head));
189 */ 152 __put_compound_page(page_head);
190 if (PageHead(page_head))
191 __put_compound_page(page_head);
192 else
193 __put_single_page(page_head);
194 }
195out_put_single:
196 if (put_page_testzero(page))
197 __put_single_page(page);
198 return;
199 } 153 }
200 VM_BUG_ON(page_head != page->first_page); 154 return;
155 } else
201 /* 156 /*
202 * We can release the refcount taken by 157 * __split_huge_page_refcount run before us,
203 * get_page_unless_zero() now that 158 * "page" was a THP tail. The split page_head
204 * __split_huge_page_refcount() is blocked on 159 * has been freed and reallocated as slab or
205 * the compound_lock. 160 * hugetlbfs page of smaller order (only
161 * possible if reallocated as slab on x86).
206 */ 162 */
207 if (put_page_testzero(page_head)) 163 goto out_put_single;
208 VM_BUG_ON(1); 164 }
209 /* __split_huge_page_refcount will wait now */ 165
210 VM_BUG_ON(page_mapcount(page) <= 0); 166 if (likely(page != page_head && get_page_unless_zero(page_head))) {
211 atomic_dec(&page->_mapcount); 167 unsigned long flags;
212 VM_BUG_ON(atomic_read(&page_head->_count) <= 0);
213 VM_BUG_ON(atomic_read(&page->_count) != 0);
214 compound_unlock_irqrestore(page_head, flags);
215 168
169 /*
170 * page_head wasn't a dangling pointer but it may not
171 * be a head page anymore by the time we obtain the
172 * lock. That is ok as long as it can't be freed from
173 * under us.
174 */
175 flags = compound_lock_irqsave(page_head);
176 if (unlikely(!PageTail(page))) {
177 /* __split_huge_page_refcount run before us */
178 compound_unlock_irqrestore(page_head, flags);
216 if (put_page_testzero(page_head)) { 179 if (put_page_testzero(page_head)) {
180 /*
181 * The head page may have been freed
182 * and reallocated as a compound page
183 * of smaller order and then freed
184 * again. All we know is that it
185 * cannot have become: a THP page, a
186 * compound page of higher order, a
187 * tail page. That is because we
188 * still hold the refcount of the
189 * split THP tail and page_head was
190 * the THP head before the split.
191 */
217 if (PageHead(page_head)) 192 if (PageHead(page_head))
218 __put_compound_page(page_head); 193 __put_compound_page(page_head);
219 else 194 else
220 __put_single_page(page_head); 195 __put_single_page(page_head);
221 } 196 }
222 } else { 197out_put_single:
223 /* page_head is a dangling pointer */ 198 if (put_page_testzero(page))
224 VM_BUG_ON(PageTail(page)); 199 __put_single_page(page);
225 goto out_put_single; 200 return;
226 } 201 }
227 } else if (put_page_testzero(page)) { 202 VM_BUG_ON(page_head != page->first_page);
228 if (PageHead(page)) 203 /*
229 __put_compound_page(page); 204 * We can release the refcount taken by
230 else 205 * get_page_unless_zero() now that
231 __put_single_page(page); 206 * __split_huge_page_refcount() is blocked on the
207 * compound_lock.
208 */
209 if (put_page_testzero(page_head))
210 VM_BUG_ON(1);
211 /* __split_huge_page_refcount will wait now */
212 VM_BUG_ON(page_mapcount(page) <= 0);
213 atomic_dec(&page->_mapcount);
214 VM_BUG_ON(atomic_read(&page_head->_count) <= 0);
215 VM_BUG_ON(atomic_read(&page->_count) != 0);
216 compound_unlock_irqrestore(page_head, flags);
217
218 if (put_page_testzero(page_head)) {
219 if (PageHead(page_head))
220 __put_compound_page(page_head);
221 else
222 __put_single_page(page_head);
223 }
224 } else {
225 /* page_head is a dangling pointer */
226 VM_BUG_ON(PageTail(page));
227 goto out_put_single;
232 } 228 }
233} 229}
234 230