xref: /linux/mm/swap.h (revision a58f3dcf20ea9e7e968ee8369fd782bbb53dff73)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _MM_SWAP_H
3 #define _MM_SWAP_H
4 
5 struct mempolicy;
6 
7 #ifdef CONFIG_SWAP
8 #include <linux/swapops.h> /* for swp_offset */
9 #include <linux/blk_types.h> /* for bio_end_io_t */
10 
11 /* linux/mm/page_io.c */
12 int sio_pool_init(void);
13 struct swap_iocb;
14 void swap_read_folio(struct folio *folio, struct swap_iocb **plug);
15 void __swap_read_unplug(struct swap_iocb *plug);
16 static inline void swap_read_unplug(struct swap_iocb *plug)
17 {
18 	if (unlikely(plug))
19 		__swap_read_unplug(plug);
20 }
21 void swap_write_unplug(struct swap_iocb *sio);
22 int swap_writepage(struct page *page, struct writeback_control *wbc);
23 void __swap_writepage(struct folio *folio, struct writeback_control *wbc);
24 
25 /* linux/mm/swap_state.c */
26 /* One swap address space for each 64M swap space */
27 #define SWAP_ADDRESS_SPACE_SHIFT	14
28 #define SWAP_ADDRESS_SPACE_PAGES	(1 << SWAP_ADDRESS_SPACE_SHIFT)
29 #define SWAP_ADDRESS_SPACE_MASK		(SWAP_ADDRESS_SPACE_PAGES - 1)
30 extern struct address_space *swapper_spaces[];
31 #define swap_address_space(entry)			    \
32 	(&swapper_spaces[swp_type(entry)][swp_offset(entry) \
33 		>> SWAP_ADDRESS_SPACE_SHIFT])
34 
35 /*
36  * Return the swap device position of the swap entry.
37  */
38 static inline loff_t swap_dev_pos(swp_entry_t entry)
39 {
40 	return ((loff_t)swp_offset(entry)) << PAGE_SHIFT;
41 }
42 
43 /*
44  * Return the swap cache index of the swap entry.
45  */
46 static inline pgoff_t swap_cache_index(swp_entry_t entry)
47 {
48 	BUILD_BUG_ON((SWP_OFFSET_MASK | SWAP_ADDRESS_SPACE_MASK) != SWP_OFFSET_MASK);
49 	return swp_offset(entry) & SWAP_ADDRESS_SPACE_MASK;
50 }
51 
52 void show_swap_cache_info(void);
53 void *get_shadow_from_swap_cache(swp_entry_t entry);
54 int add_to_swap_cache(struct folio *folio, swp_entry_t entry,
55 		      gfp_t gfp, void **shadowp);
56 void __delete_from_swap_cache(struct folio *folio,
57 			      swp_entry_t entry, void *shadow);
58 void delete_from_swap_cache(struct folio *folio);
59 void clear_shadow_from_swap_cache(int type, unsigned long begin,
60 				  unsigned long end);
61 void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry, int nr);
62 struct folio *swap_cache_get_folio(swp_entry_t entry,
63 		struct vm_area_struct *vma, unsigned long addr);
64 struct folio *filemap_get_incore_folio(struct address_space *mapping,
65 		pgoff_t index);
66 
67 struct folio *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
68 		struct vm_area_struct *vma, unsigned long addr,
69 		struct swap_iocb **plug);
70 struct folio *__read_swap_cache_async(swp_entry_t entry, gfp_t gfp_flags,
71 		struct mempolicy *mpol, pgoff_t ilx, bool *new_page_allocated,
72 		bool skip_if_exists);
73 struct folio *swap_cluster_readahead(swp_entry_t entry, gfp_t flag,
74 		struct mempolicy *mpol, pgoff_t ilx);
75 struct folio *swapin_readahead(swp_entry_t entry, gfp_t flag,
76 		struct vm_fault *vmf);
77 
78 static inline unsigned int folio_swap_flags(struct folio *folio)
79 {
80 	return swp_swap_info(folio->swap)->flags;
81 }
82 
83 /*
84  * Return the count of contiguous swap entries that share the same
85  * zeromap status as the starting entry. If is_zeromap is not NULL,
86  * it will return the zeromap status of the starting entry.
87  */
88 static inline int swap_zeromap_batch(swp_entry_t entry, int max_nr,
89 		bool *is_zeromap)
90 {
91 	struct swap_info_struct *sis = swp_swap_info(entry);
92 	unsigned long start = swp_offset(entry);
93 	unsigned long end = start + max_nr;
94 	bool first_bit;
95 
96 	first_bit = test_bit(start, sis->zeromap);
97 	if (is_zeromap)
98 		*is_zeromap = first_bit;
99 
100 	if (max_nr <= 1)
101 		return max_nr;
102 	if (first_bit)
103 		return find_next_zero_bit(sis->zeromap, end, start) - start;
104 	else
105 		return find_next_bit(sis->zeromap, end, start) - start;
106 }
107 
108 #else /* CONFIG_SWAP */
109 struct swap_iocb;
110 static inline void swap_read_folio(struct folio *folio, struct swap_iocb **plug)
111 {
112 }
113 static inline void swap_write_unplug(struct swap_iocb *sio)
114 {
115 }
116 
117 static inline struct address_space *swap_address_space(swp_entry_t entry)
118 {
119 	return NULL;
120 }
121 
122 static inline pgoff_t swap_cache_index(swp_entry_t entry)
123 {
124 	return 0;
125 }
126 
127 static inline void show_swap_cache_info(void)
128 {
129 }
130 
131 static inline struct folio *swap_cluster_readahead(swp_entry_t entry,
132 			gfp_t gfp_mask, struct mempolicy *mpol, pgoff_t ilx)
133 {
134 	return NULL;
135 }
136 
137 static inline struct folio *swapin_readahead(swp_entry_t swp, gfp_t gfp_mask,
138 			struct vm_fault *vmf)
139 {
140 	return NULL;
141 }
142 
143 static inline int swap_writepage(struct page *p, struct writeback_control *wbc)
144 {
145 	return 0;
146 }
147 
148 static inline void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry, int nr)
149 {
150 }
151 
152 static inline struct folio *swap_cache_get_folio(swp_entry_t entry,
153 		struct vm_area_struct *vma, unsigned long addr)
154 {
155 	return NULL;
156 }
157 
158 static inline
159 struct folio *filemap_get_incore_folio(struct address_space *mapping,
160 		pgoff_t index)
161 {
162 	return filemap_get_folio(mapping, index);
163 }
164 
165 static inline void *get_shadow_from_swap_cache(swp_entry_t entry)
166 {
167 	return NULL;
168 }
169 
170 static inline int add_to_swap_cache(struct folio *folio, swp_entry_t entry,
171 					gfp_t gfp_mask, void **shadowp)
172 {
173 	return -1;
174 }
175 
176 static inline void __delete_from_swap_cache(struct folio *folio,
177 					swp_entry_t entry, void *shadow)
178 {
179 }
180 
181 static inline void delete_from_swap_cache(struct folio *folio)
182 {
183 }
184 
185 static inline void clear_shadow_from_swap_cache(int type, unsigned long begin,
186 				unsigned long end)
187 {
188 }
189 
190 static inline unsigned int folio_swap_flags(struct folio *folio)
191 {
192 	return 0;
193 }
194 
195 static inline int swap_zeromap_batch(swp_entry_t entry, int max_nr,
196 		bool *has_zeromap)
197 {
198 	return 0;
199 }
200 
201 #endif /* CONFIG_SWAP */
202 
203 #endif /* _MM_SWAP_H */
204