diff options
-rw-r--r-- | include/linux/page-flags.h | 195 |
1 files changed, 68 insertions, 127 deletions
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index e5bddbfcf7ae..ed7659adfaaf 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h | |||
@@ -149,28 +149,58 @@ static inline int TestClearPage##uname(struct page *page) \ | |||
149 | #define TESTSCFLAG(uname, lname) \ | 149 | #define TESTSCFLAG(uname, lname) \ |
150 | TESTSETFLAG(uname, lname) TESTCLEARFLAG(uname, lname) | 150 | TESTSETFLAG(uname, lname) TESTCLEARFLAG(uname, lname) |
151 | 151 | ||
152 | struct page; /* forward declaration */ | ||
153 | |||
154 | PAGEFLAG(Locked, locked) TESTSCFLAG(Locked, locked) | ||
155 | PAGEFLAG(Error, error) | ||
156 | PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced) | ||
157 | PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty) | ||
158 | PAGEFLAG(LRU, lru) __CLEARPAGEFLAG(LRU, lru) | ||
159 | PAGEFLAG(Active, active) __CLEARPAGEFLAG(Active, active) | ||
160 | __PAGEFLAG(Slab, slab) | ||
161 | PAGEFLAG(Checked, checked) /* Used by some filesystems */ | ||
162 | PAGEFLAG(Pinned, pinned) /* Xen pinned pagetable */ | ||
163 | PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved) | ||
164 | PAGEFLAG(Private, private) __CLEARPAGEFLAG(Private, private) | ||
165 | __SETPAGEFLAG(Private, private) | ||
166 | |||
167 | /* | ||
168 | * Only test-and-set exist for PG_writeback. The unconditional operators are | ||
169 | * risky: they bypass page accounting. | ||
170 | */ | ||
171 | TESTPAGEFLAG(Writeback, writeback) TESTSCFLAG(Writeback, writeback) | ||
172 | __PAGEFLAG(Buddy, buddy) | ||
173 | PAGEFLAG(MappedToDisk, mappedtodisk) | ||
174 | |||
175 | /* PG_readahead is only used for file reads; PG_reclaim is only for writes */ | ||
176 | PAGEFLAG(Reclaim, reclaim) TESTCLEARFLAG(Reclaim, reclaim) | ||
177 | PAGEFLAG(Readahead, readahead) /* Reminder to do async read-ahead */ | ||
178 | |||
179 | #ifdef CONFIG_HIGHMEM | ||
152 | /* | 180 | /* |
153 | * Manipulation of page state flags | 181 | * Must use a macro here due to header dependency issues. page_zone() is not |
182 | * available at this point. | ||
154 | */ | 183 | */ |
155 | #define PageLocked(page) \ | 184 | #define PageHighMem(__p) is_highmem(page_zone(page)) |
156 | test_bit(PG_locked, &(page)->flags) | 185 | #else |
157 | #define SetPageLocked(page) \ | 186 | static inline int PageHighMem(struct page *page) |
158 | set_bit(PG_locked, &(page)->flags) | 187 | { |
159 | #define TestSetPageLocked(page) \ | 188 | return 0; |
160 | test_and_set_bit(PG_locked, &(page)->flags) | 189 | } |
161 | #define ClearPageLocked(page) \ | 190 | #endif |
162 | clear_bit(PG_locked, &(page)->flags) | 191 | |
163 | #define TestClearPageLocked(page) \ | 192 | #ifdef CONFIG_SWAP |
164 | test_and_clear_bit(PG_locked, &(page)->flags) | 193 | PAGEFLAG(SwapCache, swapcache) |
165 | 194 | #else | |
166 | #define PageError(page) test_bit(PG_error, &(page)->flags) | 195 | static inline int PageSwapCache(struct page *page) |
167 | #define SetPageError(page) set_bit(PG_error, &(page)->flags) | 196 | { |
168 | #define ClearPageError(page) clear_bit(PG_error, &(page)->flags) | 197 | return 0; |
169 | 198 | } | |
170 | #define PageReferenced(page) test_bit(PG_referenced, &(page)->flags) | 199 | #endif |
171 | #define SetPageReferenced(page) set_bit(PG_referenced, &(page)->flags) | 200 | |
172 | #define ClearPageReferenced(page) clear_bit(PG_referenced, &(page)->flags) | 201 | #if (BITS_PER_LONG > 32) |
173 | #define TestClearPageReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags) | 202 | PAGEFLAG(Uncached, uncached) |
203 | #endif | ||
174 | 204 | ||
175 | static inline int PageUptodate(struct page *page) | 205 | static inline int PageUptodate(struct page *page) |
176 | { | 206 | { |
@@ -218,97 +248,37 @@ static inline void SetPageUptodate(struct page *page) | |||
218 | #endif | 248 | #endif |
219 | } | 249 | } |
220 | 250 | ||
221 | #define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags) | 251 | CLEARPAGEFLAG(Uptodate, uptodate) |
222 | |||
223 | #define PageDirty(page) test_bit(PG_dirty, &(page)->flags) | ||
224 | #define SetPageDirty(page) set_bit(PG_dirty, &(page)->flags) | ||
225 | #define TestSetPageDirty(page) test_and_set_bit(PG_dirty, &(page)->flags) | ||
226 | #define ClearPageDirty(page) clear_bit(PG_dirty, &(page)->flags) | ||
227 | #define __ClearPageDirty(page) __clear_bit(PG_dirty, &(page)->flags) | ||
228 | #define TestClearPageDirty(page) test_and_clear_bit(PG_dirty, &(page)->flags) | ||
229 | |||
230 | #define PageLRU(page) test_bit(PG_lru, &(page)->flags) | ||
231 | #define SetPageLRU(page) set_bit(PG_lru, &(page)->flags) | ||
232 | #define ClearPageLRU(page) clear_bit(PG_lru, &(page)->flags) | ||
233 | #define __ClearPageLRU(page) __clear_bit(PG_lru, &(page)->flags) | ||
234 | |||
235 | #define PageActive(page) test_bit(PG_active, &(page)->flags) | ||
236 | #define SetPageActive(page) set_bit(PG_active, &(page)->flags) | ||
237 | #define ClearPageActive(page) clear_bit(PG_active, &(page)->flags) | ||
238 | #define __ClearPageActive(page) __clear_bit(PG_active, &(page)->flags) | ||
239 | |||
240 | #define PageSlab(page) test_bit(PG_slab, &(page)->flags) | ||
241 | #define __SetPageSlab(page) __set_bit(PG_slab, &(page)->flags) | ||
242 | #define __ClearPageSlab(page) __clear_bit(PG_slab, &(page)->flags) | ||
243 | |||
244 | #ifdef CONFIG_HIGHMEM | ||
245 | #define PageHighMem(page) is_highmem(page_zone(page)) | ||
246 | #else | ||
247 | #define PageHighMem(page) 0 /* needed to optimize away at compile time */ | ||
248 | #endif | ||
249 | |||
250 | #define PageChecked(page) test_bit(PG_checked, &(page)->flags) | ||
251 | #define SetPageChecked(page) set_bit(PG_checked, &(page)->flags) | ||
252 | #define ClearPageChecked(page) clear_bit(PG_checked, &(page)->flags) | ||
253 | |||
254 | #define PagePinned(page) test_bit(PG_pinned, &(page)->flags) | ||
255 | #define SetPagePinned(page) set_bit(PG_pinned, &(page)->flags) | ||
256 | #define ClearPagePinned(page) clear_bit(PG_pinned, &(page)->flags) | ||
257 | |||
258 | #define PageReserved(page) test_bit(PG_reserved, &(page)->flags) | ||
259 | #define SetPageReserved(page) set_bit(PG_reserved, &(page)->flags) | ||
260 | #define ClearPageReserved(page) clear_bit(PG_reserved, &(page)->flags) | ||
261 | #define __ClearPageReserved(page) __clear_bit(PG_reserved, &(page)->flags) | ||
262 | |||
263 | #define SetPagePrivate(page) set_bit(PG_private, &(page)->flags) | ||
264 | #define ClearPagePrivate(page) clear_bit(PG_private, &(page)->flags) | ||
265 | #define PagePrivate(page) test_bit(PG_private, &(page)->flags) | ||
266 | #define __SetPagePrivate(page) __set_bit(PG_private, &(page)->flags) | ||
267 | #define __ClearPagePrivate(page) __clear_bit(PG_private, &(page)->flags) | ||
268 | 252 | ||
269 | /* | 253 | extern void cancel_dirty_page(struct page *page, unsigned int account_size); |
270 | * Only test-and-set exist for PG_writeback. The unconditional operators are | ||
271 | * risky: they bypass page accounting. | ||
272 | */ | ||
273 | #define PageWriteback(page) test_bit(PG_writeback, &(page)->flags) | ||
274 | #define TestSetPageWriteback(page) test_and_set_bit(PG_writeback, \ | ||
275 | &(page)->flags) | ||
276 | #define TestClearPageWriteback(page) test_and_clear_bit(PG_writeback, \ | ||
277 | &(page)->flags) | ||
278 | |||
279 | #define PageBuddy(page) test_bit(PG_buddy, &(page)->flags) | ||
280 | #define __SetPageBuddy(page) __set_bit(PG_buddy, &(page)->flags) | ||
281 | #define __ClearPageBuddy(page) __clear_bit(PG_buddy, &(page)->flags) | ||
282 | |||
283 | #define PageMappedToDisk(page) test_bit(PG_mappedtodisk, &(page)->flags) | ||
284 | #define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags) | ||
285 | #define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags) | ||
286 | 254 | ||
287 | #define PageReadahead(page) test_bit(PG_readahead, &(page)->flags) | 255 | int test_clear_page_writeback(struct page *page); |
288 | #define SetPageReadahead(page) set_bit(PG_readahead, &(page)->flags) | 256 | int test_set_page_writeback(struct page *page); |
289 | #define ClearPageReadahead(page) clear_bit(PG_readahead, &(page)->flags) | ||
290 | 257 | ||
291 | #define PageReclaim(page) test_bit(PG_reclaim, &(page)->flags) | 258 | static inline void set_page_writeback(struct page *page) |
292 | #define SetPageReclaim(page) set_bit(PG_reclaim, &(page)->flags) | 259 | { |
293 | #define ClearPageReclaim(page) clear_bit(PG_reclaim, &(page)->flags) | 260 | test_set_page_writeback(page); |
294 | #define TestClearPageReclaim(page) test_and_clear_bit(PG_reclaim, &(page)->flags) | 261 | } |
295 | 262 | ||
296 | #define PageCompound(page) test_bit(PG_compound, &(page)->flags) | 263 | TESTPAGEFLAG(Compound, compound) |
297 | #define __SetPageCompound(page) __set_bit(PG_compound, &(page)->flags) | 264 | __PAGEFLAG(Head, compound) |
298 | #define __ClearPageCompound(page) __clear_bit(PG_compound, &(page)->flags) | ||
299 | 265 | ||
300 | /* | 266 | /* |
301 | * PG_reclaim is used in combination with PG_compound to mark the | 267 | * PG_reclaim is used in combination with PG_compound to mark the |
302 | * head and tail of a compound page | 268 | * head and tail of a compound page. This saves one page flag |
269 | * but makes it impossible to use compound pages for the page cache. | ||
270 | * The PG_reclaim bit would have to be used for reclaim or readahead | ||
271 | * if compound pages enter the page cache. | ||
303 | * | 272 | * |
304 | * PG_compound & PG_reclaim => Tail page | 273 | * PG_compound & PG_reclaim => Tail page |
305 | * PG_compound & ~PG_reclaim => Head page | 274 | * PG_compound & ~PG_reclaim => Head page |
306 | */ | 275 | */ |
307 | |||
308 | #define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim)) | 276 | #define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim)) |
309 | 277 | ||
310 | #define PageTail(page) (((page)->flags & PG_head_tail_mask) \ | 278 | static inline int PageTail(struct page *page) |
311 | == PG_head_tail_mask) | 279 | { |
280 | return ((page->flags & PG_head_tail_mask) == PG_head_tail_mask); | ||
281 | } | ||
312 | 282 | ||
313 | static inline void __SetPageTail(struct page *page) | 283 | static inline void __SetPageTail(struct page *page) |
314 | { | 284 | { |
@@ -320,34 +290,5 @@ static inline void __ClearPageTail(struct page *page) | |||
320 | page->flags &= ~PG_head_tail_mask; | 290 | page->flags &= ~PG_head_tail_mask; |
321 | } | 291 | } |
322 | 292 | ||
323 | #define PageHead(page) (((page)->flags & PG_head_tail_mask) \ | ||
324 | == (1L << PG_compound)) | ||
325 | #define __SetPageHead(page) __SetPageCompound(page) | ||
326 | #define __ClearPageHead(page) __ClearPageCompound(page) | ||
327 | |||
328 | #ifdef CONFIG_SWAP | ||
329 | #define PageSwapCache(page) test_bit(PG_swapcache, &(page)->flags) | ||
330 | #define SetPageSwapCache(page) set_bit(PG_swapcache, &(page)->flags) | ||
331 | #define ClearPageSwapCache(page) clear_bit(PG_swapcache, &(page)->flags) | ||
332 | #else | ||
333 | #define PageSwapCache(page) 0 | ||
334 | #endif | ||
335 | |||
336 | #define PageUncached(page) test_bit(PG_uncached, &(page)->flags) | ||
337 | #define SetPageUncached(page) set_bit(PG_uncached, &(page)->flags) | ||
338 | #define ClearPageUncached(page) clear_bit(PG_uncached, &(page)->flags) | ||
339 | |||
340 | struct page; /* forward declaration */ | ||
341 | |||
342 | extern void cancel_dirty_page(struct page *page, unsigned int account_size); | ||
343 | |||
344 | int test_clear_page_writeback(struct page *page); | ||
345 | int test_set_page_writeback(struct page *page); | ||
346 | |||
347 | static inline void set_page_writeback(struct page *page) | ||
348 | { | ||
349 | test_set_page_writeback(page); | ||
350 | } | ||
351 | |||
352 | #endif /* !__GENERATING_BOUNDS_H */ | 293 | #endif /* !__GENERATING_BOUNDS_H */ |
353 | #endif /* PAGE_FLAGS_H */ | 294 | #endif /* PAGE_FLAGS_H */ |