1 #ifndef _LINUX_SWAPOPS_H 2 #define _LINUX_SWAPOPS_H 3 4 #include <linux/radix-tree.h> 5 6 /* 7 * swapcache pages are stored in the swapper_space radix tree. We want to 8 * get good packing density in that tree, so the index should be dense in 9 * the low-order bits. 10 * 11 * We arrange the `type' and `offset' fields so that `type' is at the five 12 * high-order bits of the swp_entry_t and `offset' is right-aligned in the 13 * remaining bits. 14 * 15 * swp_entry_t's are *never* stored anywhere in their arch-dependent format. 16 */ 17 #define SWP_TYPE_SHIFT(e) (sizeof(e.val) * 8 - MAX_SWAPFILES_SHIFT) 18 #define SWP_OFFSET_MASK(e) ((1UL << SWP_TYPE_SHIFT(e)) - 1) 19 20 /* 21 * Store a type+offset into a swp_entry_t in an arch-independent format 22 */ 23 static inline swp_entry_t swp_entry(unsigned long type, pgoff_t offset) 24 { 25 swp_entry_t ret; 26 27 ret.val = (type << SWP_TYPE_SHIFT(ret)) | 28 (offset & SWP_OFFSET_MASK(ret)); 29 return ret; 30 } 31 32 /* 33 * Extract the `type' field from a swp_entry_t. The swp_entry_t is in 34 * arch-independent format 35 */ 36 static inline unsigned swp_type(swp_entry_t entry) 37 { 38 return (entry.val >> SWP_TYPE_SHIFT(entry)); 39 } 40 41 /* 42 * Extract the `offset' field from a swp_entry_t. The swp_entry_t is in 43 * arch-independent format 44 */ 45 static inline pgoff_t swp_offset(swp_entry_t entry) 46 { 47 return entry.val & SWP_OFFSET_MASK(entry); 48 } 49 50 #ifdef CONFIG_MMU 51 /* check whether a pte points to a swap entry */ 52 static inline int is_swap_pte(pte_t pte) 53 { 54 return !pte_none(pte) && !pte_present(pte) && !pte_file(pte); 55 } 56 #endif 57 58 /* 59 * Convert the arch-dependent pte representation of a swp_entry_t into an 60 * arch-independent swp_entry_t. 61 */ 62 static inline swp_entry_t pte_to_swp_entry(pte_t pte) 63 { 64 swp_entry_t arch_entry; 65 66 BUG_ON(pte_file(pte)); 67 arch_entry = __pte_to_swp_entry(pte); 68 return swp_entry(__swp_type(arch_entry), __swp_offset(arch_entry)); 69 } 70 71 /* 72 * Convert the arch-independent representation of a swp_entry_t into the 73 * arch-dependent pte representation. 74 */ 75 static inline pte_t swp_entry_to_pte(swp_entry_t entry) 76 { 77 swp_entry_t arch_entry; 78 79 arch_entry = __swp_entry(swp_type(entry), swp_offset(entry)); 80 BUG_ON(pte_file(__swp_entry_to_pte(arch_entry))); 81 return __swp_entry_to_pte(arch_entry); 82 } 83 84 static inline swp_entry_t radix_to_swp_entry(void *arg) 85 { 86 swp_entry_t entry; 87 88 entry.val = (unsigned long)arg >> RADIX_TREE_EXCEPTIONAL_SHIFT; 89 return entry; 90 } 91 92 static inline void *swp_to_radix_entry(swp_entry_t entry) 93 { 94 unsigned long value; 95 96 value = entry.val << RADIX_TREE_EXCEPTIONAL_SHIFT; 97 return (void *)(value | RADIX_TREE_EXCEPTIONAL_ENTRY); 98 } 99 100 #ifdef CONFIG_MIGRATION 101 static inline swp_entry_t make_migration_entry(struct page *page, int write) 102 { 103 BUG_ON(!PageLocked(page)); 104 return swp_entry(write ? SWP_MIGRATION_WRITE : SWP_MIGRATION_READ, 105 page_to_pfn(page)); 106 } 107 108 static inline int is_migration_entry(swp_entry_t entry) 109 { 110 return unlikely(swp_type(entry) == SWP_MIGRATION_READ || 111 swp_type(entry) == SWP_MIGRATION_WRITE); 112 } 113 114 static inline int is_write_migration_entry(swp_entry_t entry) 115 { 116 return unlikely(swp_type(entry) == SWP_MIGRATION_WRITE); 117 } 118 119 static inline struct page *migration_entry_to_page(swp_entry_t entry) 120 { 121 struct page *p = pfn_to_page(swp_offset(entry)); 122 /* 123 * Any use of migration entries may only occur while the 124 * corresponding page is locked 125 */ 126 BUG_ON(!PageLocked(p)); 127 return p; 128 } 129 130 static inline void make_migration_entry_read(swp_entry_t *entry) 131 { 132 *entry = swp_entry(SWP_MIGRATION_READ, swp_offset(*entry)); 133 } 134 135 extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, 136 unsigned long address); 137 #else 138 139 #define make_migration_entry(page, write) swp_entry(0, 0) 140 static inline int is_migration_entry(swp_entry_t swp) 141 { 142 return 0; 143 } 144 #define migration_entry_to_page(swp) NULL 145 static inline void make_migration_entry_read(swp_entry_t *entryp) { } 146 static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, 147 unsigned long address) { } 148 static inline int is_write_migration_entry(swp_entry_t entry) 149 { 150 return 0; 151 } 152 153 #endif 154 155 #ifdef CONFIG_MEMORY_FAILURE 156 /* 157 * Support for hardware poisoned pages 158 */ 159 static inline swp_entry_t make_hwpoison_entry(struct page *page) 160 { 161 BUG_ON(!PageLocked(page)); 162 return swp_entry(SWP_HWPOISON, page_to_pfn(page)); 163 } 164 165 static inline int is_hwpoison_entry(swp_entry_t entry) 166 { 167 return swp_type(entry) == SWP_HWPOISON; 168 } 169 #else 170 171 static inline swp_entry_t make_hwpoison_entry(struct page *page) 172 { 173 return swp_entry(0, 0); 174 } 175 176 static inline int is_hwpoison_entry(swp_entry_t swp) 177 { 178 return 0; 179 } 180 #endif 181 182 #if defined(CONFIG_MEMORY_FAILURE) || defined(CONFIG_MIGRATION) 183 static inline int non_swap_entry(swp_entry_t entry) 184 { 185 return swp_type(entry) >= MAX_SWAPFILES; 186 } 187 #else 188 static inline int non_swap_entry(swp_entry_t entry) 189 { 190 return 0; 191 } 192 #endif 193 194 #endif /* _LINUX_SWAPOPS_H */ 195