diff options
Diffstat (limited to 'include/linux/mm.h')
-rw-r--r-- | include/linux/mm.h | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index c95d96ebd5ad..8c149fa4491d 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -267,17 +267,28 @@ static inline int get_page_unless_zero(struct page *page) | |||
267 | return atomic_inc_not_zero(&page->_count); | 267 | return atomic_inc_not_zero(&page->_count); |
268 | } | 268 | } |
269 | 269 | ||
270 | static inline struct page *compound_head(struct page *page) | ||
271 | { | ||
272 | /* | ||
273 | * We could avoid the PageCompound(page) check if | ||
274 | * we would not overload PageTail(). | ||
275 | * | ||
276 | * This check has to be done in several performance critical | ||
277 | * paths of the slab etc. IMHO PageTail deserves its own flag. | ||
278 | */ | ||
279 | if (unlikely(PageCompound(page) && PageTail(page))) | ||
280 | return page->first_page; | ||
281 | return page; | ||
282 | } | ||
283 | |||
270 | static inline int page_count(struct page *page) | 284 | static inline int page_count(struct page *page) |
271 | { | 285 | { |
272 | if (unlikely(PageCompound(page))) | 286 | return atomic_read(&compound_head(page)->_count); |
273 | page = (struct page *)page_private(page); | ||
274 | return atomic_read(&page->_count); | ||
275 | } | 287 | } |
276 | 288 | ||
277 | static inline void get_page(struct page *page) | 289 | static inline void get_page(struct page *page) |
278 | { | 290 | { |
279 | if (unlikely(PageCompound(page))) | 291 | page = compound_head(page); |
280 | page = (struct page *)page_private(page); | ||
281 | VM_BUG_ON(atomic_read(&page->_count) == 0); | 292 | VM_BUG_ON(atomic_read(&page->_count) == 0); |
282 | atomic_inc(&page->_count); | 293 | atomic_inc(&page->_count); |
283 | } | 294 | } |
@@ -314,6 +325,18 @@ static inline compound_page_dtor *get_compound_page_dtor(struct page *page) | |||
314 | return (compound_page_dtor *)page[1].lru.next; | 325 | return (compound_page_dtor *)page[1].lru.next; |
315 | } | 326 | } |
316 | 327 | ||
328 | static inline int compound_order(struct page *page) | ||
329 | { | ||
330 | if (!PageCompound(page) || PageTail(page)) | ||
331 | return 0; | ||
332 | return (unsigned long)page[1].lru.prev; | ||
333 | } | ||
334 | |||
335 | static inline void set_compound_order(struct page *page, unsigned long order) | ||
336 | { | ||
337 | page[1].lru.prev = (void *)order; | ||
338 | } | ||
339 | |||
317 | /* | 340 | /* |
318 | * Multiple processes may "see" the same page. E.g. for untouched | 341 | * Multiple processes may "see" the same page. E.g. for untouched |
319 | * mappings of /dev/null, all processes see the same page full of | 342 | * mappings of /dev/null, all processes see the same page full of |