blob: f92667ec833c0b23728d69a71eee5cf89df6984f [file] [log] [blame]
Nicholas Flintham1e3d3112013-04-10 10:48:38 +01001
2#ifndef PAGE_FLAGS_H
3#define PAGE_FLAGS_H
4
5#include <linux/types.h>
6#include <linux/bug.h>
7#ifndef __GENERATING_BOUNDS_H
8#include <linux/mm_types.h>
9#include <generated/bounds.h>
10#endif
11
12
13enum pageflags {
14 PG_locked,
15 PG_error,
16 PG_referenced,
17 PG_uptodate,
18 PG_dirty,
19 PG_lru,
20 PG_active,
21 PG_slab,
22 PG_owner_priv_1,
23 PG_arch_1,
24 PG_reserved,
25 PG_private,
26 PG_private_2,
27 PG_writeback,
28#ifdef CONFIG_PAGEFLAGS_EXTENDED
29 PG_head,
30 PG_tail,
31#else
32 PG_compound,
33#endif
34 PG_swapcache,
35 PG_mappedtodisk,
36 PG_reclaim,
37 PG_swapbacked,
38 PG_unevictable,
39#ifdef CONFIG_MMU
40 PG_mlocked,
41#endif
42#ifdef CONFIG_ARCH_USES_PG_UNCACHED
43 PG_uncached,
44#endif
45#ifdef CONFIG_MEMORY_FAILURE
46 PG_hwpoison,
47#endif
48#ifdef CONFIG_TRANSPARENT_HUGEPAGE
49 PG_compound_lock,
50#endif
51 __NR_PAGEFLAGS,
52
53
54 PG_checked = PG_owner_priv_1,
55
56 PG_fscache = PG_private_2,
57
58
59 PG_pinned = PG_owner_priv_1,
60 PG_savepinned = PG_dirty,
61
62
63 PG_slob_free = PG_private,
64};
65
66#ifndef __GENERATING_BOUNDS_H
67
68#define TESTPAGEFLAG(uname, lname) \
69static inline int Page##uname(const struct page *page) \
70 { return test_bit(PG_##lname, &page->flags); }
71
72#define SETPAGEFLAG(uname, lname) \
73static inline void SetPage##uname(struct page *page) \
74 { set_bit(PG_##lname, &page->flags); }
75
76#define CLEARPAGEFLAG(uname, lname) \
77static inline void ClearPage##uname(struct page *page) \
78 { clear_bit(PG_##lname, &page->flags); }
79
80#define __SETPAGEFLAG(uname, lname) \
81static inline void __SetPage##uname(struct page *page) \
82 { __set_bit(PG_##lname, &page->flags); }
83
84#define __CLEARPAGEFLAG(uname, lname) \
85static inline void __ClearPage##uname(struct page *page) \
86 { __clear_bit(PG_##lname, &page->flags); }
87
88#define TESTSETFLAG(uname, lname) \
89static inline int TestSetPage##uname(struct page *page) \
90 { return test_and_set_bit(PG_##lname, &page->flags); }
91
92#define TESTCLEARFLAG(uname, lname) \
93static inline int TestClearPage##uname(struct page *page) \
94 { return test_and_clear_bit(PG_##lname, &page->flags); }
95
96#define __TESTCLEARFLAG(uname, lname) \
97static inline int __TestClearPage##uname(struct page *page) \
98 { return __test_and_clear_bit(PG_##lname, &page->flags); }
99
100#define PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \
101 SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname)
102
103#define __PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \
104 __SETPAGEFLAG(uname, lname) __CLEARPAGEFLAG(uname, lname)
105
106#define PAGEFLAG_FALSE(uname) \
107static inline int Page##uname(const struct page *page) \
108 { return 0; }
109
110#define TESTSCFLAG(uname, lname) \
111 TESTSETFLAG(uname, lname) TESTCLEARFLAG(uname, lname)
112
113#define SETPAGEFLAG_NOOP(uname) \
114static inline void SetPage##uname(struct page *page) { }
115
116#define CLEARPAGEFLAG_NOOP(uname) \
117static inline void ClearPage##uname(struct page *page) { }
118
119#define __CLEARPAGEFLAG_NOOP(uname) \
120static inline void __ClearPage##uname(struct page *page) { }
121
122#define TESTCLEARFLAG_FALSE(uname) \
123static inline int TestClearPage##uname(struct page *page) { return 0; }
124
125#define __TESTCLEARFLAG_FALSE(uname) \
126static inline int __TestClearPage##uname(struct page *page) { return 0; }
127
128struct page;
129
130TESTPAGEFLAG(Locked, locked)
131PAGEFLAG(Error, error) TESTCLEARFLAG(Error, error)
132PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced)
133PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty)
134PAGEFLAG(LRU, lru) __CLEARPAGEFLAG(LRU, lru)
135PAGEFLAG(Active, active) __CLEARPAGEFLAG(Active, active)
136 TESTCLEARFLAG(Active, active)
137__PAGEFLAG(Slab, slab)
138PAGEFLAG(Checked, checked)
139PAGEFLAG(Pinned, pinned) TESTSCFLAG(Pinned, pinned)
140PAGEFLAG(SavePinned, savepinned);
141PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)
142PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
143
144__PAGEFLAG(SlobFree, slob_free)
145
146PAGEFLAG(Private, private) __SETPAGEFLAG(Private, private)
147 __CLEARPAGEFLAG(Private, private)
148PAGEFLAG(Private2, private_2) TESTSCFLAG(Private2, private_2)
149PAGEFLAG(OwnerPriv1, owner_priv_1) TESTCLEARFLAG(OwnerPriv1, owner_priv_1)
150
151TESTPAGEFLAG(Writeback, writeback) TESTSCFLAG(Writeback, writeback)
152PAGEFLAG(MappedToDisk, mappedtodisk)
153
154PAGEFLAG(Reclaim, reclaim) TESTCLEARFLAG(Reclaim, reclaim)
155PAGEFLAG(Readahead, reclaim)
156
157#ifdef CONFIG_HIGHMEM
158#define PageHighMem(__p) is_highmem(page_zone(__p))
159#else
160PAGEFLAG_FALSE(HighMem)
161#endif
162
163#ifdef CONFIG_SWAP
164PAGEFLAG(SwapCache, swapcache)
165#else
166PAGEFLAG_FALSE(SwapCache)
167 SETPAGEFLAG_NOOP(SwapCache) CLEARPAGEFLAG_NOOP(SwapCache)
168#endif
169
170PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable)
171 TESTCLEARFLAG(Unevictable, unevictable)
172
173#ifdef CONFIG_MMU
174PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked)
175 TESTSCFLAG(Mlocked, mlocked) __TESTCLEARFLAG(Mlocked, mlocked)
176#else
177PAGEFLAG_FALSE(Mlocked) SETPAGEFLAG_NOOP(Mlocked)
178 TESTCLEARFLAG_FALSE(Mlocked) __TESTCLEARFLAG_FALSE(Mlocked)
179#endif
180
181#ifdef CONFIG_ARCH_USES_PG_UNCACHED
182PAGEFLAG(Uncached, uncached)
183#else
184PAGEFLAG_FALSE(Uncached)
185#endif
186
187#ifdef CONFIG_MEMORY_FAILURE
188PAGEFLAG(HWPoison, hwpoison)
189TESTSCFLAG(HWPoison, hwpoison)
190#define __PG_HWPOISON (1UL << PG_hwpoison)
191#else
192PAGEFLAG_FALSE(HWPoison)
193#define __PG_HWPOISON 0
194#endif
195
196u64 stable_page_flags(struct page *page);
197
198static inline int PageUptodate(struct page *page)
199{
200 int ret = test_bit(PG_uptodate, &(page)->flags);
201
202 if (ret)
203 smp_rmb();
204
205 return ret;
206}
207
208static inline void __SetPageUptodate(struct page *page)
209{
210 smp_wmb();
211 __set_bit(PG_uptodate, &(page)->flags);
212}
213
214static inline void SetPageUptodate(struct page *page)
215{
216#ifdef CONFIG_S390
217 if (!test_and_set_bit(PG_uptodate, &page->flags))
218 page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, 0);
219#else
220 smp_wmb();
221 set_bit(PG_uptodate, &(page)->flags);
222#endif
223}
224
225CLEARPAGEFLAG(Uptodate, uptodate)
226
227extern void cancel_dirty_page(struct page *page, unsigned int account_size);
228
229int test_clear_page_writeback(struct page *page);
230int test_set_page_writeback(struct page *page);
231
232static inline void set_page_writeback(struct page *page)
233{
234 test_set_page_writeback(page);
235}
236
237#ifdef CONFIG_PAGEFLAGS_EXTENDED
238__PAGEFLAG(Head, head) CLEARPAGEFLAG(Head, head)
239__PAGEFLAG(Tail, tail)
240
241static inline int PageCompound(struct page *page)
242{
243 return page->flags & ((1L << PG_head) | (1L << PG_tail));
244
245}
246#ifdef CONFIG_TRANSPARENT_HUGEPAGE
247static inline void ClearPageCompound(struct page *page)
248{
249 BUG_ON(!PageHead(page));
250 ClearPageHead(page);
251}
252#endif
253#else
254TESTPAGEFLAG(Compound, compound)
255__PAGEFLAG(Head, compound)
256
257#define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim))
258
259static inline int PageTail(struct page *page)
260{
261 return ((page->flags & PG_head_tail_mask) == PG_head_tail_mask);
262}
263
264static inline void __SetPageTail(struct page *page)
265{
266 page->flags |= PG_head_tail_mask;
267}
268
269static inline void __ClearPageTail(struct page *page)
270{
271 page->flags &= ~PG_head_tail_mask;
272}
273
274#ifdef CONFIG_TRANSPARENT_HUGEPAGE
275static inline void ClearPageCompound(struct page *page)
276{
277 BUG_ON((page->flags & PG_head_tail_mask) != (1 << PG_compound));
278 clear_bit(PG_compound, &page->flags);
279}
280#endif
281
282#endif
283
284#ifdef CONFIG_TRANSPARENT_HUGEPAGE
285static inline int PageTransHuge(struct page *page)
286{
287 VM_BUG_ON(PageTail(page));
288 return PageHead(page);
289}
290
291static inline int PageTransCompound(struct page *page)
292{
293 return PageCompound(page);
294}
295
296static inline int PageTransTail(struct page *page)
297{
298 return PageTail(page);
299}
300
301#else
302
303static inline int PageTransHuge(struct page *page)
304{
305 return 0;
306}
307
308static inline int PageTransCompound(struct page *page)
309{
310 return 0;
311}
312
313static inline int PageTransTail(struct page *page)
314{
315 return 0;
316}
317#endif
318
319#ifdef CONFIG_MMU
320#define __PG_MLOCKED (1 << PG_mlocked)
321#else
322#define __PG_MLOCKED 0
323#endif
324
325#ifdef CONFIG_TRANSPARENT_HUGEPAGE
326#define __PG_COMPOUND_LOCK (1 << PG_compound_lock)
327#else
328#define __PG_COMPOUND_LOCK 0
329#endif
330
331#define PAGE_FLAGS_CHECK_AT_FREE \
332 (1 << PG_lru | 1 << PG_locked | \
333 1 << PG_private | 1 << PG_private_2 | \
334 1 << PG_writeback | 1 << PG_reserved | \
335 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active | \
336 1 << PG_unevictable | __PG_MLOCKED | __PG_HWPOISON | \
337 __PG_COMPOUND_LOCK)
338
339#define PAGE_FLAGS_CHECK_AT_PREP ((1 << NR_PAGEFLAGS) - 1)
340
341#define PAGE_FLAGS_PRIVATE \
342 (1 << PG_private | 1 << PG_private_2)
343static inline int page_has_private(struct page *page)
344{
345 return !!(page->flags & PAGE_FLAGS_PRIVATE);
346}
347
348#endif
349
350#endif