linux-bk/include/linux/page-flags.h
<<
>>
Prefs
   1/*
   2 * Macros for manipulating and testing page->flags
   3 */
   4
   5#ifndef PAGE_FLAGS_H
   6#define PAGE_FLAGS_H
   7
   8/*
   9 * Various page->flags bits:
  10 *
  11 * PG_reserved is set for special pages, which can never be swapped out. Some
  12 * of them might not even exist (eg empty_bad_page)...
  13 *
  14 * The PG_private bitflag is set if page->private contains a valid value.
  15 *
  16 * During disk I/O, PG_locked is used. This bit is set before I/O and
  17 * reset when I/O completes. page_waitqueue(page) is a wait queue of all tasks
  18 * waiting for the I/O on this page to complete.
  19 *
  20 * PG_uptodate tells whether the page's contents is valid.  When a read
  21 * completes, the page becomes uptodate, unless a disk I/O error happened.
  22 *
  23 * For choosing which pages to swap out, inode pages carry a PG_referenced bit,
  24 * which is set any time the system accesses that page through the (mapping,
  25 * index) hash table.  This referenced bit, together with the referenced bit
  26 * in the page tables, is used to manipulate page->age and move the page across
  27 * the active, inactive_dirty and inactive_clean lists.
  28 *
  29 * Note that the referenced bit, the page->lru list_head and the active,
  30 * inactive_dirty and inactive_clean lists are protected by the
  31 * pagemap_lru_lock, and *NOT* by the usual PG_locked bit!
  32 *
  33 * PG_error is set to indicate that an I/O error occurred on this page.
  34 *
  35 * PG_arch_1 is an architecture specific page state bit.  The generic code
  36 * guarantees that this bit is cleared for a page when it first is entered into
  37 * the page cache.
  38 *
  39 * PG_highmem pages are not permanently mapped into the kernel virtual address
  40 * space, they need to be kmapped separately for doing IO on the pages.  The
  41 * struct page (these bits with information) are always mapped into kernel
  42 * address space...
  43 */
  44
  45/*
  46 * Don't use the *_dontuse flags.  Use the macros.  Otherwise you'll break
  47 * locked- and dirty-page accounting.  The top eight bits of page->flags are
  48 * used for page->zone, so putting flag bits there doesn't work.
  49 */
  50#define PG_locked                0      /* Page is locked. Don't touch. */
  51#define PG_error                 1
  52#define PG_referenced            2
  53#define PG_uptodate              3
  54
  55#define PG_dirty_dontuse         4
  56#define PG_lru                   5
  57#define PG_active                6
  58#define PG_slab                  7      /* slab debug (Suparna wants this) */
  59
  60#define PG_highmem               8
  61#define PG_checked               9      /* kill me in 2.5.<early>. */
  62#define PG_arch_1               10
  63#define PG_reserved             11
  64
  65#define PG_private              12      /* Has something at ->private */
  66#define PG_writeback            13      /* Page is under writeback */
  67#define PG_nosave               14      /* Used for system suspend/resume */
  68#define PG_chainlock            15      /* lock bit for ->pte_chain */
  69
  70#define PG_direct               16      /* ->pte_chain points directly at pte */
  71
  72/*
  73 * Global page accounting.  One instance per CPU.
  74 */
  75extern struct page_state {
  76        unsigned long nr_dirty;
  77        unsigned long nr_writeback;
  78        unsigned long nr_pagecache;
  79        unsigned long nr_active;        /* on active_list LRU */
  80        unsigned long nr_inactive;      /* on inactive_list LRU */
  81        unsigned long nr_page_table_pages;
  82        unsigned long nr_pte_chain_pages;
  83        unsigned long used_pte_chains_bytes;
  84} ____cacheline_aligned_in_smp page_states[NR_CPUS];
  85
  86extern void get_page_state(struct page_state *ret);
  87
  88#define mod_page_state(member, delta)                                   \
  89        do {                                                            \
  90                preempt_disable();                                      \
  91                page_states[smp_processor_id()].member += (delta);      \
  92                preempt_enable();                                       \
  93        } while (0)
  94
  95#define inc_page_state(member)  mod_page_state(member, 1UL)
  96#define dec_page_state(member)  mod_page_state(member, 0UL - 1)
  97
  98
  99/*
 100 * Manipulation of page state flags
 101 */
 102#define PageLocked(page)                \
 103                test_bit(PG_locked, &(page)->flags)
 104#define SetPageLocked(page)             \
 105                set_bit(PG_locked, &(page)->flags)
 106#define TestSetPageLocked(page)         \
 107                test_and_set_bit(PG_locked, &(page)->flags)
 108#define ClearPageLocked(page)           \
 109                clear_bit(PG_locked, &(page)->flags)
 110#define TestClearPageLocked(page)       \
 111                test_and_clear_bit(PG_locked, &(page)->flags)
 112
 113#define PageError(page)         test_bit(PG_error, &(page)->flags)
 114#define SetPageError(page)      set_bit(PG_error, &(page)->flags)
 115#define ClearPageError(page)    clear_bit(PG_error, &(page)->flags)
 116
 117#define PageReferenced(page)    test_bit(PG_referenced, &(page)->flags)
 118#define SetPageReferenced(page) set_bit(PG_referenced, &(page)->flags)
 119#define ClearPageReferenced(page)       clear_bit(PG_referenced, &(page)->flags)
 120#define TestClearPageReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags)
 121
 122#define PageUptodate(page)      test_bit(PG_uptodate, &(page)->flags)
 123#define SetPageUptodate(page)   set_bit(PG_uptodate, &(page)->flags)
 124#define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags)
 125
 126#define PageDirty(page)         test_bit(PG_dirty_dontuse, &(page)->flags)
 127#define SetPageDirty(page)                                              \
 128        do {                                                            \
 129                if (!test_and_set_bit(PG_dirty_dontuse,                 \
 130                                        &(page)->flags))                \
 131                        inc_page_state(nr_dirty);                       \
 132        } while (0)
 133#define TestSetPageDirty(page)                                          \
 134        ({                                                              \
 135                int ret;                                                \
 136                ret = test_and_set_bit(PG_dirty_dontuse,                \
 137                                &(page)->flags);                        \
 138                if (!ret)                                               \
 139                        inc_page_state(nr_dirty);                       \
 140                ret;                                                    \
 141        })
 142#define ClearPageDirty(page)                                            \
 143        do {                                                            \
 144                if (test_and_clear_bit(PG_dirty_dontuse,                \
 145                                &(page)->flags))                        \
 146                        dec_page_state(nr_dirty);                       \
 147        } while (0)
 148#define TestClearPageDirty(page)                                        \
 149        ({                                                              \
 150                int ret;                                                \
 151                ret = test_and_clear_bit(PG_dirty_dontuse,              \
 152                                &(page)->flags);                        \
 153                if (ret)                                                \
 154                        dec_page_state(nr_dirty);                       \
 155                ret;                                                    \
 156        })
 157
 158#define PageLRU(page)           test_bit(PG_lru, &(page)->flags)
 159#define TestSetPageLRU(page)    test_and_set_bit(PG_lru, &(page)->flags)
 160#define TestClearPageLRU(page)  test_and_clear_bit(PG_lru, &(page)->flags)
 161
 162#define PageActive(page)        test_bit(PG_active, &(page)->flags)
 163#define SetPageActive(page)     set_bit(PG_active, &(page)->flags)
 164#define ClearPageActive(page)   clear_bit(PG_active, &(page)->flags)
 165
 166#define PageSlab(page)          test_bit(PG_slab, &(page)->flags)
 167#define SetPageSlab(page)       set_bit(PG_slab, &(page)->flags)
 168#define ClearPageSlab(page)     clear_bit(PG_slab, &(page)->flags)
 169
 170#ifdef CONFIG_HIGHMEM
 171#define PageHighMem(page)       test_bit(PG_highmem, &(page)->flags)
 172#else
 173#define PageHighMem(page)       0 /* needed to optimize away at compile time */
 174#endif
 175
 176#define PageChecked(page)       test_bit(PG_checked, &(page)->flags)
 177#define SetPageChecked(page)    set_bit(PG_checked, &(page)->flags)
 178
 179#define PageReserved(page)      test_bit(PG_reserved, &(page)->flags)
 180#define SetPageReserved(page)   set_bit(PG_reserved, &(page)->flags)
 181#define ClearPageReserved(page) clear_bit(PG_reserved, &(page)->flags)
 182
 183#define SetPagePrivate(page)    set_bit(PG_private, &(page)->flags)
 184#define ClearPagePrivate(page)  clear_bit(PG_private, &(page)->flags)
 185#define PagePrivate(page)       test_bit(PG_private, &(page)->flags)
 186
 187#define PageWriteback(page)     test_bit(PG_writeback, &(page)->flags)
 188#define SetPageWriteback(page)                                          \
 189        do {                                                            \
 190                if (!test_and_set_bit(PG_writeback,                     \
 191                                &(page)->flags))                        \
 192                        inc_page_state(nr_writeback);                   \
 193        } while (0)
 194#define TestSetPageWriteback(page)                                      \
 195        ({                                                              \
 196                int ret;                                                \
 197                ret = test_and_set_bit(PG_writeback,                    \
 198                                        &(page)->flags);                \
 199                if (!ret)                                               \
 200                        inc_page_state(nr_writeback);                   \
 201                ret;                                                    \
 202        })
 203#define ClearPageWriteback(page)                                        \
 204        do {                                                            \
 205                if (test_and_clear_bit(PG_writeback,                    \
 206                                &(page)->flags))                        \
 207                        dec_page_state(nr_writeback);                   \
 208        } while (0)
 209#define TestClearPageWriteback(page)                                    \
 210        ({                                                              \
 211                int ret;                                                \
 212                ret = test_and_clear_bit(PG_writeback,                  \
 213                                &(page)->flags);                        \
 214                if (ret)                                                \
 215                        dec_page_state(nr_writeback);                   \
 216                ret;                                                    \
 217        })
 218
 219#define PageNosave(page)        test_bit(PG_nosave, &(page)->flags)
 220#define SetPageNosave(page)     set_bit(PG_nosave, &(page)->flags)
 221#define TestSetPageNosave(page) test_and_set_bit(PG_nosave, &(page)->flags)
 222#define ClearPageNosave(page)           clear_bit(PG_nosave, &(page)->flags)
 223#define TestClearPageNosave(page)       test_and_clear_bit(PG_nosave, &(page)->flags)
 224
 225#define PageDirect(page)        test_bit(PG_direct, &(page)->flags)
 226#define SetPageDirect(page)     set_bit(PG_direct, &(page)->flags)
 227#define TestSetPageDirect(page) test_and_set_bit(PG_direct, &(page)->flags)
 228#define ClearPageDirect(page)           clear_bit(PG_direct, &(page)->flags)
 229#define TestClearPageDirect(page)       test_and_clear_bit(PG_direct, &(page)->flags)
 230
 231/*
 232 * inlines for acquisition and release of PG_chainlock
 233 */
 234static inline void pte_chain_lock(struct page *page)
 235{
 236        /*
 237         * Assuming the lock is uncontended, this never enters
 238         * the body of the outer loop. If it is contended, then
 239         * within the inner loop a non-atomic test is used to
 240         * busywait with less bus contention for a good time to
 241         * attempt to acquire the lock bit.
 242         */
 243        preempt_disable();
 244        while (test_and_set_bit(PG_chainlock, &page->flags)) {
 245                while (test_bit(PG_chainlock, &page->flags))
 246                        cpu_relax();
 247        }
 248}
 249
 250static inline void pte_chain_unlock(struct page *page)
 251{
 252        clear_bit(PG_chainlock, &page->flags);
 253        preempt_enable();
 254}
 255
 256/*
 257 * The PageSwapCache predicate doesn't use a PG_flag at this time,
 258 * but it may again do so one day.
 259 */
 260extern struct address_space swapper_space;
 261#define PageSwapCache(page) ((page)->mapping == &swapper_space)
 262
 263#endif  /* PAGE_FLAGS_H */
 264
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.