1#ifndef _LINUX_PAGE_REF_H
2#define _LINUX_PAGE_REF_H
3
4#include <linux/atomic.h>
5#include <linux/mm_types.h>
6#include <linux/page-flags.h>
7
8static inline struct page *compound_head_by_tail(struct page *tail)
9{
10 struct page *head = tail->first_page;
11
12
13
14
15
16
17 smp_rmb();
18 if (likely(PageTail(tail)))
19 return head;
20 return tail;
21}
22
23static inline struct page *compound_head(struct page *page)
24{
25 if (unlikely(PageTail(page)))
26 return compound_head_by_tail(page);
27 return page;
28}
29
30static inline int page_ref_count(struct page *page)
31{
32 return atomic_read(&page->_count);
33}
34
35static inline int page_count(struct page *page)
36{
37 return atomic_read(&compound_head(page)->_count);
38}
39
40static inline void set_page_count(struct page *page, int v)
41{
42 atomic_set(&page->_count, v);
43}
44
45
46
47
48
49static inline void init_page_count(struct page *page)
50{
51 set_page_count(page, 1);
52}
53
54static inline void page_ref_add(struct page *page, int nr)
55{
56 atomic_add(nr, &page->_count);
57}
58
59static inline void page_ref_sub(struct page *page, int nr)
60{
61 atomic_sub(nr, &page->_count);
62}
63
64static inline void page_ref_inc(struct page *page)
65{
66 atomic_inc(&page->_count);
67}
68
69static inline void page_ref_dec(struct page *page)
70{
71 atomic_dec(&page->_count);
72}
73
74static inline int page_ref_sub_and_test(struct page *page, int nr)
75{
76 return atomic_sub_and_test(nr, &page->_count);
77}
78
79static inline int page_ref_dec_and_test(struct page *page)
80{
81 return atomic_dec_and_test(&page->_count);
82}
83
84static inline int page_ref_dec_return(struct page *page)
85{
86 return atomic_dec_return(&page->_count);
87}
88
89static inline int page_ref_add_unless(struct page *page, int nr, int u)
90{
91 return atomic_add_unless(&page->_count, nr, u);
92}
93
94static inline int page_ref_freeze(struct page *page, int count)
95{
96 return likely(atomic_cmpxchg(&page->_count, count, 0) == count);
97}
98
99static inline void page_ref_unfreeze(struct page *page, int count)
100{
101 VM_BUG_ON_PAGE(page_count(page) != 0, page);
102 VM_BUG_ON(count == 0);
103
104 atomic_set(&page->_count, count);
105}
106
107#endif
108