1
2
3
4
5#ifndef PAGE_FLAGS_H
6#define PAGE_FLAGS_H
7
8#include <linux/types.h>
9#include <linux/bug.h>
10#ifndef __GENERATING_BOUNDS_H
11#include <linux/mm_types.h>
12#include <generated/bounds.h>
13#endif
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73enum pageflags {
74 PG_locked,
75 PG_error,
76 PG_referenced,
77 PG_uptodate,
78 PG_dirty,
79 PG_lru,
80 PG_active,
81 PG_slab,
82 PG_owner_priv_1,
83 PG_arch_1,
84 PG_reserved,
85 PG_private,
86 PG_private_2,
87 PG_writeback,
88#ifdef CONFIG_PAGEFLAGS_EXTENDED
89 PG_head,
90 PG_tail,
91#else
92 PG_compound,
93#endif
94 PG_swapcache,
95 PG_mappedtodisk,
96 PG_reclaim,
97 PG_swapbacked,
98 PG_unevictable,
99#ifdef CONFIG_MMU
100 PG_mlocked,
101#endif
102#ifdef CONFIG_ARCH_USES_PG_UNCACHED
103 PG_uncached,
104#endif
105#ifdef CONFIG_MEMORY_FAILURE
106 PG_hwpoison,
107#endif
108#ifdef CONFIG_TRANSPARENT_HUGEPAGE
109 PG_compound_lock,
110#endif
111 __NR_PAGEFLAGS,
112
113
114 PG_checked = PG_owner_priv_1,
115
116
117
118
119
120 PG_fscache = PG_private_2,
121
122
123 PG_pinned = PG_owner_priv_1,
124 PG_savepinned = PG_dirty,
125
126
127 PG_slob_free = PG_private,
128};
129
130#ifndef __GENERATING_BOUNDS_H
131
132
133
134
135#define TESTPAGEFLAG(uname, lname) \
136static inline int Page##uname(const struct page *page) \
137 { return test_bit(PG_##lname, &page->flags); }
138
139#define SETPAGEFLAG(uname, lname) \
140static inline void SetPage##uname(struct page *page) \
141 { set_bit(PG_##lname, &page->flags); }
142
143#define CLEARPAGEFLAG(uname, lname) \
144static inline void ClearPage##uname(struct page *page) \
145 { clear_bit(PG_##lname, &page->flags); }
146
147#define __SETPAGEFLAG(uname, lname) \
148static inline void __SetPage##uname(struct page *page) \
149 { __set_bit(PG_##lname, &page->flags); }
150
151#define __CLEARPAGEFLAG(uname, lname) \
152static inline void __ClearPage##uname(struct page *page) \
153 { __clear_bit(PG_##lname, &page->flags); }
154
155#define TESTSETFLAG(uname, lname) \
156static inline int TestSetPage##uname(struct page *page) \
157 { return test_and_set_bit(PG_##lname, &page->flags); }
158
159#define TESTCLEARFLAG(uname, lname) \
160static inline int TestClearPage##uname(struct page *page) \
161 { return test_and_clear_bit(PG_##lname, &page->flags); }
162
163#define __TESTCLEARFLAG(uname, lname) \
164static inline int __TestClearPage##uname(struct page *page) \
165 { return __test_and_clear_bit(PG_##lname, &page->flags); }
166
167#define PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \
168 SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname)
169
170#define __PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \
171 __SETPAGEFLAG(uname, lname) __CLEARPAGEFLAG(uname, lname)
172
173#define PAGEFLAG_FALSE(uname) \
174static inline int Page##uname(const struct page *page) \
175 { return 0; }
176
177#define TESTSCFLAG(uname, lname) \
178 TESTSETFLAG(uname, lname) TESTCLEARFLAG(uname, lname)
179
180#define SETPAGEFLAG_NOOP(uname) \
181static inline void SetPage##uname(struct page *page) { }
182
183#define CLEARPAGEFLAG_NOOP(uname) \
184static inline void ClearPage##uname(struct page *page) { }
185
186#define __CLEARPAGEFLAG_NOOP(uname) \
187static inline void __ClearPage##uname(struct page *page) { }
188
189#define TESTCLEARFLAG_FALSE(uname) \
190static inline int TestClearPage##uname(struct page *page) { return 0; }
191
192#define __TESTCLEARFLAG_FALSE(uname) \
193static inline int __TestClearPage##uname(struct page *page) { return 0; }
194
195struct page;
196
197TESTPAGEFLAG(Locked, locked)
198PAGEFLAG(Error, error) TESTCLEARFLAG(Error, error)
199PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced)
200PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty)
201PAGEFLAG(LRU, lru) __CLEARPAGEFLAG(LRU, lru)
202PAGEFLAG(Active, active) __CLEARPAGEFLAG(Active, active)
203 TESTCLEARFLAG(Active, active)
204__PAGEFLAG(Slab, slab)
205PAGEFLAG(Checked, checked)
206PAGEFLAG(Pinned, pinned) TESTSCFLAG(Pinned, pinned)
207PAGEFLAG(SavePinned, savepinned);
208PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)
209PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
210
211__PAGEFLAG(SlobFree, slob_free)
212
213
214
215
216
217
218PAGEFLAG(Private, private) __SETPAGEFLAG(Private, private)
219 __CLEARPAGEFLAG(Private, private)
220PAGEFLAG(Private2, private_2) TESTSCFLAG(Private2, private_2)
221PAGEFLAG(OwnerPriv1, owner_priv_1) TESTCLEARFLAG(OwnerPriv1, owner_priv_1)
222
223
224
225
226
227TESTPAGEFLAG(Writeback, writeback) TESTSCFLAG(Writeback, writeback)
228PAGEFLAG(MappedToDisk, mappedtodisk)
229
230
231PAGEFLAG(Reclaim, reclaim) TESTCLEARFLAG(Reclaim, reclaim)
232PAGEFLAG(Readahead, reclaim)
233
234#ifdef CONFIG_HIGHMEM
235
236
237
238
239#define PageHighMem(__p) is_highmem(page_zone(__p))
240#else
241PAGEFLAG_FALSE(HighMem)
242#endif
243
244#ifdef CONFIG_SWAP
245PAGEFLAG(SwapCache, swapcache)
246#else
247PAGEFLAG_FALSE(SwapCache)
248 SETPAGEFLAG_NOOP(SwapCache) CLEARPAGEFLAG_NOOP(SwapCache)
249#endif
250
251PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable)
252 TESTCLEARFLAG(Unevictable, unevictable)
253
254#ifdef CONFIG_MMU
255PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked)
256 TESTSCFLAG(Mlocked, mlocked) __TESTCLEARFLAG(Mlocked, mlocked)
257#else
258PAGEFLAG_FALSE(Mlocked) SETPAGEFLAG_NOOP(Mlocked)
259 TESTCLEARFLAG_FALSE(Mlocked) __TESTCLEARFLAG_FALSE(Mlocked)
260#endif
261
262#ifdef CONFIG_ARCH_USES_PG_UNCACHED
263PAGEFLAG(Uncached, uncached)
264#else
265PAGEFLAG_FALSE(Uncached)
266#endif
267
268#ifdef CONFIG_MEMORY_FAILURE
269PAGEFLAG(HWPoison, hwpoison)
270TESTSCFLAG(HWPoison, hwpoison)
271#define __PG_HWPOISON (1UL << PG_hwpoison)
272#else
273PAGEFLAG_FALSE(HWPoison)
274#define __PG_HWPOISON 0
275#endif
276
277u64 stable_page_flags(struct page *page);
278
279static inline int PageUptodate(struct page *page)
280{
281 int ret = test_bit(PG_uptodate, &(page)->flags);
282
283
284
285
286
287
288
289
290
291 if (ret)
292 smp_rmb();
293
294 return ret;
295}
296
297static inline void __SetPageUptodate(struct page *page)
298{
299 smp_wmb();
300 __set_bit(PG_uptodate, &(page)->flags);
301}
302
303static inline void SetPageUptodate(struct page *page)
304{
305#ifdef CONFIG_S390
306 if (!test_and_set_bit(PG_uptodate, &page->flags))
307 page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, 0);
308#else
309
310
311
312
313
314
315
316
317 smp_wmb();
318 set_bit(PG_uptodate, &(page)->flags);
319#endif
320}
321
322CLEARPAGEFLAG(Uptodate, uptodate)
323
324extern void cancel_dirty_page(struct page *page, unsigned int account_size);
325
326int test_clear_page_writeback(struct page *page);
327int test_set_page_writeback(struct page *page);
328
329static inline void set_page_writeback(struct page *page)
330{
331 test_set_page_writeback(page);
332}
333
334#ifdef CONFIG_PAGEFLAGS_EXTENDED
335
336
337
338
339
340
341__PAGEFLAG(Head, head) CLEARPAGEFLAG(Head, head)
342__PAGEFLAG(Tail, tail)
343
344static inline int PageCompound(struct page *page)
345{
346 return page->flags & ((1L << PG_head) | (1L << PG_tail));
347
348}
349#ifdef CONFIG_TRANSPARENT_HUGEPAGE
350static inline void ClearPageCompound(struct page *page)
351{
352 BUG_ON(!PageHead(page));
353 ClearPageHead(page);
354}
355#endif
356#else
357
358
359
360
361
362
363TESTPAGEFLAG(Compound, compound)
364__PAGEFLAG(Head, compound)
365
366
367
368
369
370
371
372
373
374
375
376#define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim))
377
378static inline int PageTail(struct page *page)
379{
380 return ((page->flags & PG_head_tail_mask) == PG_head_tail_mask);
381}
382
383static inline void __SetPageTail(struct page *page)
384{
385 page->flags |= PG_head_tail_mask;
386}
387
388static inline void __ClearPageTail(struct page *page)
389{
390 page->flags &= ~PG_head_tail_mask;
391}
392
393#ifdef CONFIG_TRANSPARENT_HUGEPAGE
394static inline void ClearPageCompound(struct page *page)
395{
396 BUG_ON((page->flags & PG_head_tail_mask) != (1 << PG_compound));
397 clear_bit(PG_compound, &page->flags);
398}
399#endif
400
401#endif
402
403#ifdef CONFIG_TRANSPARENT_HUGEPAGE
404
405
406
407
408
409
410
411
412static inline int PageTransHuge(struct page *page)
413{
414 VM_BUG_ON(PageTail(page));
415 return PageHead(page);
416}
417
418
419
420
421
422
423static inline int PageTransCompound(struct page *page)
424{
425 return PageCompound(page);
426}
427
428
429
430
431
432
433static inline int PageTransTail(struct page *page)
434{
435 return PageTail(page);
436}
437
438#else
439
440static inline int PageTransHuge(struct page *page)
441{
442 return 0;
443}
444
445static inline int PageTransCompound(struct page *page)
446{
447 return 0;
448}
449
450static inline int PageTransTail(struct page *page)
451{
452 return 0;
453}
454#endif
455
456#ifdef CONFIG_MMU
457#define __PG_MLOCKED (1 << PG_mlocked)
458#else
459#define __PG_MLOCKED 0
460#endif
461
462#ifdef CONFIG_TRANSPARENT_HUGEPAGE
463#define __PG_COMPOUND_LOCK (1 << PG_compound_lock)
464#else
465#define __PG_COMPOUND_LOCK 0
466#endif
467
468
469
470
471
472#define PAGE_FLAGS_CHECK_AT_FREE \
473 (1 << PG_lru | 1 << PG_locked | \
474 1 << PG_private | 1 << PG_private_2 | \
475 1 << PG_writeback | 1 << PG_reserved | \
476 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active | \
477 1 << PG_unevictable | __PG_MLOCKED | __PG_HWPOISON | \
478 __PG_COMPOUND_LOCK)
479
480
481
482
483
484
485#define PAGE_FLAGS_CHECK_AT_PREP ((1 << NR_PAGEFLAGS) - 1)
486
487#define PAGE_FLAGS_PRIVATE \
488 (1 << PG_private | 1 << PG_private_2)
489
490
491
492
493
494
495
496static inline int page_has_private(struct page *page)
497{
498 return !!(page->flags & PAGE_FLAGS_PRIVATE);
499}
500
501#endif
502
503#endif
504