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 <linux/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_writeback,
86#ifdef CONFIG_PAGEFLAGS_EXTENDED
87 PG_head,
88 PG_tail,
89#else
90 PG_compound,
91#endif
92 PG_swapcache,
93 PG_mappedtodisk,
94 PG_reclaim,
95 PG_buddy,
96 PG_swapbacked,
97#ifdef CONFIG_UNEVICTABLE_LRU
98 PG_unevictable,
99 PG_mlocked,
100#endif
101#ifdef CONFIG_IA64_UNCACHED_ALLOCATOR
102 PG_uncached,
103#endif
104 __NR_PAGEFLAGS,
105
106
107 PG_checked = PG_owner_priv_1,
108
109
110 PG_pinned = PG_owner_priv_1,
111 PG_savepinned = PG_dirty,
112
113
114 PG_slob_page = PG_active,
115 PG_slob_free = PG_private,
116
117
118 PG_slub_frozen = PG_active,
119 PG_slub_debug = PG_error,
120};
121
122#ifndef __GENERATING_BOUNDS_H
123
124
125
126
127#define TESTPAGEFLAG(uname, lname) \
128static inline int Page##uname(struct page *page) \
129 { return test_bit(PG_##lname, &page->flags); }
130
131#define SETPAGEFLAG(uname, lname) \
132static inline void SetPage##uname(struct page *page) \
133 { set_bit(PG_##lname, &page->flags); }
134
135#define CLEARPAGEFLAG(uname, lname) \
136static inline void ClearPage##uname(struct page *page) \
137 { clear_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 TESTSETFLAG(uname, lname) \
148static inline int TestSetPage##uname(struct page *page) \
149 { return test_and_set_bit(PG_##lname, &page->flags); }
150
151#define TESTCLEARFLAG(uname, lname) \
152static inline int TestClearPage##uname(struct page *page) \
153 { return test_and_clear_bit(PG_##lname, &page->flags); }
154
155
156#define PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \
157 SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname)
158
159#define __PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \
160 __SETPAGEFLAG(uname, lname) __CLEARPAGEFLAG(uname, lname)
161
162#define PAGEFLAG_FALSE(uname) \
163static inline int Page##uname(struct page *page) \
164 { return 0; }
165
166#define TESTSCFLAG(uname, lname) \
167 TESTSETFLAG(uname, lname) TESTCLEARFLAG(uname, lname)
168
169#define SETPAGEFLAG_NOOP(uname) \
170static inline void SetPage##uname(struct page *page) { }
171
172#define CLEARPAGEFLAG_NOOP(uname) \
173static inline void ClearPage##uname(struct page *page) { }
174
175#define __CLEARPAGEFLAG_NOOP(uname) \
176static inline void __ClearPage##uname(struct page *page) { }
177
178#define TESTCLEARFLAG_FALSE(uname) \
179static inline int TestClearPage##uname(struct page *page) { return 0; }
180
181struct page;
182
183TESTPAGEFLAG(Locked, locked)
184PAGEFLAG(Error, error)
185PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced)
186PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty)
187PAGEFLAG(LRU, lru) __CLEARPAGEFLAG(LRU, lru)
188PAGEFLAG(Active, active) __CLEARPAGEFLAG(Active, active)
189 TESTCLEARFLAG(Active, active)
190__PAGEFLAG(Slab, slab)
191PAGEFLAG(Checked, checked)
192PAGEFLAG(Pinned, pinned) TESTSCFLAG(Pinned, pinned)
193PAGEFLAG(SavePinned, savepinned);
194PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)
195PAGEFLAG(Private, private) __CLEARPAGEFLAG(Private, private)
196 __SETPAGEFLAG(Private, private)
197PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
198
199__PAGEFLAG(SlobPage, slob_page)
200__PAGEFLAG(SlobFree, slob_free)
201
202__PAGEFLAG(SlubFrozen, slub_frozen)
203__PAGEFLAG(SlubDebug, slub_debug)
204
205
206
207
208
209TESTPAGEFLAG(Writeback, writeback) TESTSCFLAG(Writeback, writeback)
210__PAGEFLAG(Buddy, buddy)
211PAGEFLAG(MappedToDisk, mappedtodisk)
212
213
214PAGEFLAG(Reclaim, reclaim) TESTCLEARFLAG(Reclaim, reclaim)
215PAGEFLAG(Readahead, reclaim)
216
217#ifdef CONFIG_HIGHMEM
218
219
220
221
222#define PageHighMem(__p) is_highmem(page_zone(__p))
223#else
224PAGEFLAG_FALSE(HighMem)
225#endif
226
227#ifdef CONFIG_SWAP
228PAGEFLAG(SwapCache, swapcache)
229#else
230PAGEFLAG_FALSE(SwapCache)
231#endif
232
233#ifdef CONFIG_UNEVICTABLE_LRU
234PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable)
235 TESTCLEARFLAG(Unevictable, unevictable)
236
237#define MLOCK_PAGES 1
238PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked)
239 TESTSCFLAG(Mlocked, mlocked)
240
241#else
242
243#define MLOCK_PAGES 0
244PAGEFLAG_FALSE(Mlocked)
245 SETPAGEFLAG_NOOP(Mlocked) TESTCLEARFLAG_FALSE(Mlocked)
246
247PAGEFLAG_FALSE(Unevictable) TESTCLEARFLAG_FALSE(Unevictable)
248 SETPAGEFLAG_NOOP(Unevictable) CLEARPAGEFLAG_NOOP(Unevictable)
249 __CLEARPAGEFLAG_NOOP(Unevictable)
250#endif
251
252#ifdef CONFIG_IA64_UNCACHED_ALLOCATOR
253PAGEFLAG(Uncached, uncached)
254#else
255PAGEFLAG_FALSE(Uncached)
256#endif
257
258static inline int PageUptodate(struct page *page)
259{
260 int ret = test_bit(PG_uptodate, &(page)->flags);
261
262
263
264
265
266
267
268
269
270 if (ret)
271 smp_rmb();
272
273 return ret;
274}
275
276static inline void __SetPageUptodate(struct page *page)
277{
278 smp_wmb();
279 __set_bit(PG_uptodate, &(page)->flags);
280}
281
282static inline void SetPageUptodate(struct page *page)
283{
284#ifdef CONFIG_S390
285 if (!test_and_set_bit(PG_uptodate, &page->flags))
286 page_clear_dirty(page);
287#else
288
289
290
291
292
293
294
295
296 smp_wmb();
297 set_bit(PG_uptodate, &(page)->flags);
298#endif
299}
300
301CLEARPAGEFLAG(Uptodate, uptodate)
302
303extern void cancel_dirty_page(struct page *page, unsigned int account_size);
304
305int test_clear_page_writeback(struct page *page);
306int test_set_page_writeback(struct page *page);
307
308static inline void set_page_writeback(struct page *page)
309{
310 test_set_page_writeback(page);
311}
312
313#ifdef CONFIG_PAGEFLAGS_EXTENDED
314
315
316
317
318
319
320__PAGEFLAG(Head, head)
321__PAGEFLAG(Tail, tail)
322
323static inline int PageCompound(struct page *page)
324{
325 return page->flags & ((1L << PG_head) | (1L << PG_tail));
326
327}
328#else
329
330
331
332
333
334
335TESTPAGEFLAG(Compound, compound)
336__PAGEFLAG(Head, compound)
337
338
339
340
341
342
343
344
345
346
347
348#define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim))
349
350static inline int PageTail(struct page *page)
351{
352 return ((page->flags & PG_head_tail_mask) == PG_head_tail_mask);
353}
354
355static inline void __SetPageTail(struct page *page)
356{
357 page->flags |= PG_head_tail_mask;
358}
359
360static inline void __ClearPageTail(struct page *page)
361{
362 page->flags &= ~PG_head_tail_mask;
363}
364
365#endif
366
367#ifdef CONFIG_UNEVICTABLE_LRU
368#define __PG_UNEVICTABLE (1 << PG_unevictable)
369#define __PG_MLOCKED (1 << PG_mlocked)
370#else
371#define __PG_UNEVICTABLE 0
372#define __PG_MLOCKED 0
373#endif
374
375#define PAGE_FLAGS (1 << PG_lru | 1 << PG_private | 1 << PG_locked | \
376 1 << PG_buddy | 1 << PG_writeback | \
377 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active | \
378 __PG_UNEVICTABLE | __PG_MLOCKED)
379
380
381
382
383
384#define PAGE_FLAGS_CLEAR_WHEN_BAD (PAGE_FLAGS | \
385 1 << PG_reclaim | 1 << PG_dirty | 1 << PG_swapbacked)
386
387
388
389
390
391#define PAGE_FLAGS_CHECK_AT_FREE (PAGE_FLAGS | 1 << PG_reserved)
392
393
394
395
396
397
398#define PAGE_FLAGS_CHECK_AT_PREP (PAGE_FLAGS | \
399 1 << PG_reserved | 1 << PG_dirty | 1 << PG_swapbacked)
400
401#endif
402#endif
403