1#ifndef _LINUX_SWAPOPS_H
2#define _LINUX_SWAPOPS_H
3
4#include <linux/radix-tree.h>
5#include <linux/bug.h>
6
7
8
9
10
11
12
13
14
15
16
17
18
19#define SWP_TYPE_SHIFT(e) ((sizeof(e.val) * 8) - \
20 (MAX_SWAPFILES_SHIFT + RADIX_TREE_EXCEPTIONAL_SHIFT))
21#define SWP_OFFSET_MASK(e) ((1UL << SWP_TYPE_SHIFT(e)) - 1)
22
23
24
25
26static inline swp_entry_t swp_entry(unsigned long type, pgoff_t offset)
27{
28 swp_entry_t ret;
29
30 ret.val = (type << SWP_TYPE_SHIFT(ret)) |
31 (offset & SWP_OFFSET_MASK(ret));
32 return ret;
33}
34
35
36
37
38
39static inline unsigned swp_type(swp_entry_t entry)
40{
41 return (entry.val >> SWP_TYPE_SHIFT(entry));
42}
43
44
45
46
47
48static inline pgoff_t swp_offset(swp_entry_t entry)
49{
50 return entry.val & SWP_OFFSET_MASK(entry);
51}
52
53#ifdef CONFIG_MMU
54
55static inline int is_swap_pte(pte_t pte)
56{
57 return !pte_none(pte) && !pte_present(pte) && !pte_file(pte);
58}
59#endif
60
61
62
63
64
65static inline swp_entry_t pte_to_swp_entry(pte_t pte)
66{
67 swp_entry_t arch_entry;
68
69 BUG_ON(pte_file(pte));
70 if (pte_swp_soft_dirty(pte))
71 pte = pte_swp_clear_soft_dirty(pte);
72 arch_entry = __pte_to_swp_entry(pte);
73 return swp_entry(__swp_type(arch_entry), __swp_offset(arch_entry));
74}
75
76
77
78
79
80static inline pte_t swp_entry_to_pte(swp_entry_t entry)
81{
82 swp_entry_t arch_entry;
83
84 arch_entry = __swp_entry(swp_type(entry), swp_offset(entry));
85 BUG_ON(pte_file(__swp_entry_to_pte(arch_entry)));
86 return __swp_entry_to_pte(arch_entry);
87}
88
89static inline swp_entry_t radix_to_swp_entry(void *arg)
90{
91 swp_entry_t entry;
92
93 entry.val = (unsigned long)arg >> RADIX_TREE_EXCEPTIONAL_SHIFT;
94 return entry;
95}
96
97static inline void *swp_to_radix_entry(swp_entry_t entry)
98{
99 unsigned long value;
100
101 value = entry.val << RADIX_TREE_EXCEPTIONAL_SHIFT;
102 return (void *)(value | RADIX_TREE_EXCEPTIONAL_ENTRY);
103}
104
105#ifdef CONFIG_MIGRATION
106static inline swp_entry_t make_migration_entry(struct page *page, int write)
107{
108 BUG_ON(!PageLocked(page));
109 return swp_entry(write ? SWP_MIGRATION_WRITE : SWP_MIGRATION_READ,
110 page_to_pfn(page));
111}
112
113static inline int is_migration_entry(swp_entry_t entry)
114{
115 return unlikely(swp_type(entry) == SWP_MIGRATION_READ ||
116 swp_type(entry) == SWP_MIGRATION_WRITE);
117}
118
119static inline int is_write_migration_entry(swp_entry_t entry)
120{
121 return unlikely(swp_type(entry) == SWP_MIGRATION_WRITE);
122}
123
124static inline struct page *migration_entry_to_page(swp_entry_t entry)
125{
126 struct page *p = pfn_to_page(swp_offset(entry));
127
128
129
130
131 BUG_ON(!PageLocked(p));
132 return p;
133}
134
135static inline void make_migration_entry_read(swp_entry_t *entry)
136{
137 *entry = swp_entry(SWP_MIGRATION_READ, swp_offset(*entry));
138}
139
140extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
141 unsigned long address);
142extern void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte);
143#else
144
145#define make_migration_entry(page, write) swp_entry(0, 0)
146static inline int is_migration_entry(swp_entry_t swp)
147{
148 return 0;
149}
150#define migration_entry_to_page(swp) NULL
151static inline void make_migration_entry_read(swp_entry_t *entryp) { }
152static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
153 unsigned long address) { }
154static inline void migration_entry_wait_huge(struct mm_struct *mm,
155 pte_t *pte) { }
156static inline int is_write_migration_entry(swp_entry_t entry)
157{
158 return 0;
159}
160
161#endif
162
163#ifdef CONFIG_MEMORY_FAILURE
164
165
166
167static inline swp_entry_t make_hwpoison_entry(struct page *page)
168{
169 BUG_ON(!PageLocked(page));
170 return swp_entry(SWP_HWPOISON, page_to_pfn(page));
171}
172
173static inline int is_hwpoison_entry(swp_entry_t entry)
174{
175 return swp_type(entry) == SWP_HWPOISON;
176}
177#else
178
179static inline swp_entry_t make_hwpoison_entry(struct page *page)
180{
181 return swp_entry(0, 0);
182}
183
184static inline int is_hwpoison_entry(swp_entry_t swp)
185{
186 return 0;
187}
188#endif
189
190#if defined(CONFIG_MEMORY_FAILURE) || defined(CONFIG_MIGRATION)
191static inline int non_swap_entry(swp_entry_t entry)
192{
193 return swp_type(entry) >= MAX_SWAPFILES;
194}
195#else
196static inline int non_swap_entry(swp_entry_t entry)
197{
198 return 0;
199}
200#endif
201
202#endif
203