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