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#include <linux/mmdebug.h>
11#ifndef __GENERATING_BOUNDS_H
12#include <linux/mm_types.h>
13#include <generated/bounds.h>
14#endif
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
73
74enum pageflags {
75 PG_locked,
76 PG_error,
77 PG_referenced,
78 PG_uptodate,
79 PG_dirty,
80 PG_lru,
81 PG_active,
82 PG_waiters,
83 PG_slab,
84 PG_owner_priv_1,
85 PG_arch_1,
86 PG_reserved,
87 PG_private,
88 PG_private_2,
89 PG_writeback,
90 PG_head,
91 PG_mappedtodisk,
92 PG_reclaim,
93 PG_swapbacked,
94 PG_unevictable,
95#ifdef CONFIG_MMU
96 PG_mlocked,
97#endif
98#ifdef CONFIG_ARCH_USES_PG_UNCACHED
99 PG_uncached,
100#endif
101#ifdef CONFIG_MEMORY_FAILURE
102 PG_hwpoison,
103#endif
104#if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT)
105 PG_young,
106 PG_idle,
107#endif
108 __NR_PAGEFLAGS,
109
110
111 PG_checked = PG_owner_priv_1,
112
113
114 PG_swapcache = PG_owner_priv_1,
115
116
117
118
119
120 PG_fscache = PG_private_2,
121
122
123
124 PG_pinned = PG_owner_priv_1,
125
126 PG_savepinned = PG_dirty,
127
128 PG_foreign = PG_owner_priv_1,
129
130
131 PG_slob_free = PG_private,
132
133
134 PG_double_map = PG_private_2,
135
136
137 PG_isolated = PG_reclaim,
138};
139
140#ifndef __GENERATING_BOUNDS_H
141
142struct page;
143
144static inline struct page *compound_head(struct page *page)
145{
146 unsigned long head = READ_ONCE(page->compound_head);
147
148 if (unlikely(head & 1))
149 return (struct page *) (head - 1);
150 return page;
151}
152
153static __always_inline int PageTail(struct page *page)
154{
155 return READ_ONCE(page->compound_head) & 1;
156}
157
158static __always_inline int PageCompound(struct page *page)
159{
160 return test_bit(PG_head, &page->flags) || PageTail(page);
161}
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183#define PF_ANY(page, enforce) page
184#define PF_HEAD(page, enforce) compound_head(page)
185#define PF_ONLY_HEAD(page, enforce) ({ \
186 VM_BUG_ON_PGFLAGS(PageTail(page), page); \
187 page;})
188#define PF_NO_TAIL(page, enforce) ({ \
189 VM_BUG_ON_PGFLAGS(enforce && PageTail(page), page); \
190 compound_head(page);})
191#define PF_NO_COMPOUND(page, enforce) ({ \
192 VM_BUG_ON_PGFLAGS(enforce && PageCompound(page), page); \
193 page;})
194
195
196
197
198#define TESTPAGEFLAG(uname, lname, policy) \
199static __always_inline int Page##uname(struct page *page) \
200 { return test_bit(PG_##lname, &policy(page, 0)->flags); }
201
202#define SETPAGEFLAG(uname, lname, policy) \
203static __always_inline void SetPage##uname(struct page *page) \
204 { set_bit(PG_##lname, &policy(page, 1)->flags); }
205
206#define CLEARPAGEFLAG(uname, lname, policy) \
207static __always_inline void ClearPage##uname(struct page *page) \
208 { clear_bit(PG_##lname, &policy(page, 1)->flags); }
209
210#define __SETPAGEFLAG(uname, lname, policy) \
211static __always_inline void __SetPage##uname(struct page *page) \
212 { __set_bit(PG_##lname, &policy(page, 1)->flags); }
213
214#define __CLEARPAGEFLAG(uname, lname, policy) \
215static __always_inline void __ClearPage##uname(struct page *page) \
216 { __clear_bit(PG_##lname, &policy(page, 1)->flags); }
217
218#define TESTSETFLAG(uname, lname, policy) \
219static __always_inline int TestSetPage##uname(struct page *page) \
220 { return test_and_set_bit(PG_##lname, &policy(page, 1)->flags); }
221
222#define TESTCLEARFLAG(uname, lname, policy) \
223static __always_inline int TestClearPage##uname(struct page *page) \
224 { return test_and_clear_bit(PG_##lname, &policy(page, 1)->flags); }
225
226#define PAGEFLAG(uname, lname, policy) \
227 TESTPAGEFLAG(uname, lname, policy) \
228 SETPAGEFLAG(uname, lname, policy) \
229 CLEARPAGEFLAG(uname, lname, policy)
230
231#define __PAGEFLAG(uname, lname, policy) \
232 TESTPAGEFLAG(uname, lname, policy) \
233 __SETPAGEFLAG(uname, lname, policy) \
234 __CLEARPAGEFLAG(uname, lname, policy)
235
236#define TESTSCFLAG(uname, lname, policy) \
237 TESTSETFLAG(uname, lname, policy) \
238 TESTCLEARFLAG(uname, lname, policy)
239
240#define TESTPAGEFLAG_FALSE(uname) \
241static inline int Page##uname(const struct page *page) { return 0; }
242
243#define SETPAGEFLAG_NOOP(uname) \
244static inline void SetPage##uname(struct page *page) { }
245
246#define CLEARPAGEFLAG_NOOP(uname) \
247static inline void ClearPage##uname(struct page *page) { }
248
249#define __CLEARPAGEFLAG_NOOP(uname) \
250static inline void __ClearPage##uname(struct page *page) { }
251
252#define TESTSETFLAG_FALSE(uname) \
253static inline int TestSetPage##uname(struct page *page) { return 0; }
254
255#define TESTCLEARFLAG_FALSE(uname) \
256static inline int TestClearPage##uname(struct page *page) { return 0; }
257
258#define PAGEFLAG_FALSE(uname) TESTPAGEFLAG_FALSE(uname) \
259 SETPAGEFLAG_NOOP(uname) CLEARPAGEFLAG_NOOP(uname)
260
261#define TESTSCFLAG_FALSE(uname) \
262 TESTSETFLAG_FALSE(uname) TESTCLEARFLAG_FALSE(uname)
263
264__PAGEFLAG(Locked, locked, PF_NO_TAIL)
265PAGEFLAG(Waiters, waiters, PF_ONLY_HEAD) __CLEARPAGEFLAG(Waiters, waiters, PF_ONLY_HEAD)
266PAGEFLAG(Error, error, PF_NO_COMPOUND) TESTCLEARFLAG(Error, error, PF_NO_COMPOUND)
267PAGEFLAG(Referenced, referenced, PF_HEAD)
268 TESTCLEARFLAG(Referenced, referenced, PF_HEAD)
269 __SETPAGEFLAG(Referenced, referenced, PF_HEAD)
270PAGEFLAG(Dirty, dirty, PF_HEAD) TESTSCFLAG(Dirty, dirty, PF_HEAD)
271 __CLEARPAGEFLAG(Dirty, dirty, PF_HEAD)
272PAGEFLAG(LRU, lru, PF_HEAD) __CLEARPAGEFLAG(LRU, lru, PF_HEAD)
273PAGEFLAG(Active, active, PF_HEAD) __CLEARPAGEFLAG(Active, active, PF_HEAD)
274 TESTCLEARFLAG(Active, active, PF_HEAD)
275__PAGEFLAG(Slab, slab, PF_NO_TAIL)
276__PAGEFLAG(SlobFree, slob_free, PF_NO_TAIL)
277PAGEFLAG(Checked, checked, PF_NO_COMPOUND)
278
279
280PAGEFLAG(Pinned, pinned, PF_NO_COMPOUND)
281 TESTSCFLAG(Pinned, pinned, PF_NO_COMPOUND)
282PAGEFLAG(SavePinned, savepinned, PF_NO_COMPOUND);
283PAGEFLAG(Foreign, foreign, PF_NO_COMPOUND);
284
285PAGEFLAG(Reserved, reserved, PF_NO_COMPOUND)
286 __CLEARPAGEFLAG(Reserved, reserved, PF_NO_COMPOUND)
287PAGEFLAG(SwapBacked, swapbacked, PF_NO_TAIL)
288 __CLEARPAGEFLAG(SwapBacked, swapbacked, PF_NO_TAIL)
289 __SETPAGEFLAG(SwapBacked, swapbacked, PF_NO_TAIL)
290
291
292
293
294
295
296PAGEFLAG(Private, private, PF_ANY) __SETPAGEFLAG(Private, private, PF_ANY)
297 __CLEARPAGEFLAG(Private, private, PF_ANY)
298PAGEFLAG(Private2, private_2, PF_ANY) TESTSCFLAG(Private2, private_2, PF_ANY)
299PAGEFLAG(OwnerPriv1, owner_priv_1, PF_ANY)
300 TESTCLEARFLAG(OwnerPriv1, owner_priv_1, PF_ANY)
301
302
303
304
305
306TESTPAGEFLAG(Writeback, writeback, PF_NO_COMPOUND)
307 TESTSCFLAG(Writeback, writeback, PF_NO_COMPOUND)
308PAGEFLAG(MappedToDisk, mappedtodisk, PF_NO_TAIL)
309
310
311PAGEFLAG(Reclaim, reclaim, PF_NO_TAIL)
312 TESTCLEARFLAG(Reclaim, reclaim, PF_NO_TAIL)
313PAGEFLAG(Readahead, reclaim, PF_NO_COMPOUND)
314 TESTCLEARFLAG(Readahead, reclaim, PF_NO_COMPOUND)
315
316#ifdef CONFIG_HIGHMEM
317
318
319
320
321#define PageHighMem(__p) is_highmem_idx(page_zonenum(__p))
322#else
323PAGEFLAG_FALSE(HighMem)
324#endif
325
326#ifdef CONFIG_SWAP
327static __always_inline int PageSwapCache(struct page *page)
328{
329 return PageSwapBacked(page) && test_bit(PG_swapcache, &page->flags);
330
331}
332SETPAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND)
333CLEARPAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND)
334#else
335PAGEFLAG_FALSE(SwapCache)
336#endif
337
338PAGEFLAG(Unevictable, unevictable, PF_HEAD)
339 __CLEARPAGEFLAG(Unevictable, unevictable, PF_HEAD)
340 TESTCLEARFLAG(Unevictable, unevictable, PF_HEAD)
341
342#ifdef CONFIG_MMU
343PAGEFLAG(Mlocked, mlocked, PF_NO_TAIL)
344 __CLEARPAGEFLAG(Mlocked, mlocked, PF_NO_TAIL)
345 TESTSCFLAG(Mlocked, mlocked, PF_NO_TAIL)
346#else
347PAGEFLAG_FALSE(Mlocked) __CLEARPAGEFLAG_NOOP(Mlocked)
348 TESTSCFLAG_FALSE(Mlocked)
349#endif
350
351#ifdef CONFIG_ARCH_USES_PG_UNCACHED
352PAGEFLAG(Uncached, uncached, PF_NO_COMPOUND)
353#else
354PAGEFLAG_FALSE(Uncached)
355#endif
356
357#ifdef CONFIG_MEMORY_FAILURE
358PAGEFLAG(HWPoison, hwpoison, PF_ANY)
359TESTSCFLAG(HWPoison, hwpoison, PF_ANY)
360#define __PG_HWPOISON (1UL << PG_hwpoison)
361#else
362PAGEFLAG_FALSE(HWPoison)
363#define __PG_HWPOISON 0
364#endif
365
366#if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT)
367TESTPAGEFLAG(Young, young, PF_ANY)
368SETPAGEFLAG(Young, young, PF_ANY)
369TESTCLEARFLAG(Young, young, PF_ANY)
370PAGEFLAG(Idle, idle, PF_ANY)
371#endif
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390#define PAGE_MAPPING_ANON 0x1
391#define PAGE_MAPPING_MOVABLE 0x2
392#define PAGE_MAPPING_KSM (PAGE_MAPPING_ANON | PAGE_MAPPING_MOVABLE)
393#define PAGE_MAPPING_FLAGS (PAGE_MAPPING_ANON | PAGE_MAPPING_MOVABLE)
394
395static __always_inline int PageMappingFlags(struct page *page)
396{
397 return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) != 0;
398}
399
400static __always_inline int PageAnon(struct page *page)
401{
402 page = compound_head(page);
403 return ((unsigned long)page->mapping & PAGE_MAPPING_ANON) != 0;
404}
405
406static __always_inline int __PageMovable(struct page *page)
407{
408 return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) ==
409 PAGE_MAPPING_MOVABLE;
410}
411
412#ifdef CONFIG_KSM
413
414
415
416
417
418
419static __always_inline int PageKsm(struct page *page)
420{
421 page = compound_head(page);
422 return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) ==
423 PAGE_MAPPING_KSM;
424}
425#else
426TESTPAGEFLAG_FALSE(Ksm)
427#endif
428
429u64 stable_page_flags(struct page *page);
430
431static inline int PageUptodate(struct page *page)
432{
433 int ret;
434 page = compound_head(page);
435 ret = test_bit(PG_uptodate, &(page)->flags);
436
437
438
439
440
441
442
443
444 if (ret)
445 smp_rmb();
446
447 return ret;
448}
449
450static __always_inline void __SetPageUptodate(struct page *page)
451{
452 VM_BUG_ON_PAGE(PageTail(page), page);
453 smp_wmb();
454 __set_bit(PG_uptodate, &page->flags);
455}
456
457static __always_inline void SetPageUptodate(struct page *page)
458{
459 VM_BUG_ON_PAGE(PageTail(page), page);
460
461
462
463
464
465 smp_wmb();
466 set_bit(PG_uptodate, &page->flags);
467}
468
469CLEARPAGEFLAG(Uptodate, uptodate, PF_NO_TAIL)
470
471int test_clear_page_writeback(struct page *page);
472int __test_set_page_writeback(struct page *page, bool keep_write);
473
474#define test_set_page_writeback(page) \
475 __test_set_page_writeback(page, false)
476#define test_set_page_writeback_keepwrite(page) \
477 __test_set_page_writeback(page, true)
478
479static inline void set_page_writeback(struct page *page)
480{
481 test_set_page_writeback(page);
482}
483
484static inline void set_page_writeback_keepwrite(struct page *page)
485{
486 test_set_page_writeback_keepwrite(page);
487}
488
489__PAGEFLAG(Head, head, PF_ANY) CLEARPAGEFLAG(Head, head, PF_ANY)
490
491static __always_inline void set_compound_head(struct page *page, struct page *head)
492{
493 WRITE_ONCE(page->compound_head, (unsigned long)head + 1);
494}
495
496static __always_inline void clear_compound_head(struct page *page)
497{
498 WRITE_ONCE(page->compound_head, 0);
499}
500
501#ifdef CONFIG_TRANSPARENT_HUGEPAGE
502static inline void ClearPageCompound(struct page *page)
503{
504 BUG_ON(!PageHead(page));
505 ClearPageHead(page);
506}
507#endif
508
509#define PG_head_mask ((1UL << PG_head))
510
511#ifdef CONFIG_HUGETLB_PAGE
512int PageHuge(struct page *page);
513int PageHeadHuge(struct page *page);
514bool page_huge_active(struct page *page);
515#else
516TESTPAGEFLAG_FALSE(Huge)
517TESTPAGEFLAG_FALSE(HeadHuge)
518
519static inline bool page_huge_active(struct page *page)
520{
521 return 0;
522}
523#endif
524
525
526#ifdef CONFIG_TRANSPARENT_HUGEPAGE
527
528
529
530
531
532
533
534
535static inline int PageTransHuge(struct page *page)
536{
537 VM_BUG_ON_PAGE(PageTail(page), page);
538 return PageHead(page);
539}
540
541
542
543
544
545
546static inline int PageTransCompound(struct page *page)
547{
548 return PageCompound(page);
549}
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567static inline int PageTransCompoundMap(struct page *page)
568{
569 return PageTransCompound(page) && atomic_read(&page->_mapcount) < 0;
570}
571
572
573
574
575
576
577static inline int PageTransTail(struct page *page)
578{
579 return PageTail(page);
580}
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595static inline int PageDoubleMap(struct page *page)
596{
597 return PageHead(page) && test_bit(PG_double_map, &page[1].flags);
598}
599
600static inline void SetPageDoubleMap(struct page *page)
601{
602 VM_BUG_ON_PAGE(!PageHead(page), page);
603 set_bit(PG_double_map, &page[1].flags);
604}
605
606static inline void ClearPageDoubleMap(struct page *page)
607{
608 VM_BUG_ON_PAGE(!PageHead(page), page);
609 clear_bit(PG_double_map, &page[1].flags);
610}
611static inline int TestSetPageDoubleMap(struct page *page)
612{
613 VM_BUG_ON_PAGE(!PageHead(page), page);
614 return test_and_set_bit(PG_double_map, &page[1].flags);
615}
616
617static inline int TestClearPageDoubleMap(struct page *page)
618{
619 VM_BUG_ON_PAGE(!PageHead(page), page);
620 return test_and_clear_bit(PG_double_map, &page[1].flags);
621}
622
623#else
624TESTPAGEFLAG_FALSE(TransHuge)
625TESTPAGEFLAG_FALSE(TransCompound)
626TESTPAGEFLAG_FALSE(TransCompoundMap)
627TESTPAGEFLAG_FALSE(TransTail)
628PAGEFLAG_FALSE(DoubleMap)
629 TESTSETFLAG_FALSE(DoubleMap)
630 TESTCLEARFLAG_FALSE(DoubleMap)
631#endif
632
633
634
635
636
637
638
639
640#define PAGE_MAPCOUNT_OPS(uname, lname) \
641static __always_inline int Page##uname(struct page *page) \
642{ \
643 return atomic_read(&page->_mapcount) == \
644 PAGE_##lname##_MAPCOUNT_VALUE; \
645} \
646static __always_inline void __SetPage##uname(struct page *page) \
647{ \
648 VM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page); \
649 atomic_set(&page->_mapcount, PAGE_##lname##_MAPCOUNT_VALUE); \
650} \
651static __always_inline void __ClearPage##uname(struct page *page) \
652{ \
653 VM_BUG_ON_PAGE(!Page##uname(page), page); \
654 atomic_set(&page->_mapcount, -1); \
655}
656
657
658
659
660
661#define PAGE_BUDDY_MAPCOUNT_VALUE (-128)
662PAGE_MAPCOUNT_OPS(Buddy, BUDDY)
663
664
665
666
667
668#define PAGE_BALLOON_MAPCOUNT_VALUE (-256)
669PAGE_MAPCOUNT_OPS(Balloon, BALLOON)
670
671
672
673
674
675#define PAGE_KMEMCG_MAPCOUNT_VALUE (-512)
676PAGE_MAPCOUNT_OPS(Kmemcg, KMEMCG)
677
678extern bool is_free_buddy_page(struct page *page);
679
680__PAGEFLAG(Isolated, isolated, PF_ANY);
681
682
683
684
685
686static inline int PageSlabPfmemalloc(struct page *page)
687{
688 VM_BUG_ON_PAGE(!PageSlab(page), page);
689 return PageActive(page);
690}
691
692static inline void SetPageSlabPfmemalloc(struct page *page)
693{
694 VM_BUG_ON_PAGE(!PageSlab(page), page);
695 SetPageActive(page);
696}
697
698static inline void __ClearPageSlabPfmemalloc(struct page *page)
699{
700 VM_BUG_ON_PAGE(!PageSlab(page), page);
701 __ClearPageActive(page);
702}
703
704static inline void ClearPageSlabPfmemalloc(struct page *page)
705{
706 VM_BUG_ON_PAGE(!PageSlab(page), page);
707 ClearPageActive(page);
708}
709
710#ifdef CONFIG_MMU
711#define __PG_MLOCKED (1UL << PG_mlocked)
712#else
713#define __PG_MLOCKED 0
714#endif
715
716
717
718
719
720#define PAGE_FLAGS_CHECK_AT_FREE \
721 (1UL << PG_lru | 1UL << PG_locked | \
722 1UL << PG_private | 1UL << PG_private_2 | \
723 1UL << PG_writeback | 1UL << PG_reserved | \
724 1UL << PG_slab | 1UL << PG_active | \
725 1UL << PG_unevictable | __PG_MLOCKED)
726
727
728
729
730
731
732
733
734
735#define PAGE_FLAGS_CHECK_AT_PREP \
736 (((1UL << NR_PAGEFLAGS) - 1) & ~__PG_HWPOISON)
737
738#define PAGE_FLAGS_PRIVATE \
739 (1UL << PG_private | 1UL << PG_private_2)
740
741
742
743
744
745
746
747static inline int page_has_private(struct page *page)
748{
749 return !!(page->flags & PAGE_FLAGS_PRIVATE);
750}
751
752#undef PF_ANY
753#undef PF_HEAD
754#undef PF_ONLY_HEAD
755#undef PF_NO_TAIL
756#undef PF_NO_COMPOUND
757#endif
758
759#endif
760