aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/mm.h33
-rw-r--r--include/linux/page-flags.h14
2 files changed, 42 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
270static 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
270static inline int page_count(struct page *page) 284static 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
277static inline void get_page(struct page *page) 289static 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
328static 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
335static 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
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 96326594e55d..a1e143634946 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -94,6 +94,12 @@
94/* PG_owner_priv_1 users should have descriptive aliases */ 94/* PG_owner_priv_1 users should have descriptive aliases */
95#define PG_checked PG_owner_priv_1 /* Used by some filesystems */ 95#define PG_checked PG_owner_priv_1 /* Used by some filesystems */
96 96
97/*
98 * Marks tail portion of a compound page. We currently do not reclaim
99 * compound pages so we can reuse a flag only used for reclaim here.
100 */
101#define PG_tail PG_reclaim
102
97#if (BITS_PER_LONG > 32) 103#if (BITS_PER_LONG > 32)
98/* 104/*
99 * 64-bit-only flags build down from bit 31 105 * 64-bit-only flags build down from bit 31
@@ -241,6 +247,14 @@ static inline void SetPageUptodate(struct page *page)
241#define __SetPageCompound(page) __set_bit(PG_compound, &(page)->flags) 247#define __SetPageCompound(page) __set_bit(PG_compound, &(page)->flags)
242#define __ClearPageCompound(page) __clear_bit(PG_compound, &(page)->flags) 248#define __ClearPageCompound(page) __clear_bit(PG_compound, &(page)->flags)
243 249
250/*
251 * Note: PG_tail is an alias of another page flag. The result of PageTail()
252 * is only valid if PageCompound(page) is true.
253 */
254#define PageTail(page) test_bit(PG_tail, &(page)->flags)
255#define __SetPageTail(page) __set_bit(PG_tail, &(page)->flags)
256#define __ClearPageTail(page) __clear_bit(PG_tail, &(page)->flags)
257
244#ifdef CONFIG_SWAP 258#ifdef CONFIG_SWAP
245#define PageSwapCache(page) test_bit(PG_swapcache, &(page)->flags) 259#define PageSwapCache(page) test_bit(PG_swapcache, &(page)->flags)
246#define SetPageSwapCache(page) set_bit(PG_swapcache, &(page)->flags) 260#define SetPageSwapCache(page) set_bit(PG_swapcache, &(page)->flags)