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